/* =======================================================
   ARKWER
   STYLE.CSS
   VERSION 2.0

   Fichier CSS unique pour tout le site (accueil, pages
   catégorie, fiche produit, panier, pages légales...).

   TABLE DES MATIÈRES — Ctrl+F le nom d'une section
   (copie-colle le texte tel quel, il apparaît identique
   plus bas dans le fichier) pour y sauter directement.

   RESET / TYPOGRAPHIE / VARIABLES / GLOBAL
   NAVBAR
     RANGÉE UNIQUE (logo, recherche, compte, panier)
     MENU
     ACCUEIL (bouton retour)
     LOGO
     ICÔNE PANIER
   SIDEBAR (menu)
     FERMETURE / GROUPES / LIENS / ÉTAT ACTIF
   HERO
     ARTWORK ANIMÉ
   CATEGORIES (bandeaux "À la une / Shorts / ..." accueil)
     TITRE
   PRODUITS (grille catalogue)
     CARTE / IMAGE / BADGES / HOVER PRODUIT
   RESPONSIVE (accueil + catalogue)
   SCROLLBAR / SELECTION / FOCUS
   FUTURS ELEMENTS
   FOOTER (préparation)
   PAGE LÉGALE (mentions-legales.html, conditions.html...)
   AUTHENTICITÉ (authenticite.html)
     LE PROCESSUS (parcours de vérification)
   AUTHENTICITÉ (accueil)
   REVEAL AU SCROLL
   GRAIN FILMIQUE
   SPOTLIGHT CURSEUR
   BANDEAU DÉFILANT (accueil)
   AVIS CLIENTS (accueil)
   CARRÉS CATÉGORIES (accueil)
   FILTRES CATALOGUE (pages catégorie)
   FICHE PRODUIT (produit.html)
   PANIER (cart.html)
   AUTHENTIFICATION (modal de connexion)
   ESPACE CLIENT — MON ARKWER (compte*.html)
   HAUT DE PAGE MARCHAND (accueil)
     LOGO / NAVIGATION / BARRE PROMO / SÉLECTION ARKWER
   FIN
======================================================= */


/* ===========================
   RESET
=========================== */

*{
    margin:0;
    padding:0;
    box-sizing:border-box;
}

html{
    scroll-behavior:smooth;
}

body{

    background:var(--black);

    color:var(--ink);

    font-family:"DM Sans",sans-serif;

    /* Texte clair sur fond sombre : sans ce lissage, macOS et iOS
       épaississent les lettres claires et le site paraît gras. */
    -webkit-font-smoothing:antialiased;
    -moz-osx-font-smoothing:grayscale;

    overflow-x:hidden;

    line-height:1.4;

}

/* ===========================
   TYPOGRAPHIE
   Deux familles, deux rôles, jamais mélangés :
   Anton pour les titres, DM Sans pour tout le reste
   (paragraphes, libellés, formulaires, informations longues).

   Anton n'existe qu'en une seule graisse. Sans
   font-synthesis:none, les font-weight:600/700/800 déjà posés
   plus bas sur certains titres pousseraient le navigateur à
   fabriquer un faux gras — un épaississement mécanique qui
   empâte les lettres de cette fonte déjà très dense. On coupe
   la synthèse plutôt que de reprendre une à une la centaine de
   règles existantes : leurs tailles et leurs espacements, eux,
   restent intacts.
=========================== */

h1,h2,h3,h4,h5,h6{

    font-family:"Anton",sans-serif;

    font-synthesis:none;

}

/* ===========================
   VARIABLES
   Mode sombre par défaut (valeurs ci-dessous). Le mode clair
   (voir js/theme.js + le bouton dans la navbar) redéclare tout
   sous [data-theme="light"] juste après — même mécanisme que le
   pilote testé sur la fiche produit, généralisé à tout le site.
=========================== */

:root{
    /* L'ÉCHELLE DES TAILLES DE TEXTE.

       Elle n'est pas inventée : ce sont les paliers déjà
       employés dans la feuille. Ce qui disparaît, ce sont les
       DEMI-PALIERS — 10,5 / 11,5 / 12,5 / 13,5 / 14,5 — que
       personne n'a choisis et qui viennent d'arrondis de rem.
       Aucun texte ne bouge de plus d'un demi-pixel.

       Elles ne sont déclarées QU'ICI, et pas dans le bloc du
       thème clair : une couleur change entre les deux thèmes,
       une taille non. La répéter créerait deux endroits à
       tenir à jour pour une valeur qui ne varie pas. */
    --t-micro: 11px;         /* mentions, fil d'ariane, compteur */
    --t-etiquette: 12px;     /* capitales d'etiquette, boutons */
    --t-lien: 13px;          /* liens, tailles, alertes */
    --t-texte: 14px;         /* texte courant */
    --t-confort: 15px;       /* paragraphes longs */
    --t-sous-titre: 17px;    /* la taille retenue, en capitales */
    --t-prix-mobile: 20px;   /* le prix sous 900 px */
    --t-nom-mobile: 22px;    /* le nom sous 900 px */
    --t-prix: 24px;          /* le prix */
    --t-nom-moyen: 25px;     /* le nom entre 900 et 1180 px */
    --t-nom: 28px;

    /* L'ÉCHELLE DES RAYONS.

       Trois paliers, et un seul changement de valeur : deux
       contrôles étaient arrondis à 8 px quand les cinq autres
       l'étaient à 6. Rien ne le justifiait.

       Le 50 % des trois cercles n'entre PAS dans l'échelle :
       ce n'est pas un rayon, c'est une forme. Lui donner un
       palier ferait des ovales le jour où le palier bouge. */
    --r-controle: 6px;     /* boutons, champs, vignettes */
    --r-surface: 14px;     /* les cartes */
    --r-pilule: 999px;     /* compteurs et boutons en pilule */           /* le nom de la piece */


    /* FOND DE PAGE EN MODE SOMBRE — #1C1C1C, PAS #0A0A0A
       ------------------------------------------------------------
       La palette validée sur l'accueil est devenue celle de tout le
       site. Elle repose sur une hiérarchie à trois niveaux qui monte
       vers la lumière — page, surface, carte — parce que c'est la
       lecture naturelle d'un thème sombre : ce qui est proche est
       plus clair.

         page    #1C1C1C   --black
         surface #262626   --dark
         carte   #313131   --card

       Le #0A0A0A d'origine, trop lourd, ne sert plus de fond. Il
       reste disponible comme encre du mode clair (--ink).

       CONSÉQUENCE MESURÉE : en remontant les surfaces, le gris
       secondaire #8B8A88 tombait à 4,39:1 sur #262626 et 3,77:1 sur
       #313131 — sous le seuil WCAG de 4,5. Il a été relevé en
       conséquence, voir --grey plus bas. */
    --black:#1C1C1C;

    --black-rgb:28, 28, 28;

    /* LES DEUX CRANS AU-DESSUS DE LA PAGE.
       --dark est la zone de contenu, --card ce qui est posé dessus.
       Écarts de 10 et 11 niveaux : assez pour être vus, pas assez
       pour dessiner des blocs. */
    --dark:#262626;

    --card:#313131;

    /* LES MÊMES VALEURS, SOUS LEURS NOMS D'ORIGINE.
       La palette est née sur l'accueil sous le préfixe --acc- et des
       composants la lisent encore ainsi. On les garde comme alias du
       vocabulaire général : une seule source de vérité, deux noms. */
    --acc-page:          #1C1C1C;
    --acc-page-rgb:      28, 28, 28;
    --acc-surface:       #262626;
    --acc-carte-page:    #262626;
    --acc-carte-surface: #313131;
    --acc-controle:      #313131;

    /* SURFACE DES CARTES PRODUIT (chantier surfaces, 15/09/2026).
       Pas --card en aplat : un voile du blanc de la palette, en
       transparence. Il détache la cellule de ce qui la porte sans la
       transformer en boîte, et reste un cran au-dessus de TOUTE
       surface — ce qu'un aplat fixe ne permettrait pas. Sur la page
       à #1C1C1C il donne ~#262626, le même cran que --dark. */
    --carte-surface:rgba(244, 243, 239, .04);

    /* Les traits de séparation ne sont pas une quatrième couleur :
       c'est le blanc de la palette posé en transparence. Il reste
       ainsi visible aussi bien sur le noir de la page que sur le
       gris des cartes, ce qu'un aplat fixe ne permettrait pas. */
    --line:rgba(244, 243, 239, .12);

    /* Le blanc ARKWER. Même valeur dans les deux thèmes : c'est une
       couleur de marque, pas un rôle d'interface. */
    --white:#F4F3EF;

    /* Textes secondaires : le blanc de la palette fondu dans le
       noir de la palette. Aucune teinte nouvelle n'est introduite,
       seulement deux paliers entre les deux.

       #8B8A88 A ÉTÉ RELEVÉ À #9D9B99. Quand le fond de page est
       passé de #0A0A0A à #1C1C1C, les surfaces ont suivi, et
       l'ancien gris ne tenait plus le seuil WCAG sur les plus
       claires d'entre elles :

         sur #1C1C1C   4,94:1   passait
         sur #262626   4,39:1   sous le seuil
         sur #313131   3,77:1   sous le seuil

       Le minimum strict pour 4,5:1 sur #313131 est #999896 ;
       #9D9B99 donne 4,78:1 et garde une marge si une surface
       remonte encore d'un cran. Mesuré sur « Taille L / S / M »
       des cartes produit, qui était le texte qui tombait.

       --grey-light tenait partout (6,63:1 au pire), il ne bouge
       pas. */
    --grey:#9D9B99;

    --grey-light:#BAB9B6;

    /* VERT DE DISPONIBILITÉ — le seul endroit où le site sort de ses
       neutres pour dire un état. Deux valeurs, une par thème : un
       vert lisible sur #1C1C1C est illisible sur blanc.
       Mesuré : 9,15:1 sur la page sombre, 6,98:1 sur une carte. */
    --vert-dispo:#5FD48A;

    /* Accent sémantique, hors palette de neutres : étoiles d'avis,
       favoris, badge vérifié, compte connecté. Les trois couleurs
       du système ne peuvent pas distinguer ces états. */
    /* PLUS D'OR : ce jeton portait une teinte moutarde sur des badges,
       des étoiles et des contours. Il vaut maintenant l'encre du thème —
       les ~45 usages suivent, et le texte posé dessus (--accent-ink) était
       déjà prévu pour l'encre. */
    --gold:#F4F3EF;

    /* Même couleur en composantes, pour les bordures, halos et
       ombres qui ont besoin d'une transparence. */
    --gold-rgb:244, 243, 239;

    --ink:#F4F3EF;

    --ink-rgb:244, 243, 239;

    /* PRÉSENTATION DES PHOTOS PRODUIT
       ------------------------------------------------------
       Les pièces sont détourées, sur fond transparent. Elles
       flottent donc sur la page, et il faut leur donner un sol.

       Deux moyens, dosés différemment selon le thème :

       --photo-glow-rgb  le halo radial derrière la pièce. Clair
                         dans les deux thèmes : sur fond sombre il
                         éclaire, sur fond crème il creuse un
                         écrin plus clair que la page.

       --photo-shadow    l'ombre portée par la pièce elle-même.
                         En sombre, une lueur diffuse. En clair,
                         une vraie ombre de contact projetée vers
                         le bas — le vocabulaire de la photo de
                         studio, qui pose l'objet au lieu de le
                         laisser flotter.

       Sans cette seconde couche, une pièce ivoire sur fond crème
       n'a aucune limite visible. */
    --photo-glow-rgb:244, 243, 239;
    --photo-glow-opacity:.34;
    --photo-glow-opacity-hover:.44;
    --photo-shadow:0 0 16px rgba(244, 243, 239, .14);
    --photo-shadow-hover:0 0 24px rgba(244, 243, 239, .26);
    --photo-shadow-card:0 0 12px rgba(244, 243, 239, .10);

    /* Texte posé sur un aplat --ink (boutons pleins) : le noir de
       la palette. */
    --accent-ink:#0A0A0A;

    --accent-ink-rgb:10, 10, 10;

    /* Survol d'un bouton plein : le blanc de la palette assombri
       vers le noir de la palette (85 %). */
    --accent-hover:#D1D0CD;

    --disabled-line:var(--line);

    /* Texte désactivé : blanc de la palette à 30 % dans le noir. */
    --disabled-ink:#50504F;

    --radius:18px;

    --transition:.25s cubic-bezier(.4,0,.2,1);

}

/* Mode clair — même palette que le pilote validé sur la fiche
   produit, appliquée à tout le site. Sombre reste le défaut ;
   ceci ne s'active que si le visiteur a choisi le clair (mémorisé
   en localStorage, voir js/theme.js). */
[data-theme="light"]{

    /* FOND DE PAGE EN MODE CLAIR — #FFFFFF, PAS LE CRÈME
       ------------------------------------------------------------
       Même généralisation que le mode sombre, dans l'autre sens :
       la hiérarchie descend de la page vers le gris, et ce qui est
       posé dessus revient au blanc.

         page    #FFFFFF   --black
         surface #F3F3F3   --dark
         carte   #FFFFFF   --card

       Ce n'est PAS le miroir du mode sombre, et c'est voulu : en
       clair, une carte se détache en remontant au blanc pur sur une
       zone grise, alors qu'en sombre elle se détache en montant vers
       la lumière. Les deux lectures sont naturelles dans leur thème.

       Le crème #F4F3EF reste le blanc de marque (--white) et l'encre
       du mode sombre (--ink) ; il ne sert plus de fond de page. */
    --black:#FFFFFF;

    --black-rgb:255, 255, 255;

    /* --dark DESCEND, --card REMONTE. La page est blanche : une
       surface ne peut plus s'élever en s'éclaircissant, elle se
       distingue en se posant dans le gris. Ce qui est porté par
       cette zone revient alors au blanc pur. */
    --dark:#F3F3F3;

    --card:#FFFFFF;

    /* LES MÊMES VALEURS SOUS LEURS NOMS D'ORIGINE (voir :root). */
    --acc-page:          #FFFFFF;
    --acc-page-rgb:      255, 255, 255;
    --acc-surface:       #F3F3F3;
    --acc-carte-page:    #F3F3F3;
    --acc-carte-surface: #FFFFFF;
    --acc-controle:      #FFFFFF;

    /* SURFACE DES CARTES PRODUIT — OPAQUE DÉSORMAIS.
       Elle valait rgba(255, 255, 255, .85) : un voile blanc sur le
       crème, qui donnait #FDFDFD, 3,5 points au-dessus de la page.
       Sur une page BLANCHE, ce même voile donne #FFFFFF : écart nul,
       la carte disparaît. On inverse donc le sens — la carte se pose
       dans le gris de surface au lieu de monter vers le blanc. Les
       zones qui sont déjà grises la ramènent au blanc (--acc-carte-
       surface), de sorte qu'il reste toujours un cran d'écart. */
    --carte-surface:#F3F3F3;

    /* FORCE PERÇUE, PAS COULEUR NOMINALE
       ------------------------------------------------------------
       Le filet valait #1C1C1C plein. Mesuré sur les 180 éléments
       bordés de la page : en thème sombre il se détache de 28 points
       de luminance du fond, en clair il s'en détachait de 242. Le
       même trait passait donc du murmure au trait de crayon, et le
       thème clair se lisait comme un filaire.

       L'alpha .13 ramène cet écart à 28, identique au sombre. Ce
       n'est pas la même couleur des deux côtés : c'est le même poids
       visuel, seul critère qui compte ici. */
    --line:rgba(28, 28, 28, .13);

    /* Mêmes deux paliers qu'en sombre, dans l'autre sens : le gris
       de la palette fondu dans le blanc de la palette (65 % et 80 %). */
    --grey:#6A6766;

    --grey-light:#4A4746;

    /* Le pendant clair du vert de disponibilité : un vert profond,
       pas le même éclairci. Mesuré : 6,15:1 sur blanc. */
    --vert-dispo:#17703A;

    /* L'ENCRE DU MODE CLAIR : #0A0A0A, PAS #1C1C1C.
       #1C1C1C est devenu le FOND de page du mode sombre. Le garder
       aussi comme encre du mode clair faisait porter deux rôles
       opposés par la même valeur, et c'est ce qui rendait les deux
       thèmes difficiles à tenir. Le noir profond d'origine reprend
       le rôle qu'il tient le mieux : écrire. */
    --ink:#0A0A0A;

    --ink-rgb:10, 10, 10;

    /* Le halo doit être plus clair que la page : seul le blanc pur
       passe au-dessus du crème. Effet de lumière, pas une couleur. */
    --photo-glow-rgb:255, 255, 255;

    /* Sur crème, l'écrin blanc doit être plus marqué qu'en sombre :
       l'écart entre #F4F3EF et #ffffff est faible. */
    --photo-glow-opacity:.9;

    --photo-glow-opacity-hover:1;

    /* Ombre de contact, projetée vers le bas et non centrée : une
       lueur claire serait invisible sur fond clair. */
    --photo-shadow:0 18px 26px rgba(28, 28, 28, .10);

    --photo-shadow-hover:0 24px 34px rgba(28, 28, 28, .16);

    --photo-shadow-card:0 10px 18px rgba(28, 28, 28, .08);

    --accent-ink:#F4F3EF;

    --accent-ink-rgb:244, 243, 239;

    /* Survol d'un bouton plein : le gris de la palette éclairci
       vers le blanc de la palette (8 %). */
    --accent-hover:#2D2D2D;

    --disabled-line:#CECCC9;

    --disabled-ink:#9F9D9B;

    /* Même teinte (38°) et même saturation (47 %) que le gold du
       thème sombre, simplement assombri. Sur fond clair, #c9a668
       tombait à 2,30 de contraste sur les cartes d'avis et 2,07 sur
       le fond de page : les étoiles étaient à la limite du lisible
       et sous le minimum de 4,5:1. #876830 est la valeur la plus
       claire qui passe les deux (5,19 et 4,67) — on ne perd donc
       pas plus de chaleur que nécessaire. */
    --gold:#1C1C1C;

    --gold-rgb:28, 28, 28;

}

/* ===========================
   CATALOGUE INDISPONIBLE
   Le catalogue vient désormais de la base de données : il
   peut donc, contrairement à avant, ne pas arriver. Ce
   bandeau évite d'afficher une page vide sans explication
   (voir showCatalogError dans js/products.js).
=========================== */

.catalog-error{

    position:fixed;

    left:50%;

    bottom:24px;

    z-index:9999;

    max-width:calc(100vw - 40px);

    padding:14px 22px;

    border-radius:10px;

    background:#b4231f;

    color:#F4F3EF;

    font-size:13.5px;

    line-height:1.5;

    text-align:center;

    box-shadow:0 12px 32px rgba(10, 10, 10, .35);

    transform:translateX(-50%);

}

/* ===========================
   GLOBAL
=========================== */

img{

    display:block;

    width:100%;

}

a{

    text-decoration:none;

    color:inherit;

}

button{

    font-family:inherit;

    cursor:pointer;

    border:none;

    background:none;

}

/* =======================================================
   NAVBAR
======================================================= */

.navbar{

    position:sticky;

    top:0;

    z-index:5000;

    display:flex;

    flex-direction:column;

    background:rgba(var(--black-rgb),.92);

    -webkit-backdrop-filter:blur(16px);
    backdrop-filter:blur(16px);

    border-bottom:1px solid var(--line);

}

/* ===========================
   RANGÉE UNIQUE (logo, recherche, compte, panier)
=========================== */

.navbar-top{

    width:100%;

    height:70px;

    padding:0 42px;

    display:flex;

    align-items:center;

    gap:28px;

}

.navbar-search{

    position:relative;

    flex:1;

    max-width:420px;

    display:none;

    align-items:center;

    gap:10px;

    padding:9px 16px;

    background:rgba(var(--ink-rgb),.05);

    border:1px solid var(--line);

    border-radius:30px;

    transition:border-color .25s ease;

}

.navbar-search:focus-within{

    border-color:rgba(var(--ink-rgb),.3);

}

.navbar-search-icon{

    width:15px;

    height:15px;

    color:var(--grey);

    flex-shrink:0;

}

.navbar-search-input{

    /* LE CHAMP OCCUPE TOUTE LA PASTILLE.

       Mesuré à 1024 px : le champ fait 17 px de haut dans une
       barre de 36. Le formulaire porte 9 px de rembourrage en haut
       et en bas, et seule la bande centrale de 17 px donnait le
       curseur — cliquer sur le haut ou le bas de la pastille
       n'avait aucun effet, sans rien dire.

       Marges négatives égales au rembourrage, rembourrage
       identique à l'intérieur : la zone qui répond s'étend
       jusqu'au bord de la pastille et le texte, lui, reste
       exactement où il était. */
    align-self:stretch;

    margin:-9px -16px -9px 0;

    padding:9px 16px 9px 0;

    flex:1;

    width:100%;

    background:none;

    border:none;

    outline:none;

    color:var(--ink);

    font-family:inherit;

    font-size:13px;

}

.navbar-search-input::placeholder{

    color:var(--grey);

}

.navbar-search-results{

    /* position:fixed + top/left/width calculés en JS (voir search.js).
       Le header étant en position:sticky, un positionnement absolu
       classique ancrerait le dropdown au champ lui-même ; fixed plus
       un calcul via getBoundingClientRect() le place toujours juste
       sous le header entier, quelle que soit sa hauteur. */
    position:fixed;

    min-width:320px;

    max-height:420px;

    overflow-y:auto;

    background:rgba(var(--black-rgb),.98);

    border:1px solid var(--line);

    border-radius:14px;

    z-index:6000;

    display:none;

}

.navbar-search-results.open{

    display:block;

}

.navbar-search-result{

    display:flex;

    align-items:center;

    gap:12px;

    padding:10px 14px;

    color:var(--grey-light);

    text-decoration:none;

    transition:background .2s ease;

}

.navbar-search-result:hover{

    background:var(--card);

}

.navbar-search-result img{

    width:36px;

    height:36px;

    object-fit:contain;

    background:var(--dark);

    border-radius:8px;

    flex-shrink:0;

}

.navbar-search-result-text{

    display:flex;

    flex-direction:column;

    gap:2px;

}

.navbar-search-result-brand{

    font-size:10px;

    letter-spacing:.5px;

    text-transform:uppercase;

    color:var(--grey);

}

.navbar-search-result-name{

    font-size:13px;

}

.navbar-search-empty{

    padding:16px;

    font-size:12.5px;

    color:var(--grey);

    text-align:center;

}

.navbar-search-note{

    padding:10px 16px 4px;

    font-size:11px;

    font-weight:600;

    letter-spacing:.5px;

    text-transform:uppercase;

    color:var(--grey);

}

.navbar-top-actions{

    display:flex;

    align-items:center;

    gap:22px;

    margin-left:auto;

    flex-shrink:0;

}

/* L'ORDRE EST POSÉ ICI, PAS DANS LE BALISAGE.
   ------------------------------------------------------------------
   De gauche à droite : le thème, puis ce qui appartient au visiteur —
   son panier, ses messages, son compte. La barre existe en cinq
   variantes de balisage selon les pages ; les réordonner toutes à la
   main aurait multiplié le risque pour un résultat identique. */
.navbar-top-actions > .theme-toggle { order: 1; }
.navbar-top-actions > .cart-icon    { order: 2; }
.navbar-top-actions > .messages-icon{ order: 3; }
.navbar-top-actions > .navbar-compte{ order: 4; }

/* Les pages compte ont leur propre retour, qui reste en tête. */
.navbar-top-actions > .compte-retour { order: 0; }

.navbar-compte{

    position:relative;
    display:flex;
    align-items:center;

}

/* LE BOUTON DE PROFIL. Même boîte que le panier et l'enveloppe : les
   trois se lisent comme une rangée, pas comme trois objets. */
.navbar-profil{

    position:relative;
    flex-shrink:0;
    width:42px;
    height:42px;
    display:flex;
    align-items:center;
    justify-content:center;
    padding:0;
    background:none;
    border:1px solid transparent;
    border-radius:50%;
    color:var(--ink);
    cursor:pointer;
    transition:border-color .2s ease, background .2s ease;

}

.navbar-profil svg{ width:21px; height:21px; }

.navbar-profil:hover,
.navbar-profil[aria-expanded="true"]{

    background:rgba(var(--ink-rgb), .06);
    border-color:rgba(var(--ink-rgb), .18);

}

.navbar-profil:focus-visible{ outline:1px solid var(--ink); outline-offset:2px; }

/* Une pastille muette : elle dit « quelque chose vous attend » sans
   répéter le nombre déjà porté par l'enveloppe. */
.navbar-profil-pastille{

    position:absolute;
    top:6px;
    right:6px;
    width:7px;
    height:7px;
    border-radius:50%;
    background:var(--ink);
    box-shadow:0 0 0 2px var(--black);

}

/* LE MENU
   ------------------------------------------------------------------
   Ancré sous le bouton, aligné à droite pour ne jamais sortir de
   l'écran. Il n'apparaît que déplié : .hidden est posé par le JS, et
   le sélecteur :not(.hidden) empêche cette règle de le rallumer. */
.navbar-menu:not(.hidden){

    position:absolute;
    top:calc(100% + 10px);
    right:0;
    z-index:5100;
    display:flex;
    flex-direction:column;
    min-width:238px;
    padding:10px 0 6px;
    background:var(--black);
    border:1px solid rgba(var(--ink-rgb), .14);
    border-radius:12px;
    box-shadow:0 18px 40px -16px rgba(0, 0, 0, .55);

}

.navbar-menu-nom{

    margin:0;
    padding:4px 16px 10px;
    font-size:12px;
    letter-spacing:.04em;
    color:var(--grey);
    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;

}

.navbar-menu-groupe{

    display:flex;
    flex-direction:column;
    padding:6px 0;
    border-top:1px solid rgba(var(--ink-rgb), .1);

}

.navbar-menu-groupe:first-of-type{ border-top:0; padding-top:0; }

.navbar-menu-titre{

    margin:2px 0 4px;
    padding:0 16px;
    font-size:var(--t-micro);
    font-weight:600;
    letter-spacing:.13em;
    text-transform:uppercase;
    color:var(--grey);

}

.navbar-menu-lien{

    padding:9px 16px;
    background:none;
    border:0;
    color:var(--ink);
    font-family:inherit;
    font-size:13.5px;
    text-align:left;
    text-decoration:none;
    cursor:pointer;
    transition:background .15s ease;

}

.navbar-menu-lien:hover{ background:rgba(var(--ink-rgb), .07); }

.navbar-menu-lien:focus-visible{ outline:1px solid var(--ink); outline-offset:-2px; }

/* La sortie n'est pas une destination : elle se distingue sans se
   mettre en avant. */
.navbar-menu-sortie{ color:var(--grey); }

.navbar-menu-sortie:hover{ color:var(--ink); }

/* Sous 560 px, le menu s'étale plutôt que de déborder. */
@media (max-width: 560px){

    .navbar-menu:not(.hidden){

        position:fixed;
        top:auto;
        left:12px;
        right:12px;
        min-width:0;

    }

}

/* PAGES AVEC BOUTON ACCUEIL, SOUS 400 PX.
   Menu, accueil, marque et actions tenaient à 401 px dans 375 : le
   badge du panier sortait de 4 px de l'écran. On resserre les seuls
   espacements, sur ces seules pages, à cette seule largeur. */
@media (max-width: 400px) {
    .navbar-top:has(.home-btn) {
        gap: 16px;
    }
}

.navbar-account-link{

    font-family:inherit;

    font-size:12px;

    font-weight:500;

    letter-spacing:1px;

    text-transform:uppercase;

    color:var(--grey-light);

    text-decoration:none;

    white-space:nowrap;

    background:none;

    border:none;

    padding:0;

    cursor:pointer;

    transition:color .2s ease;

    display:none;

}

.navbar-account-link:hover{

    color:var(--ink);

}

/* LES DEUX ÉTATS ONT LA MÊME FORME
   ------------------------------------------------------------------
   Connecté, ce bouton était déjà une pilule bordée (icône + prénom).
   Déconnecté, c'était un mot gris posé à plat : les deux états du
   même bouton ne se ressemblaient pas, et le plus important des
   deux — celui qui invite à créer un compte — était le plus effacé.

   Il devient la même pilule, et porte les deux entrées plutôt qu'un
   « Me connecter » qui laissait croire qu'il fallait déjà un compte.
   Le séparateur est un trait tracé ici, pas un caractère : un
   lecteur d'écran lirait « barre verticale ». */
/* EN PLEIN, PAS EN CONTOUR. C'est l'invitation à créer un compte :
   elle se tient au même rang que « Acheter maintenant », qui est le
   seul autre bouton plein du site. L'encre et son inverse basculent
   avec le thème — fond noir et texte crème en clair, l'inverse en
   sombre — exactement comme les boutons d'achat. */
/* :not(.hidden) est indispensable, pas decoratif : .hidden ne pose
   qu’un display:none de specificite (0,1,0), que ce selecteur (0,2,0)
   ecrasait. Resultat mesure : connecte, la pilule restait a l’ecran
   A COTE du bouton de profil. */
.navbar-account-link:not(.logged-in):not(.hidden){

    /* PAS DE display ICI. La pilule ne doit paraitre qu a partir de
       1000 px — en dessous, l acces au compte passe par le menu
       lateral. Poser un display hors media query l affichait a
       toutes les largeurs : mesure a 375 px, elle debordait la barre
       de 160 px. Le display reste donc gouverne par le defaut
       (none) et par la regle min-width:1000px. */
    align-items:center;
    gap:.55rem;
    padding:.46rem 1.05rem;
    background:var(--ink);
    border:1px solid var(--ink);
    border-radius:999px;
    letter-spacing:.06em;
    color:var(--accent-ink);
    transition:background .2s ease, border-color .2s ease, color .2s ease;

}

.navbar-account-link:not(.logged-in):hover{

    background:var(--accent-hover);
    border-color:var(--accent-hover);

}

/* Sur fond plein, le séparateur reprend la couleur du texte. */
.navbar-account-link:not(.logged-in) .navbar-account-sep{

    background:rgba(var(--accent-ink-rgb), .38);

}

.navbar-account-link:focus-visible{

    outline:1px solid var(--ink);
    outline-offset:2px;

}

.navbar-account-sep{

    width:1px;
    height:11px;
    flex:none;
    background:rgba(var(--ink-rgb), .3);

}

/* BASCULE CLAIR / SOMBRE
   ------------------------------------------------------------------
   Un interrupteur à deux positions plutôt qu'un bouton libellé : les
   deux icônes restent visibles en permanence et un curseur circulaire
   se place derrière celle du mode actif. Le texte « Mode clair » a
   disparu — il pesait autant qu'un lien de navigation pour une
   fonction secondaire.

   Les deux icônes toujours présentes, c'est ce qui rend l'état
   lisible : avec une seule icône, on ne sait jamais si elle montre le
   mode actuel ou celui vers lequel on bascule. Le doute est levé par
   la position du curseur.

   L'ordre est imposé en CSS (soleil à gauche, lune à droite) plutôt
   qu'en réordonnant le HTML des 93 pages qui portent cette navbar. */

.theme-toggle{

    position:relative;

    display:flex;

    align-items:center;

    flex-shrink:0;

    padding:3px;

    border:1px solid var(--line);

    border-radius:999px;

    background:transparent;

    color:var(--grey-light);

    cursor:pointer;

    transition:border-color .2s ease, color .2s ease;

}

.theme-toggle:hover{

    border-color:var(--ink);

    color:var(--ink);

}

/* Le curseur. Il glisse d'une position à l'autre au lieu
   d'apparaître et disparaître : le mouvement dit qu'on a changé
   d'état, sans avoir à l'écrire. */

.theme-toggle::before{

    content:"";

    position:absolute;

    top:3px;

    left:3px;

    width:23px;

    height:23px;

    border-radius:50%;

    background:rgba(var(--ink-rgb),.14);

    /* Sombre par défaut : le curseur est sur la lune, à droite.
       Une position vaut la largeur d'une icône, marge comprise. */
    transform:translateX(23px);

    transition:transform .28s cubic-bezier(.4,0,.2,1);

}

.theme-toggle svg{

    position:relative;

    z-index:1;

    width:13px;

    height:13px;

    margin:5px;

    flex-shrink:0;

    display:block;

    transition:opacity .2s ease;

}

.theme-toggle-icon-sun{

    order:1;

}

.theme-toggle-icon-moon{

    order:2;

}

/* Sombre par défaut : c'est le soleil qui s'efface. */

.theme-toggle-icon-sun{

    opacity:.38;

}

html[data-theme="light"] .theme-toggle::before{

    transform:translateX(0);

}

html[data-theme="light"] .theme-toggle-icon-sun{

    opacity:1;

}

html[data-theme="light"] .theme-toggle-icon-moon{

    opacity:.38;

}

.theme-toggle:hover svg{

    opacity:1;

}

@media(min-width:1000px){

    .navbar-search{

        display:flex;

    }

    .navbar-account-link{

        /* inline-flex et non block : la pilule aligne ses trois
           morceaux sur une ligne. L'état connecté repose le sien. */
        display:inline-flex;

    }

}
/* ===========================
   MENU
=========================== */

.menu-btn{

    font-size:30px;

    color:var(--ink);

    user-select:none;

    /* La largeur et la marge sont animées, pas seulement l'opacité :
       le bouton se replie complètement quand il disparaît (voir plus
       bas, en haut du hero), sinon il laisserait un vide de 27 px. */
    transition:opacity .3s ease, width .3s cubic-bezier(.4,0,.2,1),
               margin-right .3s cubic-bezier(.4,0,.2,1), transform .25s ease;

}

.menu-btn:hover{

    transform:scale(1.08);

}

/* ===========================
   ACCUEIL (bouton retour)

   Absent du HTML de index.html : sur la page d'accueil, il n'y
   a nul besoin d'un bouton pour y revenir. Rien à cacher au
   chargement ni à surveiller en JS — le bouton n'existe
   simplement pas sur cette page, et la barre se resserre
   toute seule autour de ce qui reste.
=========================== */

.home-btn{

    display:flex;

    align-items:center;

    justify-content:center;

    color:var(--ink);

    transition:transform .25s ease;

}

/* 26 px et non 21 comme les autres pictos : le dessin n'occupe que
   17/24 de sa boîte. À 21 px la maison paraissait nettement plus
   petite que le ☰ voisin ; à 26 px leurs encres font la même taille. */
.home-btn svg{

    width:26px;

    height:26px;

}

.home-btn:hover{

    transform:scale(1.08);

}

/* ===========================
   ICÔNE PANIER
=========================== */

/* L'ENVELOPPE ET LE PANIER ONT LA MEME BOITE. Deux cibles voisines
   de tailles differentes se remarquent ; ici elles se lisent comme
   une paire, et la reduction de la navbar les suit toutes deux.

   .hidden hors session (js/auth.js) : le selecteur est ecrit en
   :not(.hidden) pour qu'un display pose ici ne rallume pas une
   icone que le JS vient de masquer. */
.messages-icon:not(.hidden),
.cart-icon{

    position:relative;

    flex-shrink:0;

    width:42px;

    height:42px;

    display:flex;

    align-items:center;

    justify-content:center;

    color:var(--ink);

}

.messages-icon svg,
.cart-icon svg{

    width:21px;

    height:21px;

}

/* Le compteur. Rond plein plutôt que pastille allongée, et posé sur
   l'angle du sac. Le liseré aux couleurs du fond le détache du tracé
   de l'icône : sans lui, badge et anse se touchent et l'ensemble
   devient illisible dès qu'il y a un chiffre.

   La largeur reste libre au-delà de deux chiffres — un panier à 10
   articles ne doit pas déborder du rond. */

.messages-count,
.cart-count{

    position:absolute;

    top:1px;

    right:0;

    min-width:18px;

    height:18px;

    padding:0 5px;

    border-radius:999px;

    background:var(--ink);

    color:var(--accent-ink);

    box-shadow:0 0 0 2px rgba(var(--black-rgb),1);

    font-size:10px;

    font-weight:700;

    line-height:1;

    letter-spacing:0;

    display:flex;

    align-items:center;

    justify-content:center;

}

/* Sur la photographie du hero, le liseré ne peut pas prendre la
   couleur de la page : il prendrait celle du thème alors que le fond
   est une image. On le passe en noir de la palette, comme le reste
   de ce qui se pose sur la photo. */

body:has(.hero) .navbar:not(.navbar-opaque) .cart-count{

    box-shadow:0 0 0 2px rgba(10, 10, 10, .55);

}

.cart-count.hidden{

    display:none;

}

/* =======================================================
   MENU GLOBAL (hamburger)

   CHANTIER NAVIGATION V1, 14/09/2026.

   QUATRE UNIVERS, PAS UNE SITEMAP. Acheter, Vendre, Gagner,
   ARKWER : on lit d'abord quatre intentions, et les liens d'un
   univers n'apparaissent que lorsqu'on l'ouvre. Un seul tiroir
   ouvert à la fois — sinon le menu redevient la longue liste
   qu'il remplace.

   Le HTML est un bloc partagé, identique sur toutes les pages
   (ARKWER ADMIN/MAINTENANCE/partiels/menu.html). Le comportement
   est dans js/script.js (initMenuTiroirs).

   Le panneau fermé est visibility:hidden, pas seulement hors
   écran : ses liens ne doivent pas rester atteignables au
   clavier. Un tiroir fermé est inert pour la même raison.
======================================================= */

.sidebar {
    position: fixed;
    top: 0;
    left: -420px;
    width: 400px;
    max-width: 88vw;
    height: 100vh;
    height: 100dvh;
    background: var(--black);
    border-right: 1px solid var(--line);
    z-index: 6000;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 76px 0 36px;
    box-shadow: 25px 0 60px rgba(10, 10, 10, .18);
    visibility: hidden;
    transition: left .3s cubic-bezier(.4, 0, .2, 1), visibility 0s linear .3s;
}

.sidebar.active {
    left: 0;
    visibility: visible;
    transition: left .3s cubic-bezier(.4, 0, .2, 1);
}

.close-btn {
    position: absolute;
    top: 16px;
    right: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    background: none;
    border: 0;
    font-size: 34px;
    line-height: 1;
    color: var(--ink);
    cursor: pointer;
    transition: transform .2s ease;
}

.close-btn:focus-visible {
    outline: 1px solid var(--ink);
    outline-offset: -4px;
}

@media (hover: hover) and (pointer: fine) {
    .close-btn:hover {
        transform: rotate(90deg);
    }
}

.sidebar-nav {
    display: flex;
    flex-direction: column;
}

/* ---------- UN UNIVERS ----------------------------------------

   Le nom en Anton porte la hiérarchie ; la ligne en dessous dit
   en quatre mots ce qu'on y trouve. Des filets presque éteints
   séparent les univers : c'est l'espace qui structure. */

.menu-univers {
    border-top: 1px solid rgba(var(--ink-rgb), .08);
}

.menu-univers:last-of-type {
    border-bottom: 1px solid rgba(var(--ink-rgb), .08);
}

.menu-univers-titre {
    margin: 0;
    font: inherit;
}

.menu-univers-bouton {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: 16px;
    width: 100%;
    min-height: 76px;
    padding: 16px 28px 16px 34px;
    background: none;
    border: 0;
    color: var(--ink);
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.menu-univers-bouton:focus-visible {
    outline: 1px solid var(--ink);
    outline-offset: -4px;
}

.menu-univers-nom {
    font-family: "Anton", sans-serif;
    font-size: 1.65rem;
    font-weight: 400;
    line-height: 1;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.menu-univers-texte {
    grid-column: 1;
    margin-top: 7px;
    font-size: 12.5px;
    line-height: 1.3;
    letter-spacing: .01em;
    color: var(--grey);
}

.menu-univers-chevron {
    grid-column: 2;
    grid-row: 1 / span 2;
    width: 18px;
    height: 18px;
    color: var(--grey);
    transition: transform .22s cubic-bezier(.4, 0, .2, 1), color .2s ease;
}

.menu-univers-bouton[aria-expanded="true"] .menu-univers-chevron {
    transform: rotate(180deg);
    color: var(--ink);
}

@media (hover: hover) and (pointer: fine) {
    .menu-univers-bouton:hover .menu-univers-chevron {
        color: var(--ink);
    }
}

/* ---------- LE TIROIR -----------------------------------------

   De 0fr à 1fr : le tiroir s'ouvre à sa hauteur réelle, sans
   hauteur écrite en dur. 220 ms — le temps de voir qu'il
   s'ouvre, pas davantage. */

.menu-tiroir {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows .22s cubic-bezier(.4, 0, .2, 1);
}

.menu-tiroir.est-ouvert {
    grid-template-rows: 1fr;
}

.menu-tiroir-corps {
    min-height: 0;
    overflow: hidden;
}

.menu-tiroir-liens {
    display: flex;
    flex-direction: column;
    padding: 0 34px 22px;
}

/* 44 px de cible : un lien de tiroir se touche au doigt sans
   viser. Le fond de survol va jusqu'aux bords du panneau, le
   texte reste aligné sur le nom de l'univers. */
.sidebar-nav .menu-tiroir-liens a {
    display: flex;
    align-items: center;
    min-height: 44px;
    margin: 0 -34px;
    padding: 4px 34px;
    color: var(--grey-light);
    font-size: 15.5px;
    font-weight: 400;
    line-height: 1.3;
    text-decoration: none;
    transition: background-color .18s ease, color .18s ease;
}

.sidebar-nav .menu-tiroir-liens a:hover,
.sidebar-nav .menu-tiroir-liens a:focus-visible {
    background: rgba(var(--ink-rgb), .06);
    color: var(--ink);
    outline: none;
}

.sidebar-nav a.active {
    color: var(--ink);
    font-weight: 600;
}

/* ---------- LES ACTIONS « COMMENCER » -------------------------

   Elles ferment leur tiroir et se voient sans devenir des pavés
   publicitaires : capitales espacées et une flèche qui avance. */

.sidebar-nav .menu-tiroir-liens a.sidebar-cta {
    gap: .7rem;
    margin-top: 8px;
    color: var(--ink);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .16em;
    text-transform: uppercase;
}

.sidebar-cta-fleche {
    transition: transform .2s ease;
}

.sidebar-nav a.sidebar-cta:hover .sidebar-cta-fleche,
.sidebar-nav a.sidebar-cta:focus-visible .sidebar-cta-fleche {
    transform: translateX(5px);
}

/* ---------- LE BAS DU PANNEAU ---------------------------------

   Compte et réseaux : deux lignes en petit, en gris. Ils
   dépannent, ils ne concurrencent pas les quatre univers. */

.menu-secondaire {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 24px 34px 0;
}

.menu-secondaire-liens {
    display: flex;
    flex-wrap: wrap;
    gap: 0 20px;
}

.sidebar-nav .menu-secondaire a {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    color: var(--grey);
    font-size: 13px;
    text-decoration: none;
    transition: color .18s ease;
}

.sidebar-nav .menu-secondaire a:hover,
.sidebar-nav .menu-secondaire a:focus-visible {
    color: var(--ink);
}

.sidebar-marque {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 14px;
    height: 14px;
    margin-right: 8px;
}

.sidebar-marque svg {
    width: 100%;
    height: 100%;
}

.sidebar-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.3rem;
    height: 1.3rem;
    margin-left: 8px;
    padding: 0 .4rem;
    border-radius: 999px;
    background: var(--gold);
    color: var(--accent-ink);
    font-size: .72rem;
    font-weight: 600;
}

.sidebar-badge.hidden { display: none; }

@media (pointer: coarse) {
    .sidebar-nav .menu-secondaire a {
        min-height: 44px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .sidebar,
    .sidebar.active,
    .menu-tiroir,
    .menu-univers-chevron,
    .sidebar-cta-fleche {
        transition: none;
    }
}


/* =======================================================
   CATEGORIES
======================================================= */

.category-section{

    max-width:1700px;

    margin:0 auto 55px;

    padding:0 40px;

}

.category-link{

    display:block;

    color:inherit;

}

/* ===========================
   TITRE
=========================== */

.search-page-note{

    margin:4px 0 22px;

    font-size:13px;

    color:var(--grey-light);

}

.search-page-note:empty{

    display:none;

}

/* =======================================================
   EN-TÊTE DE RAYON

   CHANTIER CARTES 1/3, 12/09/2026. Un seul en-tête pour la
   Sélection et pour les rayons. Il y en avait deux : un tiret
   décoratif et une flèche dans un rond de 46 px d'un côté, un
   titre resserré de l'autre.

   Le titre est en Anton.

   CHANTIER SECTIONS V1, 15/09/2026 — LE SYSTÈME DE SECTIONS.
   La flèche grise seule au bout de la ligne ne disait ni qu'on
   pouvait cliquer, ni où l'on allait : une action écrite l'a
   remplacée. Les pages qui SONT la vue complète ont désormais
   un vrai titre de page, et les sections du panier le leur.

   TROIS NIVEAUX DE TITRE :
     · .category-header-page > h1 — titre d'une page qui est la
       vue complète (catalogue, rayons, À découvrir, recherche,
       Vêtements). Anton, le plus grand, détaché de l'en-tête
       du site, auquel il était collé (0 px) ;
     · .category-header > h2 — titre d'une section de page
       (accueil). Anton, l'échelle d'avant, inchangée ;
     · .category-header-secondaire > h2 et #reco-panier-titre —
       section subordonnée au travail de la page (panier).
       Anton, l'échelle des blocs du compte (.compte-bloc-titre),
       au lieu de 16,8 et 14 px.
   Les fiches gardent leurs titres en DM Sans (.pdp h2) : leur
   rail « Vous aimerez aussi » n'est pas repris ici.

   L'ACTION. L'aperçu d'une collection ouvre sur sa vue complète
   par TOUT son en-tête (a.category-link) : titre à gauche,
   action écrite à droite — « Tout voir », ou le nom de la
   destination quand ce n'est pas celle du titre (« Voir le
   catalogue »). Un seul lien, donc une seule tabulation et un
   nom accessible qui dit les deux ; la flèche est aria-hidden.
   Soulignée dès le repos : aucun survol n'est nécessaire pour
   la reconnaître. Cible : toute la ligne, 44 px de haut au
   moins.
   Une section SANS vue complète (recommandations) n'a pas
   d'action : aucune page ne les montre toutes.

   LA FIN DE SECTION. Là où la grille s'empile (≤ 1 199 px),
   l'en-tête a quitté l'écran quand on atteint la dernière
   pièce : .section-fin referme la section sur la même
   destination, sous le pouce, entre deux filets. Au-delà, la
   section tient sur une rangée et ce lien n'existe pas.

   AUCUN FILET DANS L'EN-TÊTE. Le trait sous le titre appartient
   à la grille (.products, border-top) : il n'existe que s'il y
   a des pièces dessous, et ne se double pas quand une barre de
   filtres s'intercale entre les deux.
======================================================= */

.category-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 20px;
    margin: 0;
    padding: 0 0 clamp(12px, 1.2vw, 16px);
    border: 0;
}

.category-header h2 {
    min-width: 0;
    margin: 0;
    font-family: "Anton", sans-serif;
    font-size: clamp(22px, 2vw, 30px);
    font-weight: 400;
    line-height: 1.05;
    letter-spacing: .035em;
    text-transform: uppercase;
    color: var(--ink);
}

/* --- Titre de page ------------------------------------- */

.category-header-page {
    padding: clamp(28px, 3.2vw, 48px) 0 clamp(18px, 1.8vw, 26px);
}

.category-header-page h1 {
    min-width: 0;
    margin: 0;
    font-family: "Anton", sans-serif;
    font-size: clamp(28px, 3.4vw, 50px);
    font-weight: 400;
    line-height: 1;
    letter-spacing: .02em;
    text-transform: uppercase;
    overflow-wrap: anywhere;
    color: var(--ink);
}

/* --- Titre secondaire ---------------------------------- */

/* Même écart titre → grille que les sections (12 à 16 px) : un
   titre plus petit n'a pas à flotter plus loin de ses pièces
   (il en était à 21 px, contre 12 à 16 pour un titre plus grand). */
.category-header-secondaire {
    padding-bottom: clamp(12px, 1.2vw, 16px);
}

.category-header-secondaire h2,
#reco-panier-titre {
    font-family: "Anton", sans-serif;
    font-size: 1.15rem;
    font-weight: 400;
    line-height: 1.1;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--ink);
}

#reco-panier-titre {
    margin: 0 0 clamp(12px, 1.2vw, 16px);
}

/* --- Action ---------------------------------------------- */

.section-action,
.section-fin {
    font-family: "DM Sans", sans-serif;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--ink);
}

.section-action {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
    white-space: nowrap;
}

.section-action-texte {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 5px;
    text-decoration-color: rgba(var(--ink-rgb), .35);
    transition: text-decoration-color .22s ease;
}

.section-action-fleche {
    font-size: 15px;
    line-height: 1;
    transition: transform .22s cubic-bezier(.22, 1, .36, 1);
}

/* LA CIBLE S'ÉTEND AU-DESSUS DU TITRE, ELLE N'ÉTIRE PAS L'EN-TÊTE
   (chantier système des sections, 15/09/2026).
   Un min-height de 44 px centrait un titre de 23 px dans son
   en-tête : sous 1 200 px, le titre lié flottait à 16-17 px de sa
   grille quand un titre sans action y était posé à 12 px, et la
   section suivante reculait d'autant. Le lien gagne 12 px de zone
   d'appui au-dessus du titre, rendus par une marge négative : la
   cible dépasse 44 px, la mise en page est celle d'un titre sans
   action. */
.category-link {
    padding-top: 12px;
    margin-top: -12px;
}

.category-link:focus-visible {
    outline: 1px solid var(--ink);
    outline-offset: 4px;
}

.category-link:focus-visible .section-action-texte,
.section-fin:focus-visible .section-action-texte {
    text-decoration-color: currentColor;
}

.category-link:focus-visible .section-action-fleche,
.section-fin:focus-visible .section-action-fleche {
    transform: translateX(4px);
}

@media (hover: hover) and (pointer: fine) {
    .category-link:hover .section-action-texte,
    .section-fin:hover .section-action-texte {
        text-decoration-color: currentColor;
    }

    .category-link:hover .section-action-fleche,
    .section-fin:hover .section-action-fleche {
        transform: translateX(4px);
    }
}

/* --- Fin de section ---------------------------------------
   Le filet du haut recouvre (-1 px) celui de la dernière
   rangée : il court sur toute la largeur même quand la rangée
   est entamée. */

.section-fin {
    display: none;
}

@media (max-width: 1199px) {
    .section-fin {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 16px;
        min-height: 52px;
        margin-top: -1px;
        border-top: 1px solid var(--line);
        border-bottom: 1px solid var(--line);
    }
}

.section-fin:focus-visible {
    outline: 1px solid var(--ink);
    outline-offset: -1px;
}

/* Téléphone : « SÉLECTION ARKWER » et « VOIR LE CATALOGUE »
   doivent tenir sur une ligne dans 339 px. À 12 px, l'action
   (164 px) coupait le titre en deux lignes. Le titre garde sa
   taille ; l'action se resserre, sans passer sous 11 px.
   Un titre plus long que la ligne (« Des pièces disponibles
   aujourd'hui ») ne se laisse pas broyer en trois lignes par
   l'action : elle passe dessous, alignée à gauche.
   Le titre, lui, ne rétrécit pas pour tenir sur une ligne : le
   titre secondaire gardait 1,05 rem sur téléphone contre
   1,15 rem ailleurs. Il garde sa taille et passe à la ligne
   s'il le faut (chantier système des sections). */
@media (max-width: 560px) {
    .category-header {
        gap: 12px;
    }

    .category-link .category-header {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    .section-action {
        gap: 8px;
        font-size: 11px;
        letter-spacing: .05em;
    }

    .section-action-fleche {
        font-size: 14px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .section-action-texte,
    .section-action-fleche {
        transition: none;
    }
}

/* =======================================================
   GRILLE PRODUITS ET CARTE — UN SEUL SYSTÈME

   CHANTIER CARTES 1/3, 12/09/2026.

   Il y avait deux cartes : la boîte du catalogue (fond gris,
   rayon de 10 px, cœur blanc flottant) et le présentoir de la
   Sélection, obtenu en réarrangeant la première après coup puis
   en la redéfinissant sur six cents lignes. Il n'en reste
   qu'une, partout : accueil, rayons, recherche, compte, rail
   des fiches, panier.

   PAS DE BOÎTE. Ni rayon, ni ombre, ni contour par carte.
   Un FOND, depuis le chantier surfaces (15/09/2026) : sans lui,
   la carte avait exactement la couleur de la page — écart de
   luminance nul, mesuré sur 90 vues — et ne se lisait en clair
   que par ses filets, comme un tableau. --carte-surface (voir
   VARIABLES) est un voile, pas un aplat : blanc à 85 % sur le
   crème, blanc de la palette à 4 % sur le noir, 2,5 % sur le
   gris de la fiche. Les cellules étant jointives, la grille se
   lit comme une surface de présentation posée sur la page.
   La structure reste portée par la GRILLE :
     · un filet au-dessus des pièces — celui du titre ;
     · un filet sous chaque rangée ;
     · un montant entre deux colonnes.
   Chaque montant est dessiné à gauche de sa cellule, un pixel
   hors d'elle. Ceux de la première colonne tombent hors de la
   grille, et overflow:hidden les efface : aucune règle ne
   dépend du nombre de colonnes, le système tient à 5, 4, 2 ou
   1 colonne sans être réécrit.

   --cellule est le rembourrage des cellules. Le panier et la
   mention VENDU s'y calent : une variable, pour que les trois
   restent d'accord.
======================================================= */

.products {
    --cellule: clamp(12px, 1.25vw, 20px);

    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0;
    border-top: 1px solid var(--line);
    overflow: hidden;
}

/* Une grille vide ne laisse pas de trait orphelin. */
.products:empty {
    border-top: 0;
}

/* Sous une barre de filtres, le filet de la barre fait déjà la
   séparation : un second trait quarante pixels plus bas serait
   une ligne de trop, et des montants partant de ce vide
   flotteraient. La grille remonte donc sur le filet de la barre
   — dont la marge basse de 40 px n'est pas touchée — et ses
   montants viennent y buter. */
.filter-bar + .products {
    margin-top: -40px;
    border-top: 0;
}

.card {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    padding: var(--cellule, 14px) var(--cellule, 14px) calc(var(--cellule, 14px) + 6px);
    background: var(--carte-surface);
    border: 0;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    font-family: "DM Sans", sans-serif;
    color: var(--ink);
}

/* Le montant, à gauche de la cellule. */
.card::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: -1px;
    width: 1px;
    background: var(--line);
    pointer-events: none;
}

.products > .card:first-child::after {
    display: none;
}

/* LA RÉACTION DE LA GRILLE, AU SURVOL.
   Le filet sous la carte survolée fonce d'un ton, rien de plus :
   il ne se dessine pas, ne se déplace pas, seule son opacité
   change. Le tracé à l'encre de gauche à droite qui l'a précédé
   se remarquait comme un effet ; il a été retiré. */
.card::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    z-index: 1;
    height: 1px;
    background: rgba(var(--ink-rgb), .38);
    opacity: 0;
    transition: opacity .22s ease;
    pointer-events: none;
}

.card-lien {
    display: block;
    color: inherit;
    text-decoration: none;

    /* Au doigt, le navigateur teinte la zone du lien pendant
       l'appui — ici la carte entière, puisque le lien la couvre.
       L'appui ouvre la fiche : il n'a rien d'autre à montrer. */
    -webkit-tap-highlight-color: transparent;
}

/* LA CARTE ENTIÈRE EST CLIQUABLE sans rien imbriquer dans le
   lien : son ::after s'étend sur toute la cellule. Le panier
   est posé au-dessus (z-index 3), en frère du lien. */
.card-lien::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
}

.card-lien:focus-visible::after {
    outline: 1px solid var(--ink);
    outline-offset: -3px;
}

/* LA PHOTO.
   Un cadre plus haut que large : la carte devient verticale et
   la pièce en est le sujet. Les fichiers sont carrés et
   détourés ; object-fit:contain les montre ENTIERS, posés sur
   le bas du cadre, et l'air laissé en haut accueille le panier.

   scale(1.07) AU REPOS, ET CE N'EST PAS UN ROGNAGE.
   Chaque fichier garde une marge transparente autour de la
   pièce. Relevé au pixel sur les 63 miniatures : la plus serrée
   (cp18) laisse 4,2 % de chaque côté, soit une échelle sûre de
   1,09. À 1,07, aucune pièce n'atteint le bord de son cadre, et
   le cadre ne coupe rien de toute façon (overflow visible) :
   l'agrandissement se prend sur la marge du fichier, jamais sur
   le vêtement. L'échelle part du bas : la pièce reste posée. */
.card-visuel {
    position: relative;
    display: block;
    aspect-ratio: 1 / 1.2;
    transform-origin: 50% 100%;
    transition: transform .22s cubic-bezier(.22, 1, .36, 1);
}

.card-visuel img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: 50% 100%;
    transform: scale(1.07);
    transform-origin: 50% 100%;

    /* Sans ombre, une pièce claire se confond avec la page en
       thème clair. */
    filter: drop-shadow(var(--photo-shadow-card));
}

/* LE SURVOL.
   Seulement avec une vraie souris, et seulement si le système
   n'a pas demandé moins d'animation. Au doigt, :hover resterait
   collé après l'appui — l'appui ouvre la fiche, directement. En
   mouvement réduit, la carte reste exactement dans son état de
   repos.
   Deux choses bougent, et aucune dimension : la photo grandit de
   3,5 % en 220 ms, posée sur sa base, et le filet de la cellule
   fonce d'un ton. Pas de reflow, pas de décalage. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {

    .card:not(.card-soldout):hover .card-visuel {
        transform: scale(1.035);
    }

    .card:not(.card-soldout):hover::before {
        opacity: 1;
    }

}

/* Le panier garde sa propre réaction, indépendante de la carte. */
@media (hover: hover) and (pointer: fine) {
    .card-panier:not(:disabled):hover {
        color: var(--ink);
    }
}

/* LE PANIER, EN HAUT À DROITE.
   Le cabas de l'en-tête, sans rond ni fond : un signe, pas un
   bouton d'interface. Il remplace le cœur des favoris et
   bascule comme lui — vide, la pièce n'est pas au panier ;
   plein, elle y est, et un second appui l'en retire (voir
   js/products.js, « LE PANIER DES CARTES »).
   L'icône est calée sur l'angle du cadre photo ; sa cible de
   clic la déborde : 38 px, 44 px au doigt. */
.card-panier {
    position: absolute;
    top: calc(var(--cellule, 14px) - 9px);
    right: calc(var(--cellule, 14px) - 9px);
    z-index: 3;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    color: var(--grey);
    cursor: pointer;
    transition: color .2s ease;
    -webkit-tap-highlight-color: transparent;
}

.card-panier-icone {
    display: block;
    width: 19px;
    height: 19px;
}

.card-panier-corps {
    fill: transparent;
    transition: fill .2s ease;
}

/* Le bouton est un trait de contour en gris : au survol il prend
   l'encre, comme le fait déjà l'état « au panier ». Sans cela,
   rien ne disait qu'il répondait. */
.card-panier:hover {
    color: var(--ink);
}

.card-panier:disabled:hover {
    color: rgba(var(--ink-rgb), .22);
}

.card-panier.est-au-panier {
    color: var(--ink);
}

.card-panier.est-au-panier .card-panier-corps {
    fill: currentColor;
}

/* Sac plein : le corps est rempli à l'encre, et le bord et l'anse
   sont tracés dans cette même encre — ils disparaissaient, il ne
   restait qu'un carré noir. On les passe à la couleur du fond pour
   qu'ils se lisent en réserve sur le plein. */
.card-panier.est-au-panier .card-panier-detail {
    stroke: var(--black);
    transition: stroke .2s ease;
}

.card-panier:focus-visible {
    color: var(--ink);
    outline: 1px solid var(--ink);
    outline-offset: -6px;
}

.card-panier:disabled {
    color: rgba(var(--ink-rgb), .22);
    cursor: default;
}

@media (pointer: coarse) {
    .card-panier {
        top: calc(var(--cellule, 14px) - 12px);
        right: calc(var(--cellule, 14px) - 12px);
        width: 44px;
        height: 44px;
    }
}

/* VENDU : un mot, pas une pastille. Dans l'angle opposé au
   panier, à la hauteur de son icône. */
.badge {
    position: absolute;
    top: var(--cellule, 14px);
    left: var(--cellule, 14px);
    z-index: 3;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    font-size: var(--t-micro);
    font-weight: 600;
    line-height: 19px;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--ink);
    pointer-events: none;
}

/* QUATRE LIGNES : MARQUE, NOM, TAILLE · ÉTAT, PRIX.
   Dans cet ordre, chacune sur sa ligne, en DM Sans. Le prix se
   distingue par sa graisse, pas par une autre police. Le détail
   des corps et des tons est commenté au bloc .product-info, plus
   bas : c'est là que se décide la hiérarchie. */
/* =========================================================
   LE BLOC DE TEXTE DE LA CARTE

   CE QU'IL DISAIT, ET CE QUI MANQUAIT

   Trois lignes : la marque, la taille, le prix. Pas le nom de la
   pièce, pas son état. Sur un catalogue où la quasi-totalité des
   pièces porte la même marque, une rangée donnait cinq fois
   « C.P. COMPANY » — rien à lire, rien pour choisir, et l'œil
   n'avait que les photos pour se repérer.

   QUATRE LIGNES MAINTENANT, AVEC UNE HIÉRARCHIE

     marque   12 px, capitales, encre     — ce qu'on reconnaît
     nom      13,5 px, gris clair          — ce qu'on achète
     taille · état   11,5 px, gris          — ce qui décide
     prix     16,5 px, gras, encre         — ce qu'on compare

   Trois tailles de corps et trois tons pour quatre lignes : chaque
   information a un rang, et l'œil les prend dans cet ordre. Avant,
   la marque et le prix avaient le même poids et la taille flottait
   entre les deux.

   L'ALIGNEMENT DES PRIX. Le nom peut tenir sur une ou deux lignes,
   et une rangée mélange les deux. Au lieu de forcer une hauteur
   minimale sur chaque ligne — ce que faisait l'ancienne règle, et
   qui cassait dès qu'une ligne manquait —, le bloc occupe toute la
   hauteur restante et le prix est poussé en bas. Les prix d'une
   rangée s'alignent alors quelle que soit la longueur des noms.
   ========================================================= */

.card .product-info {
    position: relative;

    /* flex: 1 — le bloc prend ce qui reste sous la photo, ce qui
       permet au prix de se caler en bas. */
    flex: 1;

    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    margin: clamp(13px, 1.3vw, 19px) 0 0;
    text-align: left;
}

/* Écrit sous .card : une règle de page sur les <p> — celle du
   panier vide leur donnait 15 px et un gris clair — ne peut plus
   changer la typographie de la carte. */
.card .product-brand {
    width: 100%;
    margin: 0;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--ink);

    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* LE NOM DE LA PIÈCE.
   Sur --grey-light et non --grey : c'est le second rang de
   lecture, pas le troisième. Dans les deux thèmes, --grey-light
   est le gris le plus proche de l'encre (6,6:1 en sombre, 8,3:1
   en clair), donc le plus lisible des deux — il porte bien un
   nom qu'on lit vraiment, là où --grey porte une légende.

   Deux lignes au maximum : au-delà, un nom long repousserait le
   prix et déséquilibrerait la rangée. */
.card .product-nom {
    width: 100%;
    margin: 1px 0 0;
    font-size: 13.5px;
    font-weight: 400;
    line-height: 1.32;
    letter-spacing: .005em;
    color: var(--grey-light);

    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* LA LIGNE TAILLE · ÉTAT.
   min-height conservée : la ligne doit tenir sa place même vide
   (un sac sans taille), sinon le nom et le prix se rapprochent
   sur cette carte-là et la rangée tremble. */
.card .product-meta {
    min-height: 1.4em;
    margin: 5px 0 0;
    font-size: 11.5px;
    font-weight: 400;
    line-height: 1.4;
    letter-spacing: .015em;
    color: var(--grey);
}

.card .product-meta-sep {
    margin: 0 .45em;
    opacity: .55;
}

/* L'ÉTAT, EN BAS DE CASSE.
   Essayé d'abord en capitales, pour le détacher de la taille. La
   carte se retrouvait avec deux lignes capitalisées — la marque et
   l'état — qui se disputaient le même rang de lecture, et l'état,
   qui n'est qu'un renseignement, criait aussi fort que la marque,
   qui est ce qu'on reconnaît.

   Le point médian sépare déjà les deux membres. Il n'y avait rien
   à ajouter. */
.card .product-etat {
    font-weight: 500;
}

/* margin-top: auto — c'est lui qui aligne les prix d'une rangée.
   Le padding-top garde l'air sous la ligne d'état quand le nom
   ne fait qu'une ligne et que « auto » ne pousse rien. */
.card .product-price {
    margin: auto 0 0;
    padding-top: 10px;
    font-size: 16.5px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -.005em;
    color: var(--ink);
}

/* Sous 520 px, le texte de la carte grandit d'un cran. */
@media (max-width: 520px) {

    .card .product-brand {
        font-size: 12.5px;
    }

    .card .product-nom {
        font-size: 14px;
    }

    .card .product-price {
        font-size: 17.5px;
    }

}

/* =======================================================
   RESPONSIVE
======================================================= */

@media(max-width:1000px){

    .category-section{

        padding:0 25px;

    }

    .catalog-filter-scope > .filter-bar{

        padding-left:25px;

        padding-right:25px;

    }

}

@media(max-width:700px){

    .mobile-hide{

        display:none;

    }

    .navbar-top{

        padding:0 22px;

        height:68px;

    }

    /* L ECART SE RESSERRE AVEC LES ICONES. A 375 px, quatre
       elements separes de 22 px font 227 px, et la barre entiere
       410 px pour 375 disponibles : 35 px dehors. Mesure avec le
       panier ET l enveloppe ET le profil ; deux sur trois tenaient.
       A 10 px, la rangee tombe a 191 px et la barre rentre. */
    .navbar-top-actions{

        gap:10px;

    }

    /* Les trois de la rangee descendent ensemble. Oublier le bouton
       de profil le laissait a 42 px face a deux icones de 36 : la
       rangee devenait bancale, et les 6 px en trop suffisaient a
       pousser la barre hors de l ecran. Mesure sur une fiche. */
    .messages-icon:not(.hidden),
    .navbar-profil:not(.hidden),
    .cart-icon{

        width:36px;

        height:36px;

    }

    .navbar-profil svg{ width:19px; height:19px; }

    .catalog-filter-scope > .filter-bar{

        padding-left:18px;

        padding-right:18px;

    }

    .category-section{

        margin-bottom:40px;

        padding:0 18px;

    }

}

/* LA GRILLE PAR LARGEUR — UNE SEULE RÈGLE POUR TOUT LE SITE
   Accueil, Sélection, rayons, recherche, recommandations,
   produits similaires, panier, espace client (13/09/2026).
   5 colonnes à partir de 1200 px ;
   3 de 769 à 1199 px ; 2 jusqu'à 768 px ; une seule sous
   360 px, où deux cartes deviendraient trop étroites.
   Écrit APRÈS les paliers responsive plus anciens, qui
   l'emporteraient sinon à spécificité égale. */
@media (max-width: 1199px) {
    .products {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 768px) {
    .products {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 520px) {
    .products {
        --cellule: 14px;
    }
}

@media (max-width: 359px) {
    .products {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* =======================================================
   INDICATEUR DE PROGRESSION

   Remplace la barre de défilement du navigateur, qui posait une
   colonne de 10 px opaque (son rail était peint en --black) contre
   le bord droit. Cette colonne coupait la photographie du hero du
   bord de l'écran : l'image s'arrêtait 10 px trop tôt.

   Une barre native ne peut pas faire autrement — elle occupe une
   place dans la mise en page, donc rien ne peut passer dessous. On
   la retire donc et on la remplace par une couche flottante,
   posée PAR-DESSUS le contenu : la photographie va désormais
   jusqu'au bord, et l'indicateur se lit par transparence.

   Ce n'était pas sa LARGEUR qui posait problème, mais le fait que
   l'image s'arrête à son bord. Elle reste donc confortable — de
   quoi l'attraper à la souris — et c'est la transparence qui la
   rend discrète : rail à 5 %, curseur à 18 %.

   Le curseur est construit, animé et rendu saisissable par
   initIndicateurProgression() dans js/script.js.
======================================================= */

/* On masque la barre native sans supprimer le défilement. */

html{

    scrollbar-width:none;

}

html::-webkit-scrollbar,
body::-webkit-scrollbar{

    width:0;

    height:0;

}

.progression{

    position:fixed;

    top:0;

    right:0;

    z-index:5500;

    width:11px;

    height:100vh;

    /* La couche reçoit les clics : c'est ce qui permet de saisir le
       curseur et de cliquer dans le rail pour sauter. Le contenu de
       la page passe visuellement dessous, mais ces 11 px lui sont
       réservés — comme l'était la barre native. */
    background:rgba(var(--ink-rgb),.05);

    opacity:0;

    transition:opacity .35s ease, background-color .2s ease;

}

/* Sur écran tactile, une bande fixe qui capte les gestes au bord
   droit gênerait le défilement au doigt. On la laisse alors
   purement décorative. */

@media(pointer:coarse){

    .progression{

        pointer-events:none;

        width:4px;

    }

}

/* Tant que la page n'est pas assez longue pour défiler, l'indicateur
   n'a rien à indiquer : le script ne pose cette classe que s'il y a
   réellement une progression à montrer. */

.progression.est-utile{

    opacity:1;

}

.progression:hover{

    background:rgba(var(--ink-rgb),.09);

}

.progression-curseur{

    position:absolute;

    top:0;

    left:2px;

    right:2px;

    border-radius:999px;

    background:rgba(var(--ink-rgb),.18);

    cursor:grab;

    transition:background-color .2s ease;

    /* Pas de transition sur la position : le curseur doit coller au
       défilement, pas le suivre avec un temps de retard. */

}

.progression:hover .progression-curseur{

    background:rgba(var(--ink-rgb),.32);

}

/* Pendant le glissement, le curseur reste appuyé même si la souris
   sort de la bande — d'où une classe posée sur la piste plutôt
   qu'un simple :active. */

.progression.en-glissement .progression-curseur{

    background:rgba(var(--ink-rgb),.46);

    cursor:grabbing;

}

/* Le glissement sélectionnerait le texte de la page en passant
   dessus : on le neutralise le temps du geste. */

body.glisse-indicateur{

    user-select:none;

    cursor:grabbing;

}

/* =======================================================
   SELECTION
======================================================= */

::selection{

    background:var(--ink);

    color:var(--accent-ink);

}

/* =======================================================
   FOCUS
======================================================= */

button:focus,
a:focus{

    outline:none;

}

/* =======================================================
   FOOTER (préparation)
======================================================= */

footer{

    margin-top:120px;

    padding:60px 40px;

    border-top:1px solid var(--line);

}

footer p{

    color:var(--grey);

    font-size:14px;

}

.footer-container{

    max-width:1700px;

    margin:0 auto;

    display:grid;

    grid-template-columns:repeat(4,minmax(0,1fr));

    gap:40px;

}

.footer-column h3{

    margin-bottom:18px;

    font-size:18px;

    font-weight:700;

    letter-spacing:2px;

}

.footer-column h4{

    margin-bottom:18px;

    font-size:13px;

    font-weight:600;

    letter-spacing:1.5px;

    text-transform:uppercase;

    color:var(--grey-light);

}

.footer-column p{

    color:var(--grey);

    font-size:14px;

    line-height:1.7;
}

.footer-column a{

    display:block;

    margin-bottom:12px;

    color:var(--grey-light);

    font-size:14px;

    transition:color .2s ease;
}

.footer-column a:hover{

    color:var(--ink);

    text-decoration:underline;
}

.footer-bottom{

    max-width:1700px;

    margin:60px auto 0;

    padding-top:30px;

    border-top:1px solid var(--line);

    text-align:center;
}

@media(max-width:900px){

    .footer-container{

        grid-template-columns:repeat(2,minmax(0,1fr));

        row-gap:40px;
    }

}

@media(max-width:500px){

    .footer-container{

        grid-template-columns:1fr;
    }

}

/* =======================================================
   PAGE LÉGALE (mentions-legales.html)
======================================================= */

.legal-page{

    max-width:900px;

    margin:0 auto;

    padding:60px 40px 120px;

}

.legal-page h1{

    margin-bottom:50px;

    font-size:34px;

    font-weight:700;

    letter-spacing:2px;

    text-transform:uppercase;

}

.legal-section{

    margin-bottom:44px;

    padding-bottom:44px;

    border-bottom:1px solid var(--line);

}

.legal-section:last-child{

    border-bottom:none;

}

.legal-section h2{

    margin-bottom:16px;

    font-size:18px;

    font-weight:600;

    letter-spacing:1px;

}

.legal-section p{

    color:var(--grey-light);

    font-size:14px;

    line-height:1.9;

}

.legal-section p + p,
.legal-liste + p{

    margin-top:14px;

}

.legal-liste{

    margin:12px 0 0;

    padding-left:20px;

    color:var(--grey-light);

    font-size:14px;

    line-height:1.8;

}

.legal-liste li{

    margin-bottom:8px;

}

.legal-liste strong{

    color:var(--ink);

    font-weight:600;

}

.legal-lien-bouton{

    padding:0;

    background:none;

    border:none;

    color:var(--ink);

    font:inherit;

    text-decoration:underline;

    cursor:pointer;

}

.legal-section .legal-maj{

    font-size:12px;

    color:var(--grey);

}

@media(max-width:700px){

    .legal-page{

        padding:40px 20px 80px;

    }

    .legal-page h1{

        font-size:26px;

        margin-bottom:35px;

    }

}

/* =======================================================
   SURTITRE (reste de l'ancienne page authenticité)

   Dernier survivant d'un ensemble qui comptait aussi .trust-cta,
   .trust-cta-button et toute la promo .authenticity-promo. Tous
   supprimés avec la section Livraison de l'accueil, qui était leur
   dernier usage. Celui-ci sert encore à laisser-un-avis.html.
======================================================= */

.trust-eyebrow{

    font-size:12px;

    letter-spacing:4px;

    text-transform:uppercase;

    color:var(--grey);

    margin-bottom:18px;

}


/* ===========================
   PAGE AUTHENTICITÉ (authenticite.html)

   Huit blocs, un seul mouvement : le doute du visiteur qui se
   défait.

   CE QUI A CHANGÉ LE 07/09/2026, ET POURQUOI
   ------------------------------------------------------------------
   La page comptait dix sections et 7 700 px de haut. Le texte
   était bon, le rythme ne l'était pas : chaque phrase occupait un
   écran, et il fallait quatre défilements avant la première
   preuve. Un visiteur qui ne lit pas tout ne comprenait rien.

   Elle est maintenant construite pour être comprise EN DÉFILANT,
   sans lire un seul paragraphe : les grands titres et les quatre
   photographies racontent seuls la chaîne de contrôle.

   AUCUNE PHRASE N'A ÉTÉ RÉÉCRITE NI SUPPRIMÉE. Les trente-sept
   textes d'origine sont tous là, au mot près. Ce qui a changé,
   c'est leur hiérarchie et leur hauteur : les sections 1 et 2 ont
   fusionné, de même que 7 à 10, et les paddings verticaux ont été
   divisés par deux environ.

   QUATRE RÈGLES QUI TIENNENT TOUTE LA PAGE
   ------------------------------------------------------------------
   1. UNE LARGEUR DE LECTURE UNIQUE. Tout est aligné sur la même
      colonne de 1180 px. Les deux seules ruptures sont les deux
      débordements photographiques, et c'est précisément parce
      qu'elles sont rares qu'elles se remarquent.

   2. UN SEUL VOCABULAIRE POUR « LISTE ». Les trois temps du
      problème et les cinq critères d'examen utilisent le même
      filet d'un pixel. Rien n'est encadré, rien n'a de fond, rien
      n'a de rayon : ce ne sont jamais des cartes.

   3. RESPIRATION → INFORMATION → PREUVE. Un filet horizontal
      sépare chaque bloc, et c'est la seule séparation. Il n'y a
      plus une seule zone vide de plus de 100 px.

   4. ANTON POUR CE QU'ON DOIT COMPRENDRE SANS LIRE, DM Sans pour
      ce qu'on lit. Un titre en Anton = une étape du raisonnement.
      Il y en a exactement six, ce sont les six choses à retenir.

   Le préfixe certif- n'existe nulle part ailleurs, donc rien de
   ce qui suit ne peut déborder sur une autre page.
=========================== */

/* Colonne de lecture commune. Les huit blocs s'y accrochent :
   c'est l'axe unique dont parle la règle 1. */

.certif-intro,
.certif-probleme,
.certif-methode,
.certif-transition,
.certif-piece,
.certif-examen,
.certif-certification,
.certif-final{

    width:100%;

    max-width:1180px;

    margin:0 auto;

    padding:0 clamp(24px,5vw,80px);

    box-sizing:border-box;

}

/* Le filet qui sépare les blocs. Un pixel, jamais deux, et
   aucune autre séparation : ni fond alterné, ni encadré, ni
   ombre. C'est ce filet qui donne le rythme, pas le vide. */

.certif-probleme,
.certif-methode,
.certif-transition,
.certif-examen,
.certif-certification,
.certif-final{

    border-top:1px solid var(--line);

}

/* ---------- 1. L'INTRODUCTION ---------- */

/* Cinq phrases, cinq poids décroissants sauf un : la question.
   Elle est le seul élément écrit en grand parce qu'elle est la
   seule chose que le visiteur se demande vraiment.

   Tout est aligné à gauche. Centrer ces cinq lignes les aurait
   transformées en diapositive de séminaire. */

.certif-intro{

    padding-top:clamp(52px,7.5vh,100px);

    padding-bottom:clamp(42px,5.6vh,72px);

}

.certif-intro-amorce{

    margin:0;

    font-family:"Anton",sans-serif;

    font-size:clamp(20px,2.2vw,30px);

    line-height:1.05;

    letter-spacing:.02em;

    text-transform:uppercase;

    color:var(--ink);

}

/* Ce qu'on a vérifié : volontairement plat, gris et petit. C'est
   la liste des gestes qu'on a faits pour rien. */

.certif-intro-liste{

    margin:10px 0 0;

    color:var(--grey-light);

    font-size:clamp(11.5px,1.05vw,14px);

    letter-spacing:.16em;

    text-transform:uppercase;

}

.certif-intro-bascule{

    margin:clamp(22px,3vh,36px) 0 0;

    color:var(--grey-light);

    font-size:15px;

    line-height:1.6;

}

.certif-intro-question{

    margin:8px 0 0;

    max-width:15ch;

    font-family:"Anton",sans-serif;

    font-size:clamp(40px,6.6vw,96px);

    line-height:.95;

    letter-spacing:.005em;

    text-transform:uppercase;

    color:var(--ink);

}

.certif-intro-verdict{

    margin:clamp(20px,2.8vh,32px) 0 0;

    color:var(--ink);

    font-size:clamp(17px,1.8vw,25px);

    font-weight:500;

    line-height:1.35;

}

/* ---------- 2. LE PROBLÈME ---------- */

/* Le constat tient la colonne de gauche, la rupture la droite.
   Empilés, ils faisaient deux écrans ; côte à côte, ils se lisent
   d'un regard — et c'est bien un regard qu'il faut, puisque
   l'un contredit l'autre. */

.certif-probleme{

    padding-top:clamp(42px,5.6vh,72px);

    padding-bottom:clamp(42px,5.6vh,72px);

    display:grid;

    grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);

    gap:clamp(24px,3.6vw,60px);

    align-items:start;

}

.certif-probleme-phrase{

    margin:0;

    max-width:30ch;

    color:var(--ink);

    font-size:clamp(15.5px,1.45vw,20px);

    line-height:1.55;

}

/* Trois lignes, trois temps. Toujours empilées et non réunies en
   une phrase : c'est leur brièveté successive qui fait entendre
   la mécanique. Le filet est le même que celui des cinq critères
   d'examen — la page n'a qu'une façon d'écrire une liste. */

.certif-secondes{

    list-style:none;

    margin:clamp(16px,2.2vh,24px) 0 0;

    padding:0;

}

.certif-secondes li{

    margin:0 0 7px;

    padding:0 0 0 15px;

    border-left:1px solid var(--line);

    color:var(--grey-light);

    font-size:14.5px;

    line-height:1.5;

}

.certif-rupture{

    margin:0;

    font-family:"Anton",sans-serif;

    font-size:clamp(28px,4.2vw,60px);

    line-height:1;

    letter-spacing:.01em;

    text-transform:uppercase;

    color:var(--ink);

}

/* La bascule vers la méthode. Elle occupait une section entière
   et un écran ; elle est maintenant la dernière ligne du
   problème, sous un filet. Même phrase, même place dans le
   raisonnement, un dixième de la hauteur. */

.certif-transition-methode{

    grid-column:1 / -1;

    margin:clamp(26px,3.6vh,44px) 0 0;

    padding-top:clamp(18px,2.4vh,28px);

    border-top:1px solid var(--line);

    color:var(--grey-light);

    font-size:clamp(14.5px,1.35vw,19px);

    line-height:1.5;

}

/* ---------- 3. LA MÉTHODE ---------- */

/* Quatre contrôles, quatre colonnes, un filet entre chacune.

   L'ancienne version les empilait le long d'un axe vertical sur
   680 px : on comprenait qu'il y avait une chaîne, mais il
   fallait défiler pour la voir en entier. En ligne, les quatre
   étapes entrent dans un seul regard — c'est tout l'objet de ce
   bloc.

   Le numéro est l'élément le plus visible de chaque colonne parce
   que c'est lui qui dit qu'il y a un ORDRE, et l'ordre est le
   propos : le contrôle commence au vendeur, la certification
   n'arrive qu'en quatrième. */

.certif-methode{

    padding-top:clamp(42px,5.6vh,72px);

    padding-bottom:clamp(42px,5.6vh,72px);

}

.certif-etapes{

    list-style:none;

    margin:0;

    padding:0;

    display:grid;

    grid-template-columns:repeat(4,minmax(0,1fr));

}

.certif-etape{

    padding:0 clamp(12px,1.7vw,28px);

    border-left:1px solid var(--line);

}

.certif-etape:first-child{

    padding-left:0;

    border-left:none;

}

.certif-etape-num{

    margin:0;

    font-family:"Anton",sans-serif;

    font-size:clamp(24px,3vw,42px);

    line-height:1;

    letter-spacing:.02em;

    color:var(--ink);

}

.certif-etape-quoi{

    margin:12px 0 0;

    color:var(--grey-light);

    font-size:11px;

    letter-spacing:.18em;

    text-transform:uppercase;

}

.certif-etape-titre{

    margin:6px 0 0;

    color:var(--ink);

    font-size:clamp(14px,1.3vw,18px);

    font-weight:600;

    line-height:1.3;

}

.certif-etape-texte{

    margin:10px 0 0;

    color:var(--grey-light);

    font-size:13.5px;

    line-height:1.6;

}

/* ---------- 4. LA TRANSITION ---------- */

/* Deux lignes et rien d'autre. Ce bloc n'a qu'un travail : dire
   que ce qui suit n'est plus une explication mais une preuve.
   Il ne lui faut pas un écran pour ça, il lui faut un filet
   au-dessus et de l'air en dessous. */

.certif-transition{

    padding-top:clamp(44px,6vh,78px);

    padding-bottom:clamp(28px,3.8vh,46px);

}

.certif-transition-titre{

    margin:0;

    font-family:"Anton",sans-serif;

    font-size:clamp(26px,3.6vw,50px);

    line-height:1.04;

    letter-spacing:.01em;

    text-transform:uppercase;

    color:var(--ink);

}

/* ---------- LES QUATRE PHOTOGRAPHIES ---------- */

/* Trois règles communes, et rien d'autre.

   1. AUCUN CADRE. Ni arrondi, ni ombre, ni bordure. Sur un fond
      sombre, une photographie n'a besoin d'aucun contenant — lui
      en donner un la transforme en vignette de catalogue.

   2. UNE HAUTEUR TOUJOURS EXPLICITE OU DÉDUITE D'UNE LARGEUR,
      JAMAIS D'UN max-height. Relevé le 07/09/2026 : tant qu'une
      boîte tire sa hauteur d'un aspect-ratio, un max-height se
      transfère en max-width et la boîte RÉTRÉCIT au lieu de
      rogner (mesuré : 468 px de large au lieu de 900). On plafonne
      donc soit la colonne, soit la hauteur en dur.

   3. LES DEUX DÉBORDEMENTS SONT DES ENFANTS DE SECTION, jamais
      la section elle-même : à l'intérieur d'un conteneur centré,
      « 50% » vaut la moitié de la colonne de lecture, donc
      calc(50% - 50vw) est exactement la marge restante jusqu'au
      bord de l'écran. Appliquer la même formule à la section
      casserait son centrage automatique. */

.certif-photo{

    margin:0;

    overflow:hidden;

}

.certif-photo img{

    display:block;

    width:100%;

    height:100%;

    object-fit:cover;

}

/* ---------- 5. LA PIÈCE ---------- */

/* Première preuve. Le texte ne fait pas FACE à l'image, il se
   range contre elle et se cale sur son bas : les deux forment un
   objet, pas deux colonnes voisines. C'est la différence entre
   une composition et un gabarit.

   La photographie sort par la droite. Sa colonne est plafonnée en
   hauteur de fenêtre — elle doit avoir du poids, pas occuper un
   écran entier. */

.certif-piece{

    padding-bottom:clamp(44px,6vh,78px);

}

.certif-piece-bloc{

    margin-right:calc(50% - 50vw);

    display:grid;

    grid-template-columns:minmax(0,1fr) minmax(0,min(54vw,56vh));

    gap:clamp(24px,3.4vw,56px);

    align-items:end;

}

.certif-photo-piece{

    aspect-ratio:1281 / 1024;

}

/* Le texte est poussé contre l'image plutôt que collé au bord
   gauche : le vide se retrouve du côté de la marge de page, où il
   se lit comme un retrait voulu et non comme un trou. */

.certif-piece-mots{

    max-width:30rem;

    margin-left:auto;

    padding-bottom:clamp(4px,1vh,14px);

}

.certif-piece-mots p{

    margin:0 0 10px;

    color:var(--grey-light);

    font-size:clamp(15px,1.4vw,19px);

    line-height:1.65;

}

.certif-piece-mots p:last-child{

    margin-bottom:0;

    color:var(--ink);

}

/* ---------- 6. L'EXAMEN ---------- */

/* Les deux photographies forment un DIPTYQUE : même hauteur, même
   ligne de base, aucun texte entre elles, un simple intervalle de
   quelques pixels. Séparées, chacune ne dirait que la moitié —
   la loupe dit l'examen du détail, les mains gantées disent que
   c'est un humain qui le fait.

   Leur hauteur est donnée en dur et object-fit recadre. C'est
   volontaire : à format naturel, la loupe seule ferait 850 px et
   ce bloc redeviendrait un écran entier. Le recadrage est réglé
   sur ce qui compte — le verre de la loupe et l'étiquette C.P. */

.certif-examen{

    padding-top:clamp(44px,6vh,78px);

    padding-bottom:clamp(44px,6vh,78px);

}

.certif-examen-titre{

    margin:0 0 clamp(24px,3.2vh,44px);

    font-family:"Anton",sans-serif;

    font-size:clamp(30px,4.4vw,62px);

    line-height:1;

    letter-spacing:.01em;

    text-transform:uppercase;

    color:var(--ink);

}

.certif-diptyque{

    margin-left:calc(50% - 50vw);

    display:grid;

    grid-template-columns:minmax(0,1.08fr) minmax(0,1fr);

    gap:clamp(10px,1.4vw,22px);

}

.certif-diptyque .certif-photo{

    height:clamp(290px,44vh,450px);

}

.certif-photo-loupe img{

    object-position:50% 40%;

}

.certif-photo-etiquettes img{

    object-position:50% 46%;

}

/* Les cinq critères. Séparés par des filets plutôt que par des
   points : on doit pouvoir les compter d'un regard, pas les lire.
   Ils viennent directement sous le diptyque, sans respiration
   intermédiaire, parce qu'ils en sont la légende. */

.certif-points{

    display:flex;

    flex-wrap:wrap;

    list-style:none;

    margin:clamp(22px,3vh,36px) 0 0;

    padding:0;

    gap:8px 0;

}

.certif-points li{

    padding:0 clamp(12px,1.6vw,24px);

    border-left:1px solid var(--line);

    color:var(--ink);

    font-size:clamp(12.5px,1.15vw,15px);

    font-weight:500;

    letter-spacing:.04em;

}

.certif-points li:first-child{

    padding-left:0;

    border-left:none;

}

/* ---------- 7. LA CERTIFICATION ---------- */

/* La seule information commerciale de la page. Traitée comme une
   annonce et non comme une promotion : grande, nette, sans
   encadré, sans couleur d'accent, sans point d'exclamation
   ajouté.

   Le certificat est à droite, à la taille d'un document. Sa
   largeur est fixée plutôt que proportionnelle : quel que soit
   l'écran, un document doit garder la dimension d'un document.
   C'est la preuve qui referme la démonstration. */

.certif-certification{

    padding-top:clamp(44px,6vh,78px);

    padding-bottom:clamp(44px,6vh,78px);

    display:grid;

    grid-template-columns:minmax(0,1fr) clamp(180px,22vw,300px);

    gap:clamp(26px,4vw,68px);

    align-items:center;

}

.certif-liaison{

    margin:0;

    color:var(--grey-light);

    font-size:clamp(14px,1.3vw,17px);

    line-height:1.5;

}

.certif-gratuit-1{

    margin:clamp(12px,1.8vh,20px) 0 0;

    font-family:"Anton",sans-serif;

    font-size:clamp(28px,4vw,56px);

    line-height:1;

    letter-spacing:.01em;

    text-transform:uppercase;

    color:var(--ink);

}

.certif-gratuit-2{

    margin:12px 0 0;

    color:var(--grey-light);

    font-size:clamp(12.5px,1.2vw,17px);

    letter-spacing:.14em;

    text-transform:uppercase;

}

.certif-photo-certificat{

    aspect-ratio:1086 / 1448;

}

/* ---------- 8. LA PROTECTION ET LA SORTIE ---------- */

/* Quatre sections tenaient ici sur 1 500 px : la protection,
   l'assistance, l'engagement et la conclusion. Elles disaient la
   même chose sous quatre angles, elles sont donc réunies en un
   bloc. Aucune phrase n'a été retirée — seule leur hauteur a
   changé.

   La protection et l'assistance se lisent côte à côte : ce sont
   les deux recours, ils vont ensemble. L'engagement et la sortie
   ferment en pleine largeur, et le lien arrive immédiatement
   après la dernière promesse au lieu d'un écran plus bas. */

.certif-final{

    padding-top:clamp(44px,6vh,78px);

    padding-bottom:clamp(52px,7.5vh,96px);

}

.certif-protection-titre{

    margin:0;

    font-family:"Anton",sans-serif;

    font-size:clamp(24px,3.3vw,46px);

    line-height:1.05;

    letter-spacing:.01em;

    text-transform:uppercase;

    color:var(--ink);

}

.certif-recours{

    margin-top:clamp(24px,3.2vh,40px);

    display:grid;

    grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);

    gap:clamp(24px,3.6vw,60px);

    align-items:start;

}

.certif-protection-corps p{

    margin:0 0 11px;

    max-width:52ch;

    color:var(--grey-light);

    font-size:14.5px;

    line-height:1.65;

}

.certif-protection-corps .certif-protection-relais{

    color:var(--ink);

    font-weight:600;

}

.certif-protection-corps .certif-protection-conclusion{

    margin-top:15px;

    color:var(--ink);

    font-weight:500;

}

.certif-protection-corps .certif-mention{

    margin:14px 0 0;

    font-size:12px;

    line-height:1.5;

    opacity:.7;

}

.certif-humain h3{

    margin:0;

    font-family:"Anton",sans-serif;

    font-size:clamp(17px,1.85vw,25px);

    line-height:1.08;

    letter-spacing:.01em;

    text-transform:uppercase;

    color:var(--ink);

}

.certif-humain-1{

    margin:14px 0 0;

    color:var(--ink);

    font-size:14.5px;

    line-height:1.6;

}

.certif-humain-2{

    margin:7px 0 0;

    color:var(--grey-light);

    font-size:14px;

    line-height:1.6;

}

.certif-engagement{

    margin-top:clamp(32px,4.2vh,54px);

    padding-top:clamp(24px,3.2vh,38px);

    border-top:1px solid var(--line);

}

.certif-engagement h2{

    margin:0;

    max-width:22ch;

    font-family:"Anton",sans-serif;

    font-size:clamp(28px,4.2vw,58px);

    line-height:1;

    letter-spacing:.01em;

    text-transform:uppercase;

    color:var(--ink);

}

.certif-engagement p{

    margin:11px 0 0;

    color:var(--grey-light);

    font-size:14.5px;

    line-height:1.6;

}

.certif-engagement p:first-of-type{

    margin-top:clamp(16px,2.2vh,24px);

}

/* La sortie. La promesse et le lien sont sur la même ligne et
   alignés sur le même bas : c'est ce qui fait qu'on clique en
   finissant la phrase plutôt qu'après avoir défilé encore. */

.certif-sortie{

    margin-top:clamp(30px,4vh,50px);

    display:flex;

    flex-wrap:wrap;

    align-items:flex-end;

    justify-content:space-between;

    gap:clamp(16px,2.6vw,44px);

}

.certif-fin-phrase{

    margin:0;

    color:var(--ink);

    font-size:clamp(17px,1.9vw,26px);

    font-weight:500;

    line-height:1.32;

}

.certif-fin-lien{

    display:inline-flex;

    align-items:baseline;

    gap:14px;

    margin:0;

    padding:12px 0;

    color:var(--ink);

    text-decoration:none;

    font-size:14px;

    font-weight:600;

    letter-spacing:.2em;

    text-transform:uppercase;

    white-space:nowrap;

}

.certif-fin-lien span:first-child{

    position:relative;

    padding-bottom:8px;

}

.certif-fin-lien span:first-child::before,
.certif-fin-lien span:first-child::after{

    content:"";

    position:absolute;

    left:0;

    bottom:0;

    height:1px;

    width:100%;

}

.certif-fin-lien span:first-child::before{

    background:rgba(var(--ink-rgb),.3);

}

.certif-fin-lien span:first-child::after{

    background:var(--ink);

    transform:scaleX(0);

    transform-origin:left;

    transition:transform .45s cubic-bezier(.22,1,.36,1);

}

.certif-fin-lien:hover span:first-child::after,
.certif-fin-lien:focus-visible span:first-child::after{

    transform:scaleX(1);

}

.certif-fin-fleche{

    transition:transform .45s cubic-bezier(.22,1,.36,1);

}

.certif-fin-lien:hover .certif-fin-fleche,
.certif-fin-lien:focus-visible .certif-fin-fleche{

    transform:translateX(8px);

}

/* ---------- Apparitions ---------- */

/* Un seul effet, le même partout : le contenu monte de dix pixels
   en s'affichant. Il utilise le mécanisme commun du site (classe
   .reveal posée par js/script.js) — aucune librairie, aucun
   blocage du défilement, aucun mouvement permanent.

   Le bloc 8 en est volontairement exclu : il contient le texte
   de protection, celui qu'on relit dans l'urgence quand un achat
   pose problème. Il doit être là tout de suite. */

.certif-intro.reveal,
.certif-probleme.reveal,
.certif-methode.reveal,
.certif-transition.reveal,
.certif-piece.reveal,
.certif-examen.reveal,
.certif-certification.reveal{

    opacity:0;

    transform:translateY(10px);

    transition:opacity .5s cubic-bezier(.22,1,.36,1),
               transform .5s cubic-bezier(.22,1,.36,1);

}

.certif-intro.reveal.in-view,
.certif-probleme.reveal.in-view,
.certif-methode.reveal.in-view,
.certif-transition.reveal.in-view,
.certif-piece.reveal.in-view,
.certif-examen.reveal.in-view,
.certif-certification.reveal.in-view{

    opacity:1;

    transform:none;

}

@media (prefers-reduced-motion: reduce){

    .certif-intro.reveal,
    .certif-probleme.reveal,
    .certif-methode.reveal,
    .certif-transition.reveal,
    .certif-piece.reveal,
    .certif-examen.reveal,
    .certif-certification.reveal{
        opacity:1;
        transform:none;
        transition:none;
    }

    .certif-fin-lien span:first-child::after,
    .certif-fin-fleche{
        transition:none;
    }

}

/* ---------- Écrans intermédiaires ---------- */

/* Entre 760 et 1020 px, trois compositions en vis-à-vis cessent
   de tenir : les colonnes de texte descendent sous trente
   caractères et les photographies n'ont plus la place de montrer
   quoi que ce soit. Elles se dépilent — mais la rupture d'axe est
   conservée, c'est elle qui porte la page : les photographies
   passent alors d'un bord à l'autre de l'écran au lieu de sortir
   d'un seul côté.

   Les quatre étapes passent en 2 × 2 : quatre colonnes sur 900 px
   donneraient 200 px chacune, soit une description coupée à
   chaque mot. */

@media(max-width:1020px){

    .certif-probleme{

        grid-template-columns:minmax(0,1fr);

        gap:clamp(22px,3.4vh,34px);

    }

    .certif-etapes{

        grid-template-columns:repeat(2,minmax(0,1fr));

        row-gap:clamp(26px,4vw,40px);

    }

    /* En 2 × 2, la troisième case ouvre une nouvelle ligne : elle
       reprend donc le traitement de la première, sans filet. */
    .certif-etape:nth-child(odd){

        padding-left:0;

        border-left:none;

    }

    .certif-piece-bloc{

        margin-right:0;

        grid-template-columns:minmax(0,1fr);

        gap:clamp(20px,3.4vw,32px);

    }

    /* Le texte passe SOUS l'image et repart à gauche : poussé à
       droite sur une colonne unique, il se lirait comme un
       décrochage accidentel. */
    .certif-piece-mots{

        max-width:none;

        margin-left:0;

        padding-bottom:0;

    }

    .certif-photo-piece{

        margin-left:calc(50% - 50vw);

        margin-right:calc(50% - 50vw);

    }

    .certif-certification{

        grid-template-columns:minmax(0,1fr) clamp(170px,26vw,240px);

        gap:clamp(24px,4vw,44px);

    }

    .certif-recours{

        grid-template-columns:minmax(0,1fr);

        gap:clamp(26px,4vh,38px);

    }

}

/* ---------- Petits écrans ---------- */

/* La narration ne change pas : mêmes blocs, même ordre, même
   progression. Ce sont les proportions qui sont recalculées — un
   titre qui remplit l'écran avant d'être compris ne convainc
   personne, et une photographie de 240 px ne prouve rien.

   Deux décisions propres au téléphone :

   · LE DIPTYQUE RESTE UN DIPTYQUE. Empilées, les deux
     photographies redeviendraient deux blocs sans relation, ce
     que ce bloc existe précisément pour éviter. Elles gardent
     donc leur ligne, avec une hauteur réduite.

   · LES QUATRE ÉTAPES REPASSENT EN COLONNE, numéro et libellé sur
     la même ligne. En 2 × 2 sur 375 px, chaque description
     tomberait à 160 px de large. */

@media(max-width:760px){

    .certif-intro{

        padding-top:clamp(40px,9vw,58px);

        padding-bottom:clamp(34px,7vw,48px);

    }

    .certif-intro-question{

        font-size:clamp(36px,11vw,56px);

        max-width:none;

    }

    .certif-rupture{

        font-size:clamp(30px,8.5vw,44px);

    }

    .certif-examen-titre,
    .certif-engagement h2{

        font-size:clamp(28px,8vw,42px);

    }

    .certif-gratuit-1{

        font-size:clamp(26px,7.5vw,40px);

    }

    .certif-transition-titre{

        font-size:clamp(24px,6.6vw,36px);

    }

    .certif-protection-titre{

        font-size:clamp(22px,6vw,34px);

    }

    /* Les étapes en colonne : le numéro devient un repère de
       gouttière, plus un titre. Le filet passe de la gauche de la
       colonne à la gauche de la ligne — même vocabulaire, autre
       orientation. */
    .certif-etapes{

        grid-template-columns:minmax(0,1fr);

        row-gap:clamp(20px,5vw,28px);

    }

    .certif-etape{

        display:grid;

        grid-template-columns:38px minmax(0,1fr);

        column-gap:14px;

        padding:0 0 0 0;

        border-left:none;

    }

    .certif-etape-num{

        grid-row:1 / span 3;

        font-size:22px;

        color:var(--grey-light);

    }

    .certif-etape-quoi{

        margin:0;

    }

    .certif-etape-titre{

        font-size:16px;

    }

    .certif-etape-texte{

        margin-top:6px;

    }

    /* LE DIPTYQUE SE DÉPILE, MAIS RESTE UN SEUL OBJET.

       Mesuré le 07/09/2026 : gardées côte à côte sur 375 px, les
       deux photographies tombaient à 179 et 166 px de large. Le
       verre de la loupe n'y faisait plus 33 px et les étiquettes
       n'étaient plus lisibles du tout — on aurait conservé la
       forme du diptyque en perdant ce qu'il sert à montrer.

       Elles passent donc l'une sous l'autre, mais rien ne les
       sépare : six pixels d'intervalle, aucun texte entre elles,
       et la seconde entre en retrait sous la première au lieu de
       reprendre sa largeur. On lit une image et sa suite, pas
       deux blocs. C'est la même alternance pleine largeur /
       retrait que le reste de la page en petit écran. */
    .certif-diptyque{

        margin-left:0;

        grid-template-columns:minmax(0,1fr);

        gap:6px;

    }

    .certif-diptyque .certif-photo-loupe{

        margin-left:calc(50% - 50vw);

        margin-right:calc(50% - 50vw);

        height:clamp(270px,74vw,330px);

    }

    /* Hauteur remise en « auto » avec la même spécificité que la
       règle du diptyque, sans quoi celle-ci l'emporterait et
       écraserait le rapport de l'image. */
    .certif-diptyque .certif-photo-etiquettes{

        height:auto;

        aspect-ratio:1535 / 1024;

        margin-left:16%;

    }

    /* Les cinq critères passent en colonne : côte à côte sur un
       écran étroit, ils se couperaient au milieu d'un mot. */
    .certif-points{

        flex-direction:column;

        gap:7px;

    }

    .certif-points li{

        padding:0 0 0 15px;

        border-left:1px solid var(--line);

    }

    .certif-points li:first-child{

        padding-left:15px;

        border-left:1px solid var(--line);

    }

    /* Le certificat passe sous les deux lignes, rangé à droite :
       il garde l'asymétrie de la version large sans écraser le
       titre qui l'annonce. */
    .certif-certification{

        grid-template-columns:minmax(0,1fr);

        gap:clamp(22px,6vw,32px);

    }

    .certif-photo-certificat{

        width:74%;

        margin-left:auto;

    }

    .certif-sortie{

        display:block;

    }

    .certif-fin-lien{

        margin-top:clamp(20px,5vw,28px);

    }

}


/* ===========================
   AUTHENTICITÉ (accueil)

   Section distincte de PROMO AUTHENTICITÉ juste en dessous :
   ce composant-là sert encore à la promo Livraison, et les deux
   ne doivent pas être liées.

   REFONTE DU 07/09/2026
   ------------------------------------------------------------------
   La version précédente était une photographie à gauche et un pavé
   de texte à droite, chacun dans sa moitié. Mesuré dans la page :
   1440 × 576, dont 222 px de vide sous le texte. Deux objets posés
   côte à côte, aucune tension, et une image qui ne pesait rien.

   Il n'y a plus qu'UN SEUL OBJET : la photographie occupe toute la
   largeur, et le texte est DEDANS. On ne lit plus une légende à
   côté d'une image, on lit une marque qui parle depuis son atelier.

   POURQUOI LE TEXTE TIENT DANS LE TIERS DROIT
   ------------------------------------------------------------------
   Le choix n'est pas une habitude de mise en page, il vient d'une
   carte de luminance du fichier relevée case par case (grille
   8 × 6, moyenne et écart-type par case) :

     · le dossier d'expertise, à gauche, est la zone la plus CLAIRE
       et la plus écrite du cliché — 135 à 153 de moyenne. Aucun
       texte ne peut y passer, et il ne le faut pas : c'est lui la
       preuve, il doit rester lisible.
     · le tiers droit sous 35 % de hauteur est la zone la plus
       SOMBRE et la plus CALME : moyennes de 4 à 29 sur 255, avec
       des écarts-types de 3 à 32. Du texte en #F4F3EF y ressort à
       plus de 15:1 de contraste.
     · le badge Stone Island, seul accent vif de cette moitié, est
       au-dessus de la zone de texte — d'où le calage EN BAS du
       bloc plutôt qu'au centre.

   Aucun voile, aucun dégradé n'a donc été ajouté sous le texte :
   la photographie est déjà assez sombre à cet endroit. C'était la
   condition pour ne pas trahir la règle « pas d'aplat décoratif ».

   LE CADRAGE
   ------------------------------------------------------------------
   Le fichier fait 1536 × 1024 (rapport 1,5). Affiché entier il
   ferait 960 px de haut sur un 1440 : impossible. Le cadre est donc
   à 2,75 et montre la bande 31 % → 85,5 % du fichier, qui contient
   tout ce qui compte dans le dossier :

     en-tête DOSSIER D'EXPERTISE   34 %
     tampon CONFIDENTIEL           38 %
     POINTS DE CONTRÔLE            48 - 65 %
     OBSERVATIONS manuscrites      70 - 83 %
     STATUT : Authentique          84 - 85 %

   Seul le mot ARKWER imprimé en tête de la fiche (29 %) sort du
   cadre — la marque est déjà partout ailleurs sur la page.
=========================== */

.authenticite-hook{

    position:relative;

    width:100%;

    /* 2,75 : voir le calcul de bande ci-dessus. Sur un 1440 la
       section fait 524 px contre 576 avant, et la photographie y
       est deux fois plus large. */
    aspect-ratio:2.75 / 1;

    overflow:hidden;

    display:flex;

    /* Le texte se cale en bas à droite. En bas parce que c'est là
       que l'image est la plus calme et que le badge Stone Island
       est au-dessus ; à droite parce que le dossier occupe la
       gauche. La diagonale dossier (bas gauche) → lien (bas
       droite) est le trajet du regard. */
    align-items:flex-end;

    justify-content:flex-end;

    margin:0 0 clamp(56px,7vw,110px);

}

/* LA PHOTOGRAPHIE
   ------------------------------------------------------------------
   Elle n'est plus un élément de la composition, elle EST la
   composition : posée en fond, elle occupe la section entière et
   le texte se pose par-dessus. */

.authenticite-hook-image{

    position:absolute;

    inset:0;

    margin:0;

}

.authenticite-hook-image img{

    width:100%;

    height:100%;

    display:block;

    object-fit:cover;

    /* 68 % du débordement caché en haut : avec un cadre à 2,75 pour
       une image à 1,5, il déborde de 45,5 % de la hauteur, et
       0,31 / 0,455 = 68 %. La bande montrée commence donc à 31 %
       du fichier et finit à 85,5 %. */
    object-position:center 68%;

}

/* LE TEXTE
   ------------------------------------------------------------------
   Sa largeur est bornée en pourcentage ET en pixels : le
   pourcentage le maintient dans la zone sombre relevée (à partir
   de 64 % de la largeur), les pixels l'empêchent de s'étaler sur
   un très grand écran où une ligne de 700 px cesserait d'être
   lisible d'un seul regard. */

.authenticite-hook-texte{

    position:relative;

    width:min(34%,460px);

    margin:0 clamp(24px,4vw,72px) clamp(34px,4.5vw,64px) 0;

}

/* COULEURS FIXES, PAS LES VARIABLES DU THÈME.
   Le texte est posé sur une photographie sombre : il doit rester
   clair que la page soit en thème sombre ou clair. Utiliser
   var(--ink) le ferait passer au noir sur fond noir en thème
   clair. C'est la seule exception de ce type sur le site, et elle
   ne vaut que tant que le texte est DANS l'image — en dessous de
   1000 px il repasse aux variables. */

.authenticite-hook-titre{

    margin:0;

    font-family:"Anton",sans-serif;

    /* Plus petit qu'avant (58 px) : la question ne dispose plus
       d'une demi-page mais d'une colonne de 460 px, et elle doit y
       tenir en trois lignes maximum. Elle n'y perd rien — sur du
       noir photographique, un blanc franc pèse plus lourd qu'un
       corps deux fois plus gros sur un fond de page. */
    font-size:clamp(26px,2.6vw,40px);

    line-height:.98;

    letter-spacing:.01em;

    text-transform:uppercase;

    color:#F4F3EF;

}

/* LA RÉPONSE
   Deuxième dans la hiérarchie, et de loin : elle reste en DM Sans,
   à un tiers de la taille de la question. Ce qui la fait exister,
   c'est sa couleur pleine et le filet court qui la précède — la
   marque prend la parole. */

.authenticite-hook-reponse{

    position:relative;

    margin:clamp(18px,2vw,26px) 0 0;

    padding-left:40px;

    color:#F4F3EF;

    font-size:clamp(15px,1.15vw,19px);

    font-weight:500;

    line-height:1.5;

}

.authenticite-hook-reponse::before{

    content:"";

    position:absolute;

    left:0;

    /* Aligné sur la première ligne du texte, pas sur le bloc : le
       filet doit partir du même axe que la première majuscule. */
    top:.72em;

    width:26px;

    height:1px;

    background:#F4F3EF;

}

/* L'EXPLICATION
   Volontairement discrète : elle informe, elle ne vend pas. Même
   retrait que la réponse pour que les deux forment une colonne. */

.authenticite-hook-detail{

    margin:14px 0 0;

    padding-left:40px;

    color:rgba(244,243,239,.72);

    font-size:14px;

    line-height:1.7;

}

/* LE LIEN
   Un mot souligné, pas un bouton. Le filet passe sous le mot seul,
   la flèche reste à côté et avance au survol. Aucun aplat, aucune
   ombre : la seule chose qui bouge est le trait, qui se remplit de
   la gauche vers la droite. */

.authenticite-hook-lien{

    display:inline-flex;

    align-items:baseline;

    gap:12px;

    margin-top:34px;

    /* Le lien s'aligne sur la réponse et l'explication, qui sont
       en retrait derrière leur filet. La valeur est reprise du
       padding-left de .authenticite-hook-reponse et doit rester
       d'accord avec lui — elle est remise à zéro en même temps que
       lui sur téléphone. */
    margin-left:40px;

    color:var(--ink);

    text-decoration:none;

    font-size:13px;

    font-weight:600;

    letter-spacing:.22em;

    text-transform:uppercase;

}

.authenticite-hook-lien span:first-child{

    position:relative;

    padding-bottom:7px;

}

/* Deux traits superposés : le gris permanent, et par-dessus le
   trait plein qui se déploie. Sans le trait permanent, le lien ne
   se signalerait pas comme cliquable avant le survol. */

.authenticite-hook-lien span:first-child::before,
.authenticite-hook-lien span:first-child::after{

    content:"";

    position:absolute;

    left:0;

    bottom:0;

    height:1px;

}

.authenticite-hook-lien span:first-child::before{

    width:100%;

    background:rgba(var(--ink-rgb),.28);

}

.authenticite-hook-lien span:first-child::after{

    width:100%;

    background:var(--ink);

    transform:scaleX(0);

    transform-origin:left;

    transition:transform .45s cubic-bezier(.22,1,.36,1);

}

.authenticite-hook-lien:hover span:first-child::after,
.authenticite-hook-lien:focus-visible span:first-child::after{

    transform:scaleX(1);

}

.authenticite-hook-fleche{

    transition:transform .45s cubic-bezier(.22,1,.36,1);

}

.authenticite-hook-lien:hover .authenticite-hook-fleche,
.authenticite-hook-lien:focus-visible .authenticite-hook-fleche{

    transform:translateX(7px);

}
/* LE LIEN SUR LA PHOTOGRAPHIE
   ------------------------------------------------------------------
   Les règles ci-dessus sont écrites avec les variables du thème.
   Posé sur l'image, le lien doit rester clair dans les deux
   thèmes, exactement comme le reste du bloc de texte : on refixe
   donc ses trois couleurs, et rien d'autre. Le mécanisme du
   soulignement qui se remplit et de la flèche qui avance est
   inchangé. */

.authenticite-hook-texte .authenticite-hook-lien{

    margin-top:clamp(20px,2.4vw,30px);

    color:#F4F3EF;

}

.authenticite-hook-texte .authenticite-hook-lien span:first-child::before{

    background:rgba(244,243,239,.35);

}

.authenticite-hook-texte .authenticite-hook-lien span:first-child::after{

    background:#F4F3EF;

}
/* ---------- Apparition ---------- */

/* La section entre déjà dans le mécanisme commun (classe .reveal
   posée par js/script.js). On ne fait qu'échelonner ses quatre
   éléments : la photographie d'abord, puis la question, puis le
   reste. L'ordre du regard, dans l'ordre du temps.

   Rien d'autre ne bouge : pas de parallaxe, pas de mouvement
   permanent, pas de blocage du défilement. Les décalages sont
   inférieurs à un quart de seconde au total. */

.authenticite-hook.reveal .authenticite-hook-image,
.authenticite-hook.reveal .authenticite-hook-titre,
.authenticite-hook.reveal .authenticite-hook-reponse,
.authenticite-hook.reveal .authenticite-hook-detail,
.authenticite-hook.reveal .authenticite-hook-lien{

    opacity:0;

    transform:translateY(10px);

    transition:opacity .5s cubic-bezier(.22,1,.36,1),
               transform .5s cubic-bezier(.22,1,.36,1);

}

.authenticite-hook.reveal.in-view .authenticite-hook-image,
.authenticite-hook.reveal.in-view .authenticite-hook-titre,
.authenticite-hook.reveal.in-view .authenticite-hook-reponse,
.authenticite-hook.reveal.in-view .authenticite-hook-detail,
.authenticite-hook.reveal.in-view .authenticite-hook-lien{

    opacity:1;

    transform:none;

}

.authenticite-hook.reveal.in-view .authenticite-hook-titre{
    transition-delay:.06s;
}

.authenticite-hook.reveal.in-view .authenticite-hook-reponse{
    transition-delay:.14s;
}

.authenticite-hook.reveal.in-view .authenticite-hook-detail{
    transition-delay:.19s;
}

.authenticite-hook.reveal.in-view .authenticite-hook-lien{
    transition-delay:.24s;
}

/* Visiteur ayant demandé moins d'animation : tout est posé
   directement, sans décalage ni transition. */

@media (prefers-reduced-motion: reduce){

    .authenticite-hook.reveal .authenticite-hook-image,
    .authenticite-hook.reveal .authenticite-hook-titre,
    .authenticite-hook.reveal .authenticite-hook-reponse,
    .authenticite-hook.reveal .authenticite-hook-detail,
    .authenticite-hook.reveal .authenticite-hook-lien{
        opacity:1;
        transform:none;
        transition:none;
        transition-delay:0s;
    }

    .authenticite-hook-lien span:first-child::after,
    .authenticite-hook-fleche{
        transition:none;
    }

}

/* La photographie ne monte plus de dix pixels avec le reste.
   Elle est maintenant en position:absolute et remplit la section :
   la décaler ouvrirait une bande vide de dix pixels en haut du
   cadre pendant la demi-seconde de l'apparition. Elle garde le
   fondu, elle perd le déplacement. */

.authenticite-hook.reveal .authenticite-hook-image{

    transform:none;

}

/* ---------- Écrans intermédiaires et téléphone ---------- */

/* LA COMPOSITION EST RECONSTRUITE, PAS RÉDUITE.

   En dessous de 1000 px, le tiers droit de l'image ne fait plus
   300 px : la question n'y tiendrait qu'en colonne d'un mot, et
   le dossier — qui est la preuve — deviendrait illisible.

   Le texte SORT donc de l'image et passe dessous, sur le fond de
   la page. Il retrouve du même coup les variables de thème : il
   n'est plus sur du noir photographique, il est sur la page.

   La photographie, elle, ne rétrécit pas : elle passe d'un cadre
   panoramique à un cadre presque carré (1,15) et le recadrage
   devient HORIZONTAL. Comme le rapport du cadre descend sous
   celui du fichier (1,5), toute la hauteur est montrée — le
   dossier apparaît donc en entier, du tampon CONFIDENTIEL au
   statut « Authentique », ce que le cadre panoramique ne fait
   même pas. Ancré à 6 %, le cadre garde la fiche complète et une
   part de la veste ; ce sont les outils du bord droit qui
   sortent. */

@media(max-width:1000px){

    .authenticite-hook{

        aspect-ratio:auto;

        display:block;

        overflow:visible;

        margin-bottom:clamp(44px,8vw,80px);

    }

    .authenticite-hook-image{

        position:relative;

        inset:auto;

        display:block;

        /* 2,0 et non le rapport du fichier : mesuré à 900 px de
           large, un cadre presque carré donnait 783 px de haut et
           une section de 1054 px — la section « excessivement
           haute » qu'il fallait éviter. À 2,0 elle fait 450 px.

           Le rognage reste vertical (2,0 > 1,5) et la bande montrée
           couvre 15 % → 90 % du fichier : l'en-tête du dossier, le
           tampon CONFIDENTIEL, les points de contrôle, les
           observations et le statut « Authentique » y sont tous. */
        aspect-ratio:2 / 1;

        overflow:hidden;

    }

    .authenticite-hook-image img{

        object-position:center 60%;

    }

    .authenticite-hook-texte{

        width:auto;

        max-width:640px;

        margin:clamp(24px,5vw,38px) clamp(24px,5vw,40px) 0;

    }

    /* Retour aux couleurs du thème : le texte est sur la page. */
    .authenticite-hook-titre,
    .authenticite-hook-reponse{

        color:var(--ink);

    }

    .authenticite-hook-reponse::before{

        background:var(--ink);

    }

    .authenticite-hook-detail{

        color:var(--grey-light);

    }

    .authenticite-hook-texte .authenticite-hook-lien{

        color:var(--ink);

    }

    .authenticite-hook-texte .authenticite-hook-lien span:first-child::before{

        background:rgba(var(--ink-rgb),.3);

    }

    .authenticite-hook-texte .authenticite-hook-lien span:first-child::after{

        background:var(--ink);

    }

    .authenticite-hook-titre{

        font-size:clamp(28px,5vw,44px);

    }

}

/* ---------- Tablette étroite ---------- */

/* En dessous de 760 px, un cadre à 2,0 ne fait plus que 380 px de
   haut et la fiche d'expertise, qui n'occupe que 40 % de la
   largeur du fichier, y tombe sous 150 px : on ne lit plus ni le
   tampon ni les cases cochées, et l'image cesse de prouver quoi
   que ce soit.

   Le cadre repasse donc au rapport du fichier. Le rognage devient
   HORIZONTAL — toute la hauteur est montrée, ce sont les outils du
   bord droit qui sortent — et la fiche retrouve sa taille. */

@media(max-width:760px){

    .authenticite-hook-image{

        aspect-ratio:1.45 / 1;

    }

    .authenticite-hook-image img{

        object-position:10% center;

    }

}

/* ---------- Téléphone ---------- */

/* Deux réglages seulement.

   Le cadre se resserre encore — à 375 px, 1,1 donne 341 px de haut
   et la fiche occupe la moitié de la largeur : le tampon et les
   cases cochées redeviennent identifiables.

   Et le retrait de 40 px sous le filet, qui coûtait un sixième de
   la largeur utile, disparaît : le filet passe AU-DESSUS de la
   réponse au lieu d'être à sa gauche. Même rôle — annoncer que la
   marque prend la parole — sans manger la colonne. */

@media(max-width:620px){

    .authenticite-hook-image{

        aspect-ratio:1.1 / 1;

    }

    .authenticite-hook-image img{

        object-position:6% center;

    }

    .authenticite-hook-reponse,
    .authenticite-hook-detail{

        padding-left:0;

    }

    .authenticite-hook-texte .authenticite-hook-lien{

        margin-left:0;

    }

    .authenticite-hook-reponse{

        padding-top:20px;

    }

    .authenticite-hook-reponse::before{

        top:0;

        width:26px;

    }

}


/* =======================================================
   REVEAL AU SCROLL

   L'apparition doit se remarquer le moins possible : ce qui
   compte est que le contenu soit là, pas qu'il fasse une
   entrée. Le déclenchement se fait 200 px avant l'entrée dans
   la fenêtre (voir initRevealOnScroll), et ce qui est déjà à
   l'écran au chargement n'est pas animé du tout.

   D'où des durées courtes et un déplacement minime : à .28s et
   6 px, l'oeil enregistre la présence du bloc, pas le mouvement.
======================================================= */

.reveal{

    opacity:0;

    transform:translateY(6px);

    transition:opacity .28s cubic-bezier(.4,0,.2,1), transform .28s cubic-bezier(.4,0,.2,1);

}

.reveal.in-view{

    opacity:1;

    transform:translateY(0);

}

/* Visiteur ayant demandé moins d'animation dans son système :
   le contenu est posé directement, sans transition. */

@media (prefers-reduced-motion: reduce){

    .reveal{
        opacity:1;
        transform:none;
        transition:none;
    }

    /* Entrées de page (fiche produit, panier, commande) et
       animations en boucle : grain filmique, bandeau de marques,
       carrousel d'avis, halo des icônes de catégorie. */
    .product-page,
    .cart-page,
    .checkout-page,
    .grain-overlay,
    .brand-marquee-track,
    .testimonials-list,
    .category-tile:hover .category-tile-icon{
        animation:none;
    }

}

/* =======================================================
   GRAIN FILMIQUE
======================================================= */

.grain-overlay{

    position:fixed;

    inset:-60px;

    z-index:9999;

    pointer-events:none;

    opacity:.035;

    mix-blend-mode:overlay;

    background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><filter id="n"><feTurbulence type="fractalNoise" baseFrequency="0.85" numOctaves="2" stitchTiles="stitch"/></filter><rect width="100%25" height="100%25" filter="url(%23n)"/></svg>');

    background-size:180px 180px;

    animation:grainShift 1s steps(6) infinite;

}

@keyframes grainShift{

    0%{ transform:translate(0,0); }

    16%{ transform:translate(-3%,2%); }

    33%{ transform:translate(2%,-4%); }

    50%{ transform:translate(-4%,3%); }

    66%{ transform:translate(3%,-2%); }

    83%{ transform:translate(-2%,4%); }

    100%{ transform:translate(0,0); }

}

/* =======================================================
   SPOTLIGHT CURSEUR
======================================================= */

.cursor-spotlight{

    position:fixed;

    inset:0;

    z-index:2;

    pointer-events:none;

    opacity:0;

    background:radial-gradient(circle 280px at var(--x,50%) var(--y,50%),rgba(244, 243, 239, .05),transparent 70%);

    transition:opacity .4s ease;

}

.cursor-spotlight.active{

    opacity:1;

}

@media(hover:none){

    .cursor-spotlight{

        display:none;

    }

}

/* =======================================================
   BANDEAU DÉFILANT (accueil)
======================================================= */

.brand-marquee{

    width:100%;

    overflow:hidden;

    margin-bottom:90px;

    -webkit-mask-image:linear-gradient(to right,transparent,black 8%,black 92%,transparent);

    mask-image:linear-gradient(to right,transparent,black 8%,black 92%,transparent);

}

.brand-marquee-track{

    display:flex;

    align-items:center;

    gap:36px;

    width:max-content;

    animation:marqueeScroll 45s linear infinite;

}

.brand-marquee:hover .brand-marquee-track{

    animation-play-state:paused;

}

.brand-marquee-track img{

    height:64px;

    width:64px;

    object-fit:contain;

    filter:grayscale(1) brightness(1.3);

    opacity:.4;

    transition:opacity .4s ease, filter .4s ease;

}

.brand-marquee-track img:hover{

    opacity:1;

    filter:grayscale(0) brightness(1);

}

@keyframes marqueeScroll{

    from{ transform:translateX(0); }

    to{ transform:translateX(-50%); }

}

/* =======================================================
   AVIS CLIENTS (accueil)
======================================================= */

.testimonials-section{

    max-width:1300px;

    margin:0 auto 36px;

    padding:0 40px;

}

.testimonial-intro{

    max-width:560px;

    margin:0 auto 16px;

    text-align:center;

}

.testimonial-intro--page-top{

    margin-top:70px;

}

.testimonial-title{

    font-size:24px;

    font-weight:700;

    letter-spacing:1.5px;

    text-transform:uppercase;

    margin:6px 0 14px;

}

.testimonial-stats{

    display:flex;

    flex-direction:column;

    align-items:center;

    gap:6px;

}

.testimonial-average{

    font-size:38px;

    font-weight:700;

    letter-spacing:1px;

    line-height:1;

    background:linear-gradient(180deg,var(--ink),var(--grey));

    -webkit-background-clip:text;

    background-clip:text;

    color:transparent;

}

.testimonial-rating-visual{

    position:relative;

    display:inline-block;

    font-size:22px;

    letter-spacing:4px;

    line-height:1;

}

.testimonial-rating-stars-bg{

    color:var(--line);

}

.testimonial-rating-stars-fg{

    position:absolute;

    top:0;

    left:0;

    overflow:hidden;

    white-space:nowrap;

    width:0%;

    color:var(--gold);

    transition:width 1s cubic-bezier(.4,0,.2,1);

}

.testimonial-verified-badge{

    display:inline-flex;

    align-items:center;

    gap:8px;

    padding:6px 14px;

    margin-bottom:10px;

    border:1px solid rgba(var(--gold-rgb),.35);

    border-radius:30px;

    font-size:12px;

    letter-spacing:.3px;

    color:var(--grey-light);

}

.testimonial-verified-badge svg{

    width:15px;

    height:15px;

    color:var(--gold);

    flex-shrink:0;

}

.testimonials-carousel-group{

    display:flex;

    flex-direction:column;

    gap:10px;

}

.testimonials-carousel{

    width:100%;

    overflow:hidden;

    margin-bottom:0;

    -webkit-mask-image:linear-gradient(to right,transparent,black 6%,black 94%,transparent);

    mask-image:linear-gradient(to right,transparent,black 6%,black 94%,transparent);

}

.testimonials-carousel.reverse .testimonials-list{

    animation-direction:reverse;

}

.testimonials-list{

    display:flex;

    align-items:stretch;

    gap:16px;

    width:max-content;

    animation:testimonialScroll 70s linear infinite;

}

.testimonials-carousel:hover .testimonials-list{

    animation-play-state:paused;

}

@keyframes testimonialScroll{

    from{ transform:translateX(0); }

    to{ transform:translateX(-50%); }

}

.testimonial-empty{

    grid-column:1 / -1;

    text-align:center;

    color:var(--grey);

    font-size:14px;

    padding:40px 0;

}

.testimonial-card{

    position:relative;

    flex-shrink:0;

    width:290px;

    /* Cartes affinées : elles montaient à 214 px de haut pour porter
       une phrase de deux lignes et une vignette. Tout est resserré —
       rembourrage, étoiles, vignette, filet du pied — sans rien
       retirer. */
    padding:12px 16px 10px;

    background:linear-gradient(165deg,var(--card) 0%,var(--dark) 100%);

    border:1px solid var(--line);

    border-radius:var(--radius);

    overflow:hidden;

    transition:transform .5s cubic-bezier(.4,0,.2,1), border-color .5s cubic-bezier(.4,0,.2,1), box-shadow .5s cubic-bezier(.4,0,.2,1);

}

.testimonial-card::before{

    content:"“";

    position:absolute;

    top:-10px;

    left:16px;

    font-size:68px;

    font-weight:700;

    color:rgba(var(--ink-rgb,255,255,255),.05);

    line-height:1;

    pointer-events:none;

}

.testimonial-card::after{

    content:"";

    position:absolute;

    inset:0;

    background:radial-gradient(circle at 50% 0%,rgba(var(--gold-rgb),.12),transparent 60%);

    opacity:0;

    transition:opacity .5s ease;

    pointer-events:none;

}

.testimonial-card:hover{

    transform:translateY(-8px);

    border-color:rgba(var(--gold-rgb),.35);

    box-shadow:0 25px 50px rgba(10, 10, 10, .5);

}

.testimonial-card:hover::after{

    opacity:1;

}

.testimonial-stars{

    position:relative;

    color:var(--gold);

    font-size:14px;

    letter-spacing:3px;

    margin-bottom:5px;

}

.testimonial-text{

    position:relative;

    font-size:13.5px;

    line-height:1.55;

    color:var(--grey-light);

    margin-bottom:9px;

    font-style:italic;

    display:-webkit-box;

    -webkit-line-clamp:2;

    -webkit-box-orient:vertical;

    overflow:hidden;

}

.testimonial-footer{

    position:relative;

    display:flex;

    align-items:center;

    gap:10px;

    padding-top:8px;

    border-top:1px solid var(--line);

}

.testimonial-product-thumb{

    width:38px;

    height:38px;

    border-radius:8px;

    object-fit:contain;

    background:var(--dark);

    border:1px solid var(--line);

    padding:6px;

    flex-shrink:0;

}

.testimonial-author{

    font-size:13px;

    font-weight:600;

    letter-spacing:.5px;

}

.testimonial-product-name{

    font-size:11.5px;

    color:var(--grey);

    margin-top:3px;

}

/* ---------------------------
   FORMULAIRE "LAISSER UN AVIS"
--------------------------- */

.review-form{

    position:relative;

    max-width:720px;

    margin:0 auto;

    padding:50px;

    background:linear-gradient(165deg,var(--card) 0%,var(--dark) 100%);

    border:1px solid var(--line);

    border-radius:var(--radius);

    overflow:hidden;

}

.review-form::before{

    content:"";

    position:absolute;

    inset:0;

    background:radial-gradient(circle at 50% 0%,rgba(244, 243, 239, .06),transparent 60%);

    pointer-events:none;

}

.review-form h3{

    position:relative;

    font-size:13px;

    font-weight:700;

    letter-spacing:3px;

    text-transform:uppercase;

    color:var(--grey);

    margin-bottom:8px;

    text-align:center;

}

.review-form-heading{

    position:relative;

    font-size:24px;

    font-weight:700;

    letter-spacing:.5px;

    text-align:center;

    margin-bottom:36px;

}

.review-form-grid{

    position:relative;

    display:grid;

    grid-template-columns:1fr 1fr;

    gap:22px;

}

.review-form-row{

    position:relative;

    margin-bottom:22px;

}

.review-form label{

    display:block;

    font-size:11px;

    letter-spacing:1.5px;

    text-transform:uppercase;

    color:var(--grey);

    margin-bottom:12px;
}

.review-star-input{

    display:flex;

    gap:10px;

    font-size:30px;

}

.review-star-input span{

    cursor:pointer;

    color:var(--line);

    transition:color .15s ease, transform .15s ease;
}

.review-star-input span:hover{

    transform:scale(1.15);

}

.review-star-input span.active{

    color:var(--gold);

}

.review-form input[type="text"],
.review-form select,
.review-form textarea{

    width:100%;

    padding:15px 18px;

    background:rgba(var(--ink-rgb),.05);

    border:1px solid var(--line);

    border-radius:10px;

    color:var(--ink);

    font-family:inherit;

    font-size:14px;

    resize:vertical;

    transition:border-color .3s ease;

}

.review-form textarea{

    min-height:120px;

}

.review-form input[type="text"]:focus,
.review-form select:focus,
.review-form textarea:focus{

    outline:none;

    border-color:rgba(var(--gold-rgb),.6);

}

/* interrupteurs premium (remplace les cases à cocher natives) */

.review-checkbox-row{

    position:relative;

    display:flex;

    align-items:center;

    gap:16px;

    margin-bottom:20px;

}

.review-toggle{

    position:relative;

    flex-shrink:0;

    width:44px;

    height:26px;

}

.review-toggle input{

    position:absolute;

    opacity:0;

    width:100%;

    height:100%;

    margin:0;

    cursor:pointer;

}

.review-toggle-track{

    position:absolute;

    inset:0;

    background:var(--line);

    border-radius:20px;

    transition:var(--transition);

    pointer-events:none;

}

.review-toggle-track::before{

    content:"";

    position:absolute;

    top:3px;

    left:3px;

    width:20px;

    height:20px;

    border-radius:50%;

    background:var(--grey-light);

    transition:var(--transition);

}

.review-toggle input:checked ~ .review-toggle-track{

    background:var(--gold);

}

.review-toggle input:checked ~ .review-toggle-track::before{

    transform:translateX(18px);

    background:var(--black);

}

.review-checkbox-row p{

    font-size:13px;

    color:var(--grey-light);

    line-height:1.6;
}

.review-submit-button{

    position:relative;

    width:100%;

    padding:18px;

    margin-top:10px;

    background:linear-gradient(120deg,#F4F3EF,#e8e0d0,#F4F3EF);

    background-size:200% auto;

    color:var(--accent-ink);

    border:none;

    border-radius:40px;

    font-size:13px;

    font-weight:700;

    letter-spacing:2px;

    text-transform:uppercase;

    cursor:pointer;

    transition:var(--transition), background-position .6s ease;
}

.review-submit-button:hover{

    transform:translateY(-3px);

    background-position:right center;

    box-shadow:0 20px 45px rgba(var(--gold-rgb),.2);

}

.review-form-note--intro{

    margin-top:0;

    margin-bottom:28px;

}

.review-form-note{

    position:relative;

    margin-top:20px;

    font-size:11.5px;

    color:var(--grey);

    text-align:center;

    line-height:1.6;

}

@media(max-width:900px){

    .testimonial-card{

        width:280px;

    }

    .review-form{

        padding:32px 24px;

    }

    .review-form-grid{

        grid-template-columns:1fr;

        gap:0;

    }

    .testimonial-title{

        font-size:20px;

    }

    .testimonial-average{

        font-size:30px;

    }

}

/* =======================================================
   CARRÉS CATÉGORIES (accueil)
======================================================= */

.category-tiles-section{

    width:100%;

    max-width:none;

    box-sizing:border-box;

    margin:0;

    /* Ces deux valeurs sont les seuls écarts verticaux du bloc :
       le hero n'a plus de marge basse et la section suivante n'a pas
       de marge haute. Tout se règle donc ici.

       En haut, 40 px et non 60 : la photographie se dissout déjà
       dans la page sur ses derniers pixels, donc le vide perçu est
       plus grand que la valeur écrite.

       En bas, 24 px et non 60 : c'est CET espace qui repoussait
       « À LA UNE » sous la ligne de flottaison. Le resserrer permet
       de garder aux cartes toute leur hauteur. */
    padding:32px clamp(10px,2vw,28px) 20px;

    background:transparent;

}

/* Quatre cartes, quatre colonnes, sur une seule ligne. auto-fit
   laissait le nombre de colonnes au navigateur : en dessous de
   1050 px il repliait déjà sur deux lignes, ce qui repoussait la
   suite de la page hors de l'écran. On l'impose.

   Mais on l'impose seulement là où c'est tenable : en dessous de
   900 px, quatre colonnes donneraient des cartes de 80 px de large
   sur téléphone. On repasse alors à deux. */

.category-tiles{

    display:grid;

    grid-template-columns:repeat(4,minmax(0,1fr));

    gap:16px;

}

@media(max-width:900px){

    .category-tiles{

        grid-template-columns:repeat(2,minmax(0,1fr));

    }

}

.category-tile{

    position:relative;

    overflow:hidden;

    display:flex;

    flex-direction:column;

    align-items:center;

    justify-content:center;

    /* Hauteur volontaire : ces cartes recevront des images. On ne
       les comprime pas — le premier écran se gagne sur les espaces
       entre les blocs, pas sur les blocs eux-mêmes. */
    gap:22px;

    padding:60px 24px;

    background:var(--card);

    border:1px solid var(--line);

    border-radius:var(--radius);

    color:var(--ink);

    text-decoration:none;

    text-align:center;

    transition:var(--transition);

}

.category-tile::after{

    content:"";

    position:absolute;

    inset:0;

    background:radial-gradient(circle at 50% 0%,rgba(var(--ink-rgb),.14),transparent 60%);

    opacity:0;

    transition:opacity .5s ease;

    pointer-events:none;

}

@keyframes categoryIconGlow{

    0%,100%{

        box-shadow:0 0 0 0 rgba(var(--ink-rgb),.22);

    }

    50%{

        box-shadow:0 0 20px 6px rgba(var(--ink-rgb),.32);

    }

}

.category-tile-icon{

    display:flex;

    align-items:center;

    justify-content:center;

    width:100%;

    height:76px;

    border-radius:20px;

    transition:var(--transition);

}

.category-tile-icon svg{

    width:28px;

    height:28px;

    color:var(--grey-light);

    transition:var(--transition);

}

.category-tile-label{

    position:relative;

    font-size:13px;

    font-weight:600;

    letter-spacing:2.5px;

    text-transform:uppercase;

}

/* La phrase qui accompagne le libellé. Elle est écrite en casse
   normale dans le HTML et mise en capitales par le CSS juste
   au-dessus pour le libellé seulement : du texte saisi en capitales
   se fait épeler lettre par lettre par certains lecteurs d'écran.

   La marge négative annule les 22 px d'espacement de la carte entre
   le libellé et sa phrase : les deux forment un bloc, et les 22 px
   ne séparent plus que l'icône de ce bloc. Sans cela, les trois
   éléments s'espaçaient également et le lien avec le libellé se
   perdait. */

.category-tile-note{

    position:relative;

    margin-top:-13px;

    /* Aucune largeur imposée : c'est la carte qui décide. Un plafond
       de 22ch coupait « La touche qui change tout. » en deux alors
       qu'elle tenait sur une ligne. Seule la phrase la plus longue
       passe désormais sur deux lignes. */
    color:var(--grey);

    font-size:12.5px;

    font-weight:400;

    letter-spacing:.2px;

    line-height:1.45;

    text-transform:none;

    transition:var(--transition);

}

.category-tile:hover .category-tile-note{

    color:var(--grey-light);

}

.category-tile:hover{

    transform:translateY(-8px);

    border-color:rgba(var(--ink-rgb),.3);

    box-shadow:0 24px 48px rgba(10, 10, 10, .45);

}

.category-tile:hover::after{

    opacity:1;

}

.category-tile:hover .category-tile-icon{

    transform:scale(1.06);

    animation:categoryIconGlow 1.8s ease-in-out infinite;

}

.category-tile:hover .category-tile-icon svg{

    color:var(--ink);

}

@media(max-width:640px){

    .category-tile{

        padding:44px 20px;

    }

    .category-tile-icon{

        height:56px;

    }

}

/* =======================================================
   FICHE PRODUIT (produit/<id>.html, produit.html)
   Écrite par ARKWER ADMIN/MAINTENANCE/generer-fiches.mjs,
   animée par js/product-page.js. Toutes les règles de la
   fiche sont préfixées .pdp ; celles qui suivent ce titre et
   ne le sont pas servent aussi ailleurs (fil d'Ariane du
   panier et de la commande, pied de page enrichi, logos de
   paiement, section de recommandations du panier).
======================================================= */

/* En mode sombre uniquement, la fiche produit se pose sur le gris de
   la palette plutôt que sur le noir : la pièce photographiée y
   respire mieux. Les surfaces qui la surplombent sont alors le blanc
   de la palette en transparence — seul moyen de passer au-dessus du
   gris sans inventer deux nouveaux aplats.

   Ces variables étaient auparavant posées sur .product-page sans
   condition, puis contre-redéclarées ici pour le mode clair. La
   contre-déclaration figeait la fiche produit sur l'ancienne palette :
   on cible directement le mode sombre, et le mode clair hérite
   simplement de la palette globale. */

/* LE PILOTE EST DEVENU LA RÈGLE — CES QUATRE BLOCS SONT RETIRÉS.
   ------------------------------------------------------------------
   Il y avait ici quatre déclarations qui donnaient à la fiche
   produit, et à elle seule, un fond #1C1C1C au lieu du #0A0A0A du
   reste du site : la fiche, le <body> qui la contient, sa navbar et
   son pied de page. Le commentaire qui les accompagnait disait leur
   statut sans détour — « Test […] À généraliser plus tard si validé,
   ou à retirer si on préfère garder la navbar noire ailleurs. »

   Elles sont validées, et généralisées : #1C1C1C est maintenant le
   fond de page du mode sombre dans :root. Les garder ici n'aurait
   plus rien changé au rendu, mais aurait laissé croire que la fiche
   a une palette à elle — et c'est précisément ce genre d'îlot qui
   avait fait diverger l'accueil du reste du site.

   Le voile des cartes descendait ici à 2,5 % parce qu'à 4 % la
   ligne de taille (--grey) tombait sous 4,5:1. Ce n'est plus la
   bonne réponse à ce problème : --grey a été relevé à #9D9B99, qui
   tient le seuil sur toutes les surfaces de la nouvelle hiérarchie.
   C'est la couleur du texte qui a été corrigée, pas la surface qui a
   été aplatie pour l'accommoder. */

/* ---------------------------
   BREADCRUMB
--------------------------- */

.breadcrumb {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 40px;
    color: var(--grey);
    font-size: 12px;
    letter-spacing: 0.4px;
}

.breadcrumb a {
    color: var(--grey);
    text-decoration: none;
    transition: color 0.2s ease;
}

.breadcrumb a:hover {
    color: var(--ink);
}

.breadcrumb-current {
    color: var(--ink);
    font-weight: 500;
}

.payment-method-badge {
    display: block;
    width: 26px;
    height: 18px;
    flex-shrink: 0;
    border-radius: 4px;
    overflow: hidden;
    box-shadow: 0 0 0 1px rgba(10, 10, 10, .06);
}

.payment-method-badge svg {
    display: block;
    width: 100%;
    height: 100%;
}

/* ---------------------------
   PRODUITS SIMILAIRES
--------------------------- */

.related-products {
    width: 100%;
    margin-top: 90px;
    margin-bottom: 70px;
    padding-top: 55px;
    border-top: 1px solid var(--line);
}

.related-products h2 {
    margin-bottom: 24px;
    color: var(--ink);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 1px;
    text-transform: uppercase;
}

/* ---------------------------
   FOOTER ENRICHI (test, inspiré Vestiaire Collective)
--------------------------- */

.footer-rich {
    width: 100%;
    margin-top: 24px;
    padding: 40px 50px 40px;
    border-top: 1px solid var(--line);
    background: var(--black);
    color: var(--ink);
}

.footer-rich-columns {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 32px;
    max-width: 1440px;
    margin: 0 auto 40px;
}

.footer-rich-column h4 {
    margin-bottom: 18px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--ink);
}

.footer-rich-column {
    display: flex;
    flex-direction: column;
}

.footer-rich-column a {
    margin-bottom: 12px;
    color: var(--grey-light);
    font-size: 13px;
    text-decoration: none;
    transition: color .2s ease;
}

.footer-rich-column a:hover {
    color: var(--ink);
}

.footer-rich-locale {
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: 1440px;
    margin: 0 auto 20px;
    padding-top: 24px;
    border-top: 1px solid var(--line);
    color: var(--ink);
    font-size: 13px;
    font-weight: 600;
}

.footer-rich-locale-flag {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    background-image: url("../images/madeinfrance.png");
    background-repeat: no-repeat;
    background-size: 375% auto;
    background-position: 44% 47%;
}

.footer-rich-dot {
    color: var(--grey);
    font-weight: 400;
}

.footer-rich-legal-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    max-width: 1440px;
    margin: 0 auto 40px;
}

.footer-rich-legal-links {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
}

.footer-rich-legal-links a {
    color: var(--grey);
    font-size: 12.5px;
    text-decoration: none;
}

.footer-rich-legal-links a:hover {
    color: var(--ink);
}

.footer-rich-socials {
    display: flex;
    align-items: center;
    gap: 14px;
}

.footer-rich-socials a {
    display: flex;
    color: var(--grey-light);
    transition: color .2s ease;
}

.footer-rich-socials a:hover {
    color: var(--ink);
}

.footer-rich-socials svg {
    width: 19px;
    height: 19px;
}

.footer-rich-disclaimer {
    max-width: 1440px;
    margin: 0 auto 32px;
    padding-top: 32px;
    border-top: 1px solid var(--line);
}

.footer-rich-disclaimer h4 {
    margin-bottom: 12px;
    font-size: 13px;
    font-weight: 700;
    color: var(--ink);
}

.footer-rich-disclaimer p {
    margin-bottom: 12px;
    color: var(--grey);
    font-size: 12.5px;
    line-height: 1.6;
    max-width: 900px;
}

.footer-rich-payments {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    max-width: 1440px;
    margin: 0 auto 24px;
}

.footer-rich-bottom {
    max-width: 1440px;
    margin: 0 auto;
    color: var(--grey);
    font-size: 12px;
}

/* ---------------------------
   STRUCTURE
   Grille de 12 colonnes, 1 280 px utiles : galerie sur 7, achat
   sur 5, colonne d'achat collée pendant la lecture des photos.
   L'ordre des sections est porté par `order` : une pièce vendue
   remonte ses recommandations juste sous la fiche, sans que le
   HTML ait à changer.
--------------------------- */

.pdp {
    --pdp-marge: 40px;
    --pdp-trait: rgba(var(--ink-rgb), .12);
    --pdp-scene: rgba(var(--ink-rgb), .045);
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: calc(1280px + 2 * var(--pdp-marge));
    margin: 0 auto;
    padding: 26px var(--pdp-marge) 80px;
    background: var(--black);
    color: var(--ink);
    font-family: "DM Sans", sans-serif;
}

.pdp [hidden],
.pdp-barre [hidden] {
    display: none !important;
}

.pdp h1,
.pdp h2 {
    font-family: "DM Sans", sans-serif;
}

.pdp > .pdp-ariane { order: 0; }
.pdp > .pdp-produit { order: 1; }
.pdp > .pdp-details { order: 3; }
.pdp > .pdp-authenticite,
.pdp > .pdp-savoir { order: 4; }
.pdp > .pdp-recos { order: 5; }

.pdp[data-etat="vendue"] > .pdp-recos,
.pdp[data-etat="retiree"] > .pdp-recos {
    order: 2;
}

.pdp .pdp-ariane {
    flex-wrap: wrap;
    row-gap: 4px;
    margin: 0 0 22px;
}

.pdp .pdp-ariane .breadcrumb-current {
    max-width: 42ch;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.pdp-produit {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: 40px;
    align-items: start;
}

/* ---------------------------
   GALERIE — UNE SCÈNE COMMUNE 4:5
   Aucune lueur, aucune ombre : un aplat discret. Les photos de
   studio remplissent la scène ; les pièces détourées s'y posent
   au centre avec de l'air ; un autre format est contenu, jamais
   rogné. Les photos ne sont jamais retouchées pour tenir.
--------------------------- */

.pdp-galerie {
    --pdp-rail: 84px;
    grid-column: 1 / span 7;
    display: grid;
    grid-template-columns: var(--pdp-rail) minmax(0, 1fr);
    gap: 14px;
    align-items: start;
}

/* Une seule photo : pas de rail. Sélecteur renforcé pour primer sur
   la grille à rail redéfinie sous 1 180 px. */
.pdp-galerie.pdp-galerie-seule {
    grid-template-columns: minmax(0, 1fr);
}


.pdp-vignettes {
    display: flex;
    flex-direction: column;
    gap: 8px;
    /* La colonne prend EXACTEMENT la hauteur de la photo (la ligne
       de la grille) et défile si les carrés sont plus nombreux. */
    align-self: stretch;
    height: 0;
    min-height: 100%;
    overflow-y: auto;
    scrollbar-width: none;
}

.pdp-vignettes::-webkit-scrollbar {
    display: none;
}

.pdp-vignette {
    flex: 0 0 auto;
    width: var(--pdp-rail);
    aspect-ratio: 1 / 1;
    padding: 0;
    overflow: hidden;
    border: 1px solid transparent;
    border-radius: var(--r-controle);
    background: var(--pdp-scene);
    opacity: .55;
    cursor: pointer;
    transition: opacity .2s ease, border-color .2s ease;
}

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

.pdp-vignette-detoure img,
.pdp-vignette-contenue img {
    object-fit: contain;
}

.pdp-vignette:hover,
.pdp-vignette:focus-visible {
    opacity: 1;
}

.pdp-vignette[aria-current="true"] {
    opacity: 1;
    border-color: var(--ink);
}

.pdp-scene-cadre {
    position: relative;
    justify-self: center;
    /* La photo entière tient sous l'en-tête et le fil d'Ariane (≈ 200 px)
       sans que la page ait à descendre pour la voir. */
    width: min(100%, calc((100vh - 200px) * .8));
}

.pdp-piste {
    display: flex;
    aspect-ratio: 4 / 5;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    border-radius: var(--r-controle);
    background: var(--pdp-scene);
}

.pdp-piste::-webkit-scrollbar {
    display: none;
}

.pdp-piste:focus-visible {
    outline: 1px solid var(--ink);
    outline-offset: 3px;
}

.pdp-scene {
    position: relative;
    flex: 0 0 100%;
    height: 100%;
    margin: 0;
    scroll-snap-align: start;
    scroll-snap-stop: always;
}

.pdp-scene img {
    display: block;
    width: 100%;
    height: 100%;
}

.pdp-scene-studio img {
    object-fit: cover;
}

/* Une pièce détourée est cadrée DANS le fichier (84 % de la toile,
   centrée — ARKWER ADMIN/MAINTENANCE/cadrer-pieces.js). Aucune marge
   n'est ajoutée ici : en ajouter une la ferait rétrécir deux fois. */
.pdp-scene-detoure img {
    object-fit: contain;
}

.pdp-scene-contenue img {
    object-fit: contain;
}

.pdp-fleche {
    position: absolute;
    top: 50%;
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px solid rgba(var(--ink-rgb), .16);
    border-radius: 50%;
    background: rgba(var(--black-rgb), .8);
    color: var(--ink);
    cursor: pointer;
    opacity: 0;
    transform: translateY(-50%);
    transition: opacity .2s ease;
}

.pdp-fleche svg {
    width: 18px;
    height: 18px;
}

.pdp-scene-cadre:hover .pdp-fleche,
.pdp-fleche:focus-visible {
    opacity: 1;
}

.pdp-fleche-prec { left: 12px; }
.pdp-fleche-suiv { right: 12px; }

.pdp-compteur {
    position: absolute;
    right: 10px;
    bottom: 10px;
    display: none;
    margin: 0;
    padding: 4px 9px;
    border-radius: var(--r-pilule);
    background: rgba(var(--black-rgb), .8);
    color: var(--ink);
    font-size: var(--t-etiquette);
    font-variant-numeric: tabular-nums;
}

/* ---------------------------
   COLONNE D'ACHAT
   Marque, nom, prix et disponibilité, taille et état, un seul
   bouton, puis quatre garanties réelles. Rien d'autre.
--------------------------- */

/* =========================================================
   LA GALERIE : UNE PHOTO À LA FOIS, LES AUTRES EN VIGNETTES CARRÉES

   Le défilement vers le bas (première photo en grand, les autres
   par deux) est abandonné. On voit UNE photo, entière, dans une
   scène 4:5 ; les autres sont des carrés qu'on touche ou qu'on
   clique, comme sur Vestiaire Collective.

     · grand écran : les carrés forment une colonne à GAUCHE de la
       photo (sa hauteur ne dépasse jamais celle de la photo) ;
     · téléphone : les carrés forment une bande SOUS la photo (voir
       plus bas, @media 899 px) ;
     · le doigt, les flèches et les touches ← → font aussi avancer.

   La photo ne dépasse jamais la fenêtre : sa largeur est bornée
   par la hauteur disponible (.pdp-scene-cadre). Plus aucune photo
   n'est rognée par une case « paysage ».
   ========================================================= */

.pdp-achat {
    grid-column: 8 / span 5;
    position: sticky;
    top: calc(var(--hauteur-header, 70px) + var(--zone-haut, 0px) + 26px);
    padding-top: 2px;
}

.pdp-marque {
    margin: 0 0 8px;
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--grey-light);
}

.pdp-nom {
    margin: 0;
    font-size: var(--t-nom);
    font-weight: 600;
    line-height: 1.18;
    letter-spacing: -.01em;
    color: var(--ink);
    overflow-wrap: anywhere;
}

.pdp-prix-ligne {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 6px 16px;
    margin-top: 16px;
}

.pdp-prix {
    margin: 0;
    font-size: var(--t-prix);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--ink);
}

/* INLINE-BLOCK, PAS INLINE-FLEX
   ------------------------------------------------------------
   La ligne est alignée sur les lignes de base (.pdp-prix-ligne,
   align-items: baseline). Or une boîte flex n'expose pas la ligne
   de base de son texte : elle la synthétise depuis son premier
   enfant — ici la pastille, une boîte sans texte. Mesuré sur la
   fiche : le badge remontait de 3 px, et de 4 px sans la pastille.
   C'est la boîte flex qui en était la cause, pas la pastille.

   En inline-block, la boîte expose la ligne de base de son texte :
   « Disponible » s'assoit exactement sur celle de « 60 € » (écart
   mesuré : 0 px). La pastille redevient un élément en ligne, calée
   par vertical-align au lieu d'align-items.

   TAILLE. 13 px sous un prix de 24 px en graisse 700 faisaient un
   rapport de 1,85 : les deux ne semblaient plus appartenir à la
   même ligne. 14 px en graisse 500 ramènent le rapport à 1,71 et
   donnent au badge de quoi tenir à côté du montant. */
.pdp-dispo {
    display: inline-block;
    margin: 0;
    font-size: var(--t-texte);
    font-weight: 500;
    color: var(--grey-light);
}

.pdp-dispo::before {
    content: "";
    display: inline-block;
    width: 7px;
    height: 7px;
    /* Remplace le gap : la boîte n'est plus flex. */
    margin-right: 9px;
    border-radius: 50%;
    /* Centrée sur le texte du badge, pas sur sa boîte de ligne. Le
       pixel de remontée la pose sur le centre des capitales plutôt
       que sur le milieu d'x-height, où elle paraissait basse. */
    vertical-align: middle;
    position: relative;
    top: -1px;
    background: var(--ink);
}

.pdp-dispo[data-etat="vendue"],
.pdp-dispo[data-etat="retiree"] {
    color: var(--grey);
}

.pdp-dispo[data-etat="vendue"]::before,
.pdp-dispo[data-etat="retiree"]::before {
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--grey);
}

.pdp-dispo[data-etat="chargement"]::before {
    display: none;
}

/* Disponible : le texte et la pastille passent au vert. Les autres
   états gardent les neutres — le vert ne sert qu'à dire « oui ». */
.pdp-dispo[data-etat="disponible"] {
    color: var(--vert-dispo);
}

.pdp-dispo[data-etat="disponible"]::before {
    background: var(--vert-dispo);
}

/* =========================================================
   TAILLE ET ÉTAT : DEUX FAITS, PAS UN TABLEAU

   CE QUE C'ÉTAIT. Une colonne d'étiquettes de 80 px, une colonne
   de valeurs, et un filet pleine largeur au-dessus et sous chaque
   rangée. C'est la présentation d'une fiche technique d'appareil
   ménager, et c'était — avec le rail de vignettes — ce qui datait
   le plus cette page. Trois traits horizontaux pour dire deux
   choses.

   CE QUE C'EST. L'étiquette passe au-dessus de sa valeur, en
   petites capitales : elle se lit comme un intitulé et libère
   toute la largeur pour ce qui compte. Un seul filet ouvre le
   groupe. La valeur gagne deux points de corps et la taille passe
   en capitales — c'est le fait que l'œil vient chercher en
   premier sur une pièce unique, puisqu'il n'y en a qu'une.

   Les deux faits tiennent côte à côte quand la colonne est assez
   large, l'un sous l'autre sinon. L'état porte une définition qui
   peut courir sur deux lignes : il prend donc la largeur entière
   dès qu'elle manque.
   ========================================================= */

/* UNE COLONNE, PAS DEUX.
   Côte à côte, la colonne ÉTAT faisait 319 px et le libellé le plus
   long l'occupait entièrement : son point d'aide n'avait d'autre
   choix que de passer à la ligne, sous le libellé, là où l'œil ne
   le rattache plus à rien. Empilés, les deux faits disposent des
   477 px de la colonne et chaque aide tient à côté de sa valeur —
   « Guide des tailles » comme le point des états. */
.pdp-faits {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
    margin: 24px 0 0;
    padding: 20px 0 0;
    border-top: 1px solid var(--pdp-trait);
}

/* La bascule a 1199 px n'a plus d'objet : la grille est en une
   colonne a toutes les largeurs. */

.pdp-fait {
    display: block;
    padding: 0;
    border: 0;
    min-width: 0;
}

.pdp-fait dt {
    margin-bottom: 5px;
    font-size: var(--t-micro);
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--grey);
}

.pdp-fait dd {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 14px;
    margin: 0;
    font-size: var(--t-confort);
    color: var(--ink);
}

/* LA TAILLE EN CAPITALES. Sur une pièce unique, il n'y a pas de
   sélecteur à parcourir : la taille est un fait, et c'est le
   premier que l'œil cherche. Elle doit se lire sans être lue. */
.pdp-fait-taille dd > span:first-child {
    font-size: var(--t-sous-titre);
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.pdp-fait-etat dd {
    display: block;
}

.pdp-fait-etat .condition-label {
    display: block;
    font-size: var(--t-confort);
    font-weight: 500;
    color: var(--ink);
}

.pdp-lien-discret {
    font-size: var(--t-etiquette);
    color: var(--grey);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.pdp-lien-discret:hover {
    color: var(--ink);
}

.pdp-actions {
    margin-top: 22px;
}

/* =========================================================
   ACHETER, OU GARDER

   Deux issues possibles à cet écran, et l'une d'elles manquait.
   Le bouton d'achat occupe l'espace, la mise de côté se tient à
   côté : assez présente pour être vue sans hésitation, assez
   discrète pour ne pas disputer la décision principale.

   Recommandation de Baymard pour une commande d'achat fixée au
   défilement : ne pas la laisser prendre toute la largeur, et lui
   garder de l'air autour. La rangée fait les deux.
   ========================================================= */

.pdp-achat-rangee {
    display: flex;
    align-items: stretch;
    gap: 10px;
}

.pdp-achat-rangee .pdp-cta {
    flex: 1;
    min-width: 0;
}

/* Deux commandes côte à côte demandent de la place : « Acheter
   maintenant » en capitales espacées ne tient pas dans une demi-
   largeur de téléphone. Sous 560 px elles s'empilent, l'achat
   direct au-dessus. */
@media (max-width: 560px) {

    .pdp-achat-rangee {
        flex-direction: column;
    }

}

.pdp-tailles {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 14px;
}

.pdp-taille {
    min-width: 48px;
    height: 44px;
    padding: 0 12px;
    border: 1px solid rgba(var(--ink-rgb), .25);
    border-radius: var(--r-controle);
    background: transparent;
    color: var(--ink);
    font: inherit;
    font-size: var(--t-lien);
    cursor: pointer;
}

.pdp-taille[aria-pressed="true"] {
    border-color: var(--ink);
    background: var(--ink);
    color: var(--accent-ink);
}

.pdp-taille:disabled {
    color: var(--disabled-ink);
    border-color: var(--disabled-line);
    text-decoration: line-through;
    cursor: default;
}

.pdp-cta {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 52px;
    padding: 0 22px;
    border: 1px solid var(--ink);
    border-radius: var(--r-controle);
    background: var(--ink);
    color: var(--accent-ink);
    font-family: "DM Sans", sans-serif;
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    transition: background .2s ease, border-color .2s ease, color .2s ease;
}

.pdp-cta:hover:not(:disabled) {
    background: var(--accent-hover);
    border-color: var(--accent-hover);
}

.pdp-cta:disabled {
    cursor: default;
}

.pdp-cta:disabled:not(.pdp-cta-ajoute) {
    background: transparent;
    border-color: var(--disabled-line);
    color: var(--disabled-ink);
}

.pdp-cta.pdp-cta-secondaire {
    background: transparent;
    border-color: rgba(var(--ink-rgb), .35);
    color: var(--ink);
}

.pdp-cta.pdp-cta-secondaire:hover {
    background: rgba(var(--ink-rgb), .06);
    border-color: var(--ink);
}

.pdp-alerte {
    margin: 10px 0 0;
    font-size: var(--t-lien);
    color: var(--ink);
}

.pdp-vendue {
    display: none;
    margin-top: 22px;
}

.pdp[data-etat="vendue"] .pdp-vendue,
.pdp[data-etat="retiree"] .pdp-vendue {
    display: block;
}

.pdp[data-etat="vendue"] .pdp-actions,
.pdp[data-etat="retiree"] .pdp-actions {
    display: none;
}

.pdp-vendue-titre {
    margin: 0;
    font-size: var(--t-lien);
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--ink);
}

.pdp-vendue-texte {
    margin: 6px 0 16px;
    font-size: var(--t-texte);
    color: var(--grey);
}


/* =========================================================
   LES BADGES DE CONFIANCE

   CE QU'ILS ÉTAIENT : quatre lignes de texte de 13 px, en gris
   clair, marquées d'une petite coche et soulignées d'un filet à
   20 % d'opacité. Autrement dit, la typographie d'un pied de
   page, posée sous le bouton d'achat — à l'endroit exact où un
   acheteur hésite, et où il faut au contraire être affirmatif.

   CE QU'ILS SONT : un picto tracé, un libellé en encre, une
   précision en gris. Trois niveaux au lieu d'un, et une surface
   qui les tient ensemble.

   POURQUOI UNE PRÉCISION SOUS CHAQUE LIBELLÉ. « Paiement
   sécurisé » est une formule que tous les sites écrivent et que
   plus personne ne lit. « Traité par Stripe, carte jamais
   stockée » dit quelque chose de vérifiable. C'est la deuxième
   ligne qui fait le travail de confiance ; la première ne fait
   que la nommer.

   DEUX COLONNES AU-DESSUS DE 1200 PX. La colonne d'achat est
   haute et étroite ; quatre badges empilés y laissaient le grand
   vide qui gênait sous le bouton. En deux colonnes, le bloc se
   referme et remplit la hauteur de la photographie.
   ========================================================= */

.pdp-confiance {
    margin: 26px 0 0;
    padding: 20px 0 0;
    border-top: 1px solid var(--pdp-trait);
}

/* LA GARANTIE EN VEDETTE : l'authentification, seule chose qui
   distingue ARKWER. Une carte, sa preuve sur une ligne, une
   flèche qui dit qu'on peut en savoir plus. */
.pdp-confiance-vedette {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 15px 16px;
    border: 1px solid var(--pdp-trait);
    border-radius: 12px;
    background: rgba(var(--ink-rgb), .025);
    color: var(--ink);
    text-decoration: none;
    transition: border-color .2s ease, background-color .2s ease;
}

.pdp-confiance-vedette:hover,
.pdp-confiance-vedette:focus-visible {
    border-color: var(--ink);
    background: rgba(var(--ink-rgb), .045);
}

/* Le sceau « vérifié » : seule couleur du bloc, le vert de la
   validation, lisible dans les deux thèmes. */
.pdp-confiance-sceau {
    flex: none;
    width: 34px;
    height: 34px;
}

.pdp-sceau-fond {
    fill: #1F8F50;
    transform-box: fill-box;
    transform-origin: center;
}

.pdp-confiance-texte {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    flex: 1;
}

.pdp-confiance-titre {
    font-size: var(--t-lien);
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: .01em;
}

.pdp-confiance-detail {
    font-size: var(--t-etiquette);
    line-height: 1.45;
    color: var(--grey);
}

.pdp-confiance-fleche {
    flex: none;
    width: 15px;
    height: 15px;
    opacity: .55;
    transition: transform .2s ease, opacity .2s ease;
}

.pdp-confiance-vedette:hover .pdp-confiance-fleche,
.pdp-confiance-vedette:focus-visible .pdp-confiance-fleche {
    transform: translateX(3px);
    opacity: 1;
}

/* LES TROIS INFORMATIONS : des faits, une ligne chacun. */
.pdp-confiance-liste {
    display: grid;
    gap: 9px;
    margin: 16px 0 0;
    padding: 0 2px;
    list-style: none;
}

.pdp-confiance-liste li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 11px;
    font-size: var(--t-etiquette);
    line-height: 1.4;
    color: var(--grey);
}

/* Picto neutre dans une pastille : il pèse moins que le sceau,
   mais reste net et aligné. */
.pdp-confiance-pastille {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 30px;
    height: 30px;
    border-radius: 9px;
    background: rgba(var(--ink-rgb), .06);
    color: var(--ink);
}

.pdp-confiance-picto {
    width: 16px;
    height: 16px;
}

.pdp-confiance-liste a {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid transparent;
    transition: border-color .2s ease;
}

.pdp-confiance-liste a:hover,
.pdp-confiance-liste a:focus-visible {
    border-color: var(--ink);
}

.pdp-confiance-liste strong {
    font-weight: 600;
    color: var(--ink);
}

.pdp-paiements {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-left: auto;
}

.pdp-paiements .payment-method-badge {
    width: 30px;
    height: 20px;
}

.pdp-paiements .payment-method-badge svg {
    width: 100%;
    height: 100%;
}

/* LES PICTOS SE DESSINENT, une fois, quand le bloc entre à l'écran
   (classe posée par js/product-page.js). Sans script, ou si
   l'utilisateur a demandé moins d'animations, ils sont là d'emblée. */
@media (prefers-reduced-motion: no-preference) {

    .pdp-confiance-attente .pdp-trace {
        stroke-dasharray: 1;
        stroke-dashoffset: 1;
    }

    .pdp-confiance-dessine .pdp-trace {
        stroke-dasharray: 1;
        stroke-dashoffset: 1;
        animation: pdp-trace .9s cubic-bezier(.4, 0, .2, 1) forwards;
    }

    .pdp-confiance-attente .pdp-sceau-fond {
        transform: scale(.4);
        opacity: 0;
    }

    .pdp-confiance-dessine .pdp-sceau-fond {
        animation: pdp-sceau .55s cubic-bezier(.34, 1.56, .64, 1) both;
    }

    .pdp-confiance-dessine .pdp-trace-coche {
        animation-delay: .4s;
        animation-duration: .45s;
    }

    .pdp-confiance-dessine .pdp-confiance-liste li:nth-child(2) .pdp-trace { animation-delay: .15s; }
    .pdp-confiance-dessine .pdp-confiance-liste li:nth-child(3) .pdp-trace { animation-delay: .3s; }

}

@keyframes pdp-trace {
    to { stroke-dashoffset: 0; }
}

@keyframes pdp-sceau {
    from { transform: scale(.4); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}

/* ---------------------------
   DÉTAILS ET AUTHENTICITÉ
   Mise en page éditoriale : des filets, pas de cartes. Sur
   téléphone, chaque bloc se replie (js/product-page.js).
--------------------------- */

/* DEUX PILES, PAS QUATRE CASES.
   ------------------------------------------------------------
   Les quatre blocs étaient posés dans une grille de douze colonnes,
   chacun à sa case. La hauteur d'une rangée y est celle de son plus
   haut élément : la carte vendeur imposait la sienne à la
   description, et la colonne gauche portait 223 px de vide avant
   « Détails de la pièce ». Mesuré sur cp58.

   Deux conteneurs, deux piles indépendantes : chaque bloc suit
   immédiatement le précédent de SA colonne. */
.pdp-details {
    display: grid;
    grid-template-columns: 5fr 6fr;
    column-gap: 40px;
    margin-top: 88px;
    border-top: 1px solid var(--pdp-trait);
}

/* Authenticite N EST PLUS une section de premier niveau. Elle etait
   groupee avec .pdp-details et heritait sa grille, sa marge de 88 px
   et son filet ; dans une pile, l ecart de la colonne suffit. La
   regle qui la repassait en block ne l atteint plus non plus : elle
   n est plus enfant direct de .pdp-details. */
.pdp-authenticite {
    display: block;
    margin-top: 0;
    border-top: 0;
}

.pdp-colonne {
    display: flex;
    flex-direction: column;
    gap: 34px;
    min-width: 0;
}

/* =========================================================
   DEUX COLONNES, QUATRE BLOCS

   AVANT : description et caractéristiques côte à côte, puis le
   bloc Authenticité seul en pleine largeur dessous. La page se
   lisait en zigzag, et la colonne de droite s'arrêtait net au
   milieu de la page.

   MAINTENANT :

     gauche (1→5)        droite (7→12)
     ───────────────     ──────────────────
     description         vendeur
     caractéristiques    authenticité

   À gauche ce qui décrit la pièce, à droite ce qui rassure sur
   l'achat. Chaque colonne se lit de haut en bas sans sauter
   d'un côté à l'autre.

   Les rangées sont posées explicitement. Sans cela, le placement
   automatique remplit dans l'ordre du balisage et met le vendeur
   sous la description à gauche.
   ========================================================= */

/* Les placements à la case ont disparu avec la grille de douze :
   ce sont les deux .pdp-colonne qui portent la répartition. */

/* La description peut être masquée (une pièce sans texte). La
   colonne gauche ne doit pas laisser un trou : les
   caractéristiques remontent. */
/* Une pièce sans description : le bloc est masqué et le suivant
   remonte de lui-même dans la pile, sans rattrapage. */


/* RESSERRÉ. Le texte de ces deux sections portait la taille du
   corps de page ; dans une colonne de 580 px il s'étalait. Un cran
   en dessous, et un interligne plus court : la même information
   occupe moins de hauteur sans devenir moins lisible. */
.pdp-description,
.pdp-authenticite-texte {
    font-size: var(--t-lien);
    line-height: 1.52;
}

/* VOIR PLUS — UN FILET, PAS UNE RÈGLE.
   ------------------------------------------------------------
   MESURE AVANT D'ÉCRIRE : sur les 66 pièces publiées, la plus
   longue description fait 141 caractères, la médiane 110. AUCUNE
   ne déborderait aujourd'hui. Ce repli ne sert donc à rien tout de
   suite — il sert au jour où une annonce arrivera du CMS avec un
   texte de vingt lignes.

   D'où le choix : pas de seuil en caractères, qui serait une
   supposition sur un texte qu'on n'a pas. Le bouton n'apparaît que
   si le texte DÉBORDE RÉELLEMENT de ses six lignes, constaté à
   l'écran par js/product-page.js. Tant que rien ne déborde, rien
   ne s'affiche. */
.pdp-description.est-repliee {
    display: -webkit-box;
    -webkit-line-clamp: 6;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.pdp-voir-plus {
    display: none;
    margin-top: 8px;
    padding: 0;
    background: none;
    border: 0;
    border-bottom: 1px solid rgba(var(--ink-rgb), .3);
    color: var(--grey);
    font-family: inherit;
    font-size: var(--t-etiquette);
    cursor: pointer;
    transition: color .2s ease, border-color .2s ease;
}

/* Posé par le JS, et seulement lui : la classe n'apparaît que si le
   débordement a été constaté. */
.pdp-voir-plus.utile {
    display: inline-block;
}

.pdp-voir-plus:hover {
    color: var(--ink);
    border-bottom-color: var(--ink);
}

.pdp-voir-plus:focus-visible {
    outline: 1px solid var(--ink);
    outline-offset: 3px;
}

.pdp-authenticite-texte {
    margin-bottom: 14px;
}

.pdp-promesses {
    margin-bottom: 16px;
}

/* Les deux blocs de la seconde rangée ouvrent leur propre filet :
   sans lui, la rangée du bas flotterait sous celle du haut. */
.pdp-bloc-caracteristiques {
    border-top: 1px solid var(--pdp-trait);
}


/* =========================================================
   LA CARTE VENDEUR

   ELLE N'EXISTAIT PAS. La fiche ne disait nulle part qui vend.
   Sur un marché de seconde main, c'est la première question d'un
   acheteur qui hésite, et la page y répondait par le silence.

   ELLE N'EST PLUS LA SEULE CARTE. La règle d'origine était
   éditoriale — des filets, pas de cartes — et cette carte en
   était l'unique exception assumée. Sur demande, le bloc
   Authenticité a reçu la même surface ; deux cartes à droite
   face à deux blocs nus à gauche auraient déséquilibré la
   page, donc les quatre blocs sont désormais des cartes.

   CE QUE ÇA COÛTE, ET C'EST ASSUMÉ : la carte vendeur ne se
   distingue plus par sa surface. Ce qui la distingue encore est
   son sceau, qu'aucun autre bloc ne porte. Si l'on revient un
   jour aux filets, c'est ce bloc-là qui doit garder la carte.

   CE QU'ELLE NE CONTIENT PAS : ni nombre de ventes, ni note, ni
   délai de réponse. Aucune de ces données n'existe derrière, et
   une carte vendeur qui affiche un chiffre inventé ne rassure
   pas, elle trompe. Les trois engagements listés sont ceux que
   le site tient déjà ailleurs.
   ========================================================= */

/* CHAQUE CARTE À SA HAUTEUR. Par défaut une case de grille
   s’étire à la hauteur de sa rangée : la carte description se
   retrouvait à 422 px pour 125 px de contenu, soit près de 300 px
   de surface vide. Tant qu’il n’y avait pas de fond, ce vide ne
   se voyait pas ; avec une carte, il se voit. Mesuré sur cp58. */
/* align-self n'a plus d'objet : dans une pile, chaque bloc prend sa
   hauteur et le suivant vient dessous. */

/* Sans surface, les blocs de gauche ont besoin d'un filet : c'est
   lui qui dit où commence la rubrique. Même trait que partout. */
.pdp-colonne-gauche > .pdp-bloc > .pdp-bloc-corps {
    padding: 2px 0 0;
}

/* LES QUATRE SURFACES. Au-dessus de 899 px les blocs sont
   toujours dépliés (js/product-page.js force aria-expanded) :
   une carte y est toujours pleine. En dessous ils redeviennent
   des accordéons, et une carte qui se replierait sur son seul
   titre ne serait plus une carte — la surface est donc retirée
   plus bas, avec le reste du traitement mobile. */
/* LA SURFACE EST À DROITE, PAS À GAUCHE.
   ------------------------------------------------------------
   À gauche, ce qui DÉCRIT la pièce : sa description, ses
   caractéristiques. À droite, ce qui RASSURE sur l'achat : qui
   vend, comment c'est authentifié. Seule la seconde colonne porte
   une surface — elle parle d'autre chose que de la pièce, et c'est
   ce qui la signale.

   Effet de bord recherché : la colonne gauche n'a plus de cadre qui
   s'arrête tôt.

   CE PARAGRAPHE A ÉTÉ CORRIGÉ. Il disait que le vide sous la
   description (156 px mesurés alors) se lisait « comme de la
   respiration, pas comme un trou ». Ce n'est plus l'arbitrage
   retenu : mesuré sur les 66 fiches, l'écart de bas de colonne
   allait de 39 à 160 px et se voyait. Le dernier bloc de gauche
   s'étire désormais et le tableau répartit la place — voir
   « ALIGNER LE BAS DES DEUX COLONNES » plus bas. Le vide a
   disparu ; la colonne gauche reste sans cadre. */
/* Selecteurs SANS .pdp-details > : depuis le passage en deux piles,
   ces blocs sont enfants d une .pdp-colonne, plus de la section. Le
   selecteur descendant ne les atteignait plus et la carte
   authenticite avait disparu. Releve a l ecran. */
.pdp-vendeur > .pdp-bloc-corps,
.pdp-authenticite > .pdp-bloc-corps {
    padding: 20px 22px 22px;
    background: var(--pdp-scene);
    border: 1px solid var(--pdp-trait);
    border-radius: var(--r-surface);
}

/* Le filet d'ouverture de bloc faisait le travail que fait
   maintenant la bordure de la carte : deux traits l'un sur
   l'autre. */
/* La carte authenticite porte sa bordure ; celle de gauche garde
   son filet, qui est desormais sa seule separation. */
.pdp-authenticite {
    border-top: 0;
}

.pdp-vendeur-identite {
    display: flex;
    align-items: center;
    gap: 14px;
}

/* LE SCEAU. Une seule lettre dans la police d'affichage de la
   marque : c'est le seul endroit de la fiche où ARKWER se montre
   comme un acteur et non comme une mention légale. */
.pdp-vendeur-sceau {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    background: var(--ink);
    color: var(--black);
    border-radius: 50%;
    font-family: "Anton", sans-serif;
    font-size: 21px;
    line-height: 1;
    letter-spacing: .02em;
    /* Anton porte haut : sans ce décalage, la lettre paraît
       posée trop bas dans le cercle. */
    padding-top: 2px;
}

.pdp-vendeur-nom {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.pdp-vendeur-nom strong {
    font-size: var(--t-confort);
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ink);
}

.pdp-vendeur-statut {
    font-size: var(--t-etiquette);
    color: var(--grey);
}

.pdp-vendeur-texte {
    margin: 18px 0 0;
    font-size: var(--t-texte);
    line-height: 1.6;
    color: var(--grey-light);
}

.pdp-vendeur .pdp-lien {
    margin-top: 20px;
}

/* Sous 1000 px la fiche passe en une colonne : la carte perd sa
   surface, qui n'a plus rien à distinguer, et redevient un bloc
   comme les autres. */
@media (max-width: 1000px) {

    .pdp-vendeur > .pdp-bloc-corps,
    .pdp-colonne > .pdp-bloc > .pdp-bloc-corps,
    .pdp-authenticite > .pdp-bloc-corps {
        padding: 0;
        background: none;
        border: 0;
        border-radius: 0;
    }

    /* La bordure de la carte servait aussi de séparation entre les
       deux rangées. En la retirant ici, il faut rendre aux blocs
       de la seconde rangée le filet qu’ils avaient avant : sans
       lui, entre 900 et 1000 px ils flottent sans rien qui les
       sépare — les blocs y sont encore dépliés, la bascule en
       accordéon n’arrivant qu’à 899 px. Mesuré à 950 px. */
    .pdp-bloc-caracteristiques,
    .pdp-authenticite {
        border-top: 1px solid var(--pdp-trait);
    }

}

.pdp-bloc-titre {
    margin: 0;
    padding: 22px 0 16px;
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ink);
}

.pdp-bloc-bouton {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    text-align: left;
    text-transform: inherit;
    cursor: default;
}

.pdp-description,
.pdp-authenticite-texte {
    max-width: 62ch;
    margin: 0;
    font-size: var(--t-confort);
    line-height: 1.7;
    color: var(--grey-light);
    white-space: pre-line;
}

.pdp-caracteristiques {
    margin: 0;
}

.pdp-caracteristiques > div {
    display: grid;
    grid-template-columns: minmax(110px, 34%) minmax(0, 1fr);
    gap: 16px;
    padding: 12px 0;
    border-bottom: 1px solid var(--pdp-trait);
}

.pdp-caracteristiques > div:first-child {
    padding-top: 0;
}

.pdp-caracteristiques dt {
    font-size: var(--t-lien);
    color: var(--grey);
}

.pdp-caracteristiques dd {
    margin: 0;
    font-size: var(--t-texte);
    color: var(--ink);
}

/* =========================================================
   ALIGNER LE BAS DES DEUX COLONNES

   La colonne de gauche s'arrêtait plus haut que celle de droite.
   Relevé sur les 66 fiches : l'écart allait de 39 à 160 px, et il
   était TOUJOURS positif — la gauche ne dépassait jamais. Les
   deux colonnes faisaient pourtant déjà la même hauteur, la
   grille les étire ; c'est leur contenu qui ne descendait pas
   jusqu'en bas.

   Le dernier bloc de gauche s'étire donc, et le tableau répartit
   la place gagnée ENTRE ses rangées. Elles gardent leur hauteur
   de 44 px et leur filet à 13 px sous le texte : ce qui grandit,
   c'est le blanc entre deux lignes, pas les lignes. La dernière
   tombe au niveau du bas de la colonne de droite.

   Les champs non renseignés sont en display:none : ils ne sont
   pas des éléments flex et ne prennent aucune part dans la
   répartition. Seulement de hauteur nulle, ils auraient fait
   varier les écarts d'une fiche à l'autre selon les champs
   remplis.

   Sous 900 px il n'y a plus deux colonnes — la règle s'arrête.
   ========================================================= */

@media (min-width: 900px) {

    .pdp-colonne-gauche > .pdp-bloc:last-child,
    .pdp-colonne-gauche > .pdp-bloc:last-child > .pdp-bloc-corps {
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
    }

    .pdp-colonne-gauche > .pdp-bloc:last-child .pdp-caracteristiques {
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
    }
}

.pdp-authenticite-texte {
    margin-bottom: 20px;
}

/* LES DEUX PROMESSES
   ------------------------------------------------------------
   Une ligne, pas une liste. Le bloc disait le processus en
   quatre étapes numérotées : c'était lourd, et surtout ça
   répondait à la question que le lien est censé faire poser.

   Ce qui reste est ce que la réassurance sous le bouton d'achat
   ne dit nulle part : la gratuité, et ce qui se passe si le
   verdict est faux. Le point médian est masqué aux lecteurs
   d'écran — il sépare à l'œil, il ne se lit pas.

   Volontairement plus discret que le texte au-dessus : c'est une
   mention, pas un argument crié. */
.pdp-promesses {
    margin: 0 0 20px;
    font-size: var(--t-etiquette);
    line-height: 1.6;
    letter-spacing: .01em;
    color: var(--grey);
}

.pdp-lien {
    font-size: var(--t-lien);
    font-weight: 600;
    color: var(--ink);
    text-decoration: underline;
    text-underline-offset: 4px;
}

/* L'APPEL DU BLOC AUTHENTICITÉ
   ------------------------------------------------------------
   Le même lien que .pdp-lien, mais c'est désormais la seule chose
   à faire dans ce bloc : il prend le cadre d'une action au lieu du
   soulignement d'une note. Il reste en contour, pas en plein — le
   plein est réservé à l'achat, et deux pleins sur une fiche se
   disputeraient le regard.

   inline-flex et non flex : l'appel se cale sur son texte au lieu
   de barrer toute la colonne, ce qui le ferait lire comme un
   second bouton d'achat. */
.pdp-lien-action {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 0 18px;
    border: 1px solid var(--pdp-trait);
    border-radius: var(--r-controle);
    color: var(--ink);
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    text-decoration: none;
    /* Jamais « all » : on nomme ce qui bouge. */
    transition: border-color .2s ease, background .2s ease;
}

.pdp-lien-action:hover {
    background: rgba(var(--ink-rgb), .06);
    border-color: var(--ink);
}

.pdp-lien-action:focus-visible {
    outline: 1px solid var(--ink);
    outline-offset: 2px;
}

.pdp-lien-action-fleche {
    flex: none;
    transition: transform .22s cubic-bezier(.22, 1, .36, 1);
}

.pdp-lien-action:hover .pdp-lien-action-fleche {
    transform: translateX(3px);
}

@media (prefers-reduced-motion: reduce) {

    .pdp-lien-action:hover .pdp-lien-action-fleche {
        transform: none;
    }

}

/* Sous 560 px l'appel prend toute la largeur : à cette taille une
   cible centrée sur son texte devient difficile à viser. */
@media (max-width: 560px) {

    .pdp-lien-action {
        display: flex;
        justify-content: center;
    }

}

/* ---------------------------
   RECOMMANDATIONS
   Un rail de six cartes en grand écran, qui défile au doigt
   sous 1 100 px. Les cartes restent celles du catalogue.
--------------------------- */

.pdp .pdp-recos {
    width: 100%;
    margin: 88px 0 0;
    padding-top: 22px;
    border-top: 1px solid var(--pdp-trait);
}

.pdp[data-etat="vendue"] .pdp-recos,
.pdp[data-etat="retiree"] .pdp-recos {
    margin-top: 56px;
}

.pdp .pdp-recos h2 {
    margin: 0 0 20px;
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ink);
}

/* Le rail « Vous aimerez aussi » n'a plus de grille à lui : il
   suit celle de la Sélection ARKWER (voir « LA SÉLECTION
   ARKWER »), cartes comprises. */

/* ---------------------------
   BARRE D'ACHAT — téléphone uniquement
--------------------------- */

.pdp-barre {
    display: none;
}

/* ---------------------------
   RESPONSIVE
--------------------------- */

@media (max-width: 1180px) {

    .pdp {
        --pdp-marge: 32px;
    }

    .pdp-produit,
    .pdp-details,
    .pdp-authenticite {
        column-gap: 28px;
    }

    .pdp-galerie {
        --pdp-rail: 68px;
        gap: 12px;
    }

    .pdp-nom {
        font-size: var(--t-nom-moyen);
    }

}

@media (max-width: 1099px) {

    .pdp-galerie {
        grid-column: 1 / span 6;
    }

    .pdp-achat {
        grid-column: 7 / span 6;
    }

}

@media (max-width: 899px) {

    .pdp {
        --pdp-marge: 20px;
        padding-top: 14px;
        padding-bottom: 48px;
    }

    .pdp .pdp-ariane {
        margin-bottom: 12px;
        font-size: var(--t-micro);
    }

    .pdp-produit {
        display: block;
    }

    .pdp-galerie,
    .pdp-galerie-seule {
        --pdp-rail: 62px;
        display: flex;
        flex-direction: column;
        gap: 10px;
    }

    .pdp-fleche {
        display: none;
    }

    .pdp-scene-cadre {
        order: 1;
        width: min(100%, calc(52vh * .8));
        margin: 0 auto;
    }

    /* LA BANDE SOUS LA PHOTO : même largeur que la photo, carrés
       alignés, défilement latéral si elles sont nombreuses. */
    .pdp-vignettes {
        order: 2;
        flex-direction: row;
        width: min(100%, calc(52vh * .8));
        height: auto;
        min-height: 0;
        align-self: auto;
        margin: 0 auto;
        padding-bottom: 2px;
        overflow-x: auto;
        overflow-y: hidden;
        scroll-snap-type: x proximity;
        overscroll-behavior-x: contain;
    }

    .pdp-vignette {
        scroll-snap-align: start;
    }

    .pdp-piste {
        border-radius: var(--r-controle);
    }

    .pdp-compteur {
        display: block;
    }

    .pdp-achat {
        position: static;
        margin-top: 18px;
    }

    .pdp-marque {
        margin-bottom: 5px;
        font-size: var(--t-micro);
    }

    .pdp-nom {
        font-size: var(--t-nom-mobile);
    }

    .pdp-prix-ligne {
        margin-top: 10px;
    }

    .pdp-prix {
        font-size: var(--t-prix-mobile);
    }

    /* Taille et état côte à côte : une ligne au lieu de deux, le
       bouton remonte dans le premier écran. La définition de l'état
       reste lisible plus bas, dans les détails. */
    /* UNE COLONNE ICI AUSSI. A 375 px, les deux colonnes faisaient
       133 et 186 px : le libelle d etat passait sur deux lignes et
       son point retombait dessous, exactement le defaut corrige en
       bureau. Mesure sur une fiche. */
    .pdp-faits {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        margin-top: 14px;
        border-bottom: 1px solid var(--pdp-trait);
    }

    .pdp-fait {
        grid-template-columns: minmax(0, 1fr);
        gap: 2px;
        padding: 9px 0;
        border-bottom: 0;
    }

    .pdp-fait + .pdp-fait {
        padding-left: 14px;
        border-left: 1px solid var(--pdp-trait);
    }

    .pdp-fait dt {
        font-size: var(--t-etiquette);
    }

    .pdp-fait dd {
        justify-content: flex-start;
        gap: 2px 10px;
    }

    .pdp-actions,
    .pdp-vendue {
        margin-top: 14px;
    }

    .pdp-confiance {
        margin-top: 18px;
    }

    .pdp-details,
    .pdp-authenticite {
        display: block;
        margin-top: 0;
        border-top: 0;
    }

    .pdp-details {
        margin-top: 40px;
        border-top: 1px solid var(--pdp-trait);
    }

    .pdp-bloc {
        border-bottom: 1px solid var(--pdp-trait);
    }

    .pdp-bloc-titre {
        padding: 0;
    }

    .pdp-bloc-bouton {
        min-height: 54px;
        cursor: pointer;
    }

    .pdp-bloc-bouton::after {
        content: "";
        width: 7px;
        height: 7px;
        margin: 0 4px 4px 12px;
        border-right: 1.5px solid currentColor;
        border-bottom: 1.5px solid currentColor;
        transform: rotate(45deg);
        transition: transform .2s ease;
    }

    .pdp-bloc-bouton[aria-expanded="true"]::after {
        margin-bottom: -4px;
        transform: rotate(-135deg);
    }

    .pdp-bloc-corps,
    .pdp-authenticite > .pdp-bloc-corps {
        padding: 0 0 22px;
    }

    .pdp-description,
    .pdp-authenticite-texte {
        font-size: var(--t-texte);
    }

    .pdp .pdp-recos,
    .pdp[data-etat="vendue"] .pdp-recos,
    .pdp[data-etat="retiree"] .pdp-recos {
        margin-top: 40px;
    }

    .pdp[data-etat="vendue"] .pdp-details,
    .pdp[data-etat="retiree"] .pdp-details {
        margin-top: 40px;
    }

    .pdp-barre {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 4000;
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
        border-top: 1px solid var(--line);
        background: rgba(var(--black-rgb), .96);
        -webkit-backdrop-filter: blur(14px);
        backdrop-filter: blur(14px);
        transform: translateY(105%);
        visibility: hidden;
        transition: transform .22s ease, visibility 0s linear .22s;
    }

    .pdp-barre-visible {
        transform: none;
        visibility: visible;
        transition: transform .22s ease, visibility 0s;
    }

    .pdp[data-etat="vendue"] ~ .pdp-barre,
    .pdp[data-etat="retiree"] ~ .pdp-barre,
    .pdp[data-etat="chargement"] ~ .pdp-barre {
        display: none;
    }

    .pdp-barre-texte {
        display: flex;
        flex: 1;
        flex-direction: column;
        min-width: 0;
    }

    .pdp-barre-nom {
        overflow: hidden;
        font-size: var(--t-etiquette);
        color: var(--grey-light);
        white-space: nowrap;
        text-overflow: ellipsis;
    }

    .pdp-barre-prix {
        font-size: var(--t-confort);
        font-weight: 700;
        color: var(--ink);
    }

    .pdp-barre .pdp-cta {
        width: auto;
        min-height: 46px;
        padding: 0 18px;
        font-size: var(--t-etiquette);
    }

    .pdp ~ footer {
        padding-bottom: 90px;
    }

}

/* Règles partagées, versions petits écrans. */

@media (max-width: 700px) {
    .footer-rich {
        padding: 40px 22px 32px;
    }

    .footer-rich-columns {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 28px 20px;
    }

    .footer-rich-legal-row {
        flex-direction: column;
        align-items: flex-start;
    }

    .breadcrumb {
        margin-bottom: 24px;
        font-size: 11px;
    }
}

/* =======================================================
   PANIER (cart.html)
======================================================= */

.cart-page {
    width: 100%;
    max-width: 1300px;
    margin: 0 auto;
    padding: 40px 50px 120px;
    animation: fadeInUp 0.22s cubic-bezier(.4,0,.2,1) both;
}

.cart-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 36px;
}

.cart-title-row h1 {
    font-size: 30px;
    font-weight: 500;
    letter-spacing: -0.3px;
}

.select-all-label {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--grey-light);
    font-size: 13px;
    cursor: pointer;
}

.select-all-label input {
    width: 16px;
    height: 16px;
    accent-color:var(--ink);
    cursor: pointer;
}

/* ---------------------------
   ÉTAT VIDE
--------------------------- */

.cart-empty {
    display: none;
    flex-direction: column;
    align-items: flex-start;
    gap: 18px;
    padding: 60px 0;
}

.cart-empty.visible {
    display: flex;
}

.cart-empty p {
    color: var(--grey-light);
    font-size: 15px;
}

.continue-shopping {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 50px;
    padding: 0 28px;
    background: var(--ink);
    color: var(--accent-ink);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 1.4px;
    text-transform: uppercase;
    transition: background 0.2s cubic-bezier(.4,0,.2,1), transform 0.2s cubic-bezier(.4,0,.2,1);
}

.continue-shopping:hover {
    background: var(--accent-hover);
    transform: translateY(-2px);
}

/* ---------------------------
   CONTENU PANIER
--------------------------- */

.cart-content {
    display: none;
    grid-template-columns: minmax(0, 1.4fr) minmax(320px, 0.6fr);
    gap: 70px;
    align-items: start;
}

.cart-content.visible {
    display: grid;
}

/* ---------------------------
   LISTE ARTICLES
--------------------------- */

.cart-list {
    width: 100%;
    border-top: 1px solid var(--line);
}

.cart-item {
    width: 100%;
    display: grid;
    grid-template-columns: auto 100px 1fr auto auto auto;
    align-items: center;
    gap: 24px;
    padding: 24px 0;
    border-bottom: 1px solid var(--line);
}

.cart-item-check {
    width: 16px;
    height: 16px;
    accent-color:var(--ink);
    cursor: pointer;
}

.cart-item-image {
    width: 100px;
    height: 100px;
    overflow: hidden;
    background: rgba(var(--ink-rgb), .04);
    border: 1px solid var(--line);
}

.cart-item-image img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.cart-item-info {
    min-width: 0;
}

.cart-item-brand {
    margin-bottom: 4px;
    color: var(--grey);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 1.5px;
    text-transform: uppercase;
}

.cart-item-name {
    margin-bottom: 6px;
    color:var(--ink);
    font-size: 15px;
    font-weight: 500;
}

.cart-item-size {
    color: var(--grey);
    font-size: 13px;
}

.cart-item-qty {
    display: flex;
    align-items: center;
    gap: 12px;
    border: 1px solid var(--line);
}

.qty-btn {
    width: 32px;
    height: 32px;
    border: none;
    background: transparent;
    color:var(--ink);
    font-size: 15px;
    cursor: pointer;
    transition: background 0.2s cubic-bezier(.4,0,.2,1), opacity 0.2s ease;
}

.qty-btn:hover {
    background: rgba(var(--ink-rgb), .08);
}

.qty-btn:disabled {
    color:var(--disabled-ink);
    cursor: not-allowed;
}

.qty-btn:disabled:hover {
    background: transparent;
}

.qty-value {
    min-width: 16px;
    text-align: center;
    font-size: 14px;
    font-weight: 500;
}

.cart-item-price {
    min-width: 70px;
    text-align: right;
    font-size: 15px;
    font-weight: 500;
}

.cart-item-remove {
    width: 30px;
    height: 30px;
    border: none;
    background: transparent;
    color: var(--grey);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    transition: color 0.2s ease;
}

.cart-item-remove:hover {
    color: #e2726f;
}

/* ---------------------------
   RÉSUMÉ
--------------------------- */

.cart-summary {
    width: 100%;
    padding: 30px;
    background: var(--card);
    border: 1px solid var(--line);
    position: sticky;
    top: calc(var(--hauteur-header, 70px) + var(--zone-haut, 0px) + 50px);
}

.cart-summary h2 {
    margin-bottom: 24px;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 1px;
    text-transform: uppercase;
}

.cart-summary-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 16px;
    color: var(--grey-light);
    font-size: 14px;
}

/* --- LA LIGNE LIVRAISON DU RÉCAPITULATIF -------------------

   Elle porte maintenant deux sous-lignes : le mode, puis le
   point. Le montant reste à droite, aligné sur le LIBELLÉ et
   non sur le bloc — un prix qui descend au milieu d'une adresse
   ne se lit plus comme un prix. D'où align-items: baseline et
   non center.

   Les sous-lignes sont en 12,5 px et en gris : elles confirment,
   elles n'annoncent pas. Vides, elles sont masquées et la ligne
   retrouve exactement son ancienne apparence — un libellé, un
   montant. */

.cart-summary-livraison {
    align-items: baseline;
    gap: 16px;
}

.cart-summary-livraison-libelle {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.cart-summary-livraison-mode,
.cart-summary-livraison-point {
    font-size: 12.5px;
    line-height: 1.35;
    color: var(--grey);
}

/* Le nom du point peut être long — « Consigne Pickup Speed
   Queen Laurent ». Il se coupe plutôt que d'élargir la colonne
   et de pousser le montant hors de la carte. */
.cart-summary-livraison-point {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.cart-divider {
    width: 100%;
    height: 1px;
    margin: 20px 0;
    background: var(--line);
}

.cart-summary-total {
    margin-bottom: 26px;
    color:var(--ink);
    font-size: 17px;
    font-weight: 600;
}

.checkout-button {
    width: 100%;
    height: 56px;
    border: 1px solid var(--ink);
    background: var(--ink);
    color: var(--accent-ink);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 1.4px;
    text-transform: uppercase;
    cursor: pointer;
    transition: background 0.2s cubic-bezier(.4,0,.2,1), transform 0.2s cubic-bezier(.4,0,.2,1);
}

.checkout-button:hover {
    background: var(--accent-hover);
    transform: translateY(-2px);
}

.checkout-button:active {
    transform: scale(0.98);
}

.cart-note {
    margin-top: 14px;
    color: var(--grey);
    font-size: 12px;
    text-align: center;
}

/* Le ⓘ de la protection acheteur.

   Un rond de la taille du texte, posé dans le fil de la phrase :
   assez présent pour qu'on sache qu'il y a quelque chose à lire,
   jamais assez pour concurrencer le bouton de commande juste
   au-dessus.

   Il n'est encore relié à rien — la page qu'il ouvrira sera
   branchée plus tard sur [data-info-protection]. */
.info-protection{

    display:inline-flex;
    align-items:center;
    justify-content:center;
    width:14px;
    height:14px;
    margin-left:.15rem;
    vertical-align:-2px;
    padding:0;
    background:none;
    border:1px solid rgba(var(--ink-rgb), .35);
    border-radius:50%;
    color:var(--grey);
    font-family:inherit;
    font-size:9px;
    font-style:italic;
    font-weight:700;
    line-height:1;
    cursor:pointer;
    transition:border-color var(--transition), color var(--transition);

}

.info-protection:hover{

    border-color:rgba(var(--ink-rgb), .7);
    color:var(--ink);

}

@media (prefers-reduced-motion: reduce){

    .info-protection{ transition:none; }

}

.cart-relay-point {
    margin: 4px 0 18px;
}

.cart-relay-label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--grey);
    margin: 0 0 8px;
}

.cart-relay-choose-btn {
    width: 100%;
    padding: 12px;
    border: 1px solid rgba(var(--ink-rgb), .16);
    border-radius: 10px;
    background: transparent;
    color:var(--ink);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: border-color .2s ease, background .2s ease;
}

.cart-relay-choose-btn:hover {
    border-color: rgba(var(--ink-rgb), .35);
    background: rgba(var(--ink-rgb), .03);
}

.cart-relay-selected {
    margin: 8px 0 0;
    font-size: 12px;
    color: var(--grey-light);
    line-height: 1.5;
}

.cart-relay-selected.hidden {
    display: none;
}

.cart-canceled-note {
    margin: 0 0 20px;
    padding: 12px 18px;
    border: 1px solid rgba(var(--ink-rgb), .14);
    border-radius: 10px;
    background: rgba(var(--ink-rgb), .03);
    color: var(--grey-light);
    font-size: 13px;
}

.cart-canceled-note.hidden {
    display: none;
}


/* ---------------------------
   PAGE COMMANDE (commande.html)
--------------------------- */

.checkout-page {
    width: 100%;
    max-width: 1300px;
    margin: 0 auto;
    padding: 40px 50px 120px;
    animation: fadeInUp 0.22s cubic-bezier(.4,0,.2,1) both;
}

.checkout-page h1 {
    font-size: 30px;
    font-weight: 500;
    letter-spacing: -0.3px;
    margin-bottom: 36px;
}

.checkout-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(320px, 0.6fr);
    gap: 70px;
    align-items: start;
}

.checkout-main {
    display: flex;
    flex-direction: column;
    gap: 40px;
}

.checkout-section h2 {
    font-size: 16px;
    font-weight: 500;
    margin-bottom: 18px;
    text-transform: uppercase;
    letter-spacing: .5px;
    color: var(--grey-light);
}

.checkout-items {
    display: flex;
    flex-direction: column;
}

.checkout-item {
    display: grid;
    grid-template-columns: 80px 1fr auto;
    align-items: center;
    gap: 20px;
    padding: 18px 0;
    border-bottom: 1px solid var(--line);
}

.checkout-item-image {
    width: 80px;
    height: 80px;
    background: rgba(var(--ink-rgb), .04);
    border: 1px solid var(--line);
}

.checkout-item-image img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.checkout-item-brand {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .5px;
    color: var(--grey);
    margin-bottom: 4px;
}

.checkout-item-name {
    font-size: 14px;
    margin-bottom: 4px;
}

.checkout-item-size {
    font-size: 12px;
    color: var(--grey);
}

.checkout-item-price {
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
}

.checkout-summary {
    width: 100%;
    padding: 30px;
    background: var(--card);
    border: 1px solid var(--line);
    position: sticky;
    top: calc(var(--hauteur-header, 70px) + var(--zone-haut, 0px) + 50px);
}

.checkout-summary h2 {
    font-size: 16px;
    font-weight: 500;
    margin-bottom: 20px;
}

.checkout-payment-methods {
    margin: 14px 0 20px;
    font-size: 12px;
    color: var(--grey);
    text-align: center;
}

.checkout-form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px;
}

.checkout-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.checkout-field-full {
    grid-column: 1 / -1;
}

.checkout-field label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--grey);
}

/* Ces champs étaient figés en blanc (bordure et texte) : sur le
   fond crème du thème clair, ils devenaient tout simplement
   invisibles — on ne voyait plus où saisir. Ils suivent
   désormais le thème, avec une bordure franche et un léger fond
   pour que la zone de saisie se distingue du reste de la page. */
.checkout-field input {
    padding: 12px 14px;
    border: 1px solid rgba(var(--ink-rgb), .28);
    border-radius: 10px;
    background: rgba(var(--ink-rgb), .04);
    color: var(--ink);
    font-size: 14px;
    font-family: inherit;
    transition: border-color .2s ease, background .2s ease;
}

.checkout-field input::placeholder {
    color: rgba(var(--ink-rgb), .38);
}

/* Le choix du pays gardait l'habillage natif du navigateur —
   un rectangle blanc au milieu d'un formulaire sombre. Il
   reprend ici l'apparence des autres champs, chevron compris,
   dessiné en SVG plutôt qu'importé. */
.checkout-field select {
    padding: 12px 38px 12px 14px;
    border: 1px solid rgba(var(--ink-rgb), .28);
    border-radius: 10px;
    background-color: rgba(var(--ink-rgb), .04);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%238B8A88' stroke-width='1.5'><path d='M1 1l5 5 5-5'/></svg>");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 11px;
    color: var(--ink);
    font-size: 14px;
    font-family: inherit;
    appearance: none;
    -webkit-appearance: none;
    cursor: pointer;
    transition: border-color .2s ease, background-color .2s ease;
}

/* La liste déroulante elle-même est peinte par le système :
   sans cette ligne, ses options restent en clair sur clair. */
.checkout-field select option {
    background: var(--black);
    color: var(--ink);
}

.checkout-field input:hover,
.checkout-field select:hover {
    border-color: rgba(var(--ink-rgb), .45);
}

.checkout-field input:focus,
.checkout-field select:focus {
    outline: none;
    border-color: var(--ink);
    background-color: rgba(var(--ink-rgb), .07);
}

/* Le remplissage automatique du navigateur impose son propre
   fond bleu pâle, illisible ici. On le neutralise avec une
   ombre interne, seule méthode acceptée par les navigateurs. */
.checkout-field input:-webkit-autofill,
.checkout-field input:-webkit-autofill:hover,
.checkout-field input:-webkit-autofill:focus {
    -webkit-text-fill-color: var(--ink);
    box-shadow: 0 0 0 1000px var(--black) inset;
}

/* L'APERÇU, avant même que la valeur soit choisie.

   Quand on survole une suggestion dans la liste du navigateur,
   Chrome écrit la valeur pressentie DANS le champ, en gris
   sombre imposé — sur fond noir, on ne lisait plus rien.

   Cet état n'est PAS couvert par :-webkit-autofill, qui ne
   décrit que le champ déjà rempli. Il a ses propres
   pseudo-classes, et elles restent dans des règles séparées :
   un sélecteur inconnu invalide toute une liste, et Firefox
   comme Safari feraient tomber la règle du dessus avec. */
.checkout-field input:-internal-autofill-previewed {
    -webkit-text-fill-color: var(--ink);
    box-shadow: 0 0 0 1000px var(--black) inset;
}

.checkout-field input:-internal-autofill-selected {
    -webkit-text-fill-color: var(--ink);
    box-shadow: 0 0 0 1000px var(--black) inset;
}

/* --- LES MODES DE LIVRAISON ------------------------------

   REFONTE DU 07/09/2026.

   Il y avait ici quatre cartes presque identiques, ouvertes par
   un émoji, où le transporteur n'était écrit nulle part. Le
   client choisissait entre quatre lignes qu'il ne distinguait
   pas.

   L'option porte maintenant quatre informations dans cet ordre
   de lecture, et un pictogramme dessiné plutôt qu'un émoji :

     TRANSPORTEUR   Mondial Relay        ← qui porte le colis
     MODE           Point relais         ← ce que le client fait
     DÉLAI          3 à 5 jours ouvrés
     PRIX           3,90 €               ← à droite, aligné

   Le transporteur est en Anton capitales, petit : il se lit en
   premier sans écraser le mode, qui est l'information que le
   client compare réellement. Le prix garde sa colonne de droite
   pour que les quatre montants s'alignent verticalement — c'est
   la comparaison la plus fréquente.

   Aucune des valeurs n'est écrite ici : carrier, kind,
   delay_label et price_cents viennent tous de shipping_devis.
   La grille tarifaire n'est pas touchée. */

.delivery-sous-titre {
    margin-top: 1.6rem;
}

.delivery-modes {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 20px;
}

/* Une grille et non un flex : le rappel du point retenu doit
   pouvoir occuper toute la largeur sur une seconde ligne, sous
   le pictogramme comme sous le prix. */
.delivery-mode {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
    gap: 4px 14px;
    padding: 15px 17px;
    border: 1px solid rgba(var(--ink-rgb), .16);
    border-radius: 10px;
    cursor: pointer;
    transition: border-color .18s ease, background-color .18s ease;
}

/* Le radio reste dans le DOM — il porte l'état, le nom de groupe
   et le clavier — mais il n'est pas dessiné : c'est le cadre de
   l'option qui montre la sélection. */
.delivery-mode input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    margin: 0;
    pointer-events: none;
}

.delivery-mode:hover {
    border-color: rgba(var(--ink-rgb), .34);
}

.delivery-mode:has(input:checked) {
    border-color: var(--ink);
    background: rgba(var(--ink-rgb), .055);
    box-shadow: inset 0 0 0 1px var(--ink);
}

.delivery-mode:has(input:focus-visible) {
    outline: 2px solid var(--ink);
    outline-offset: 2px;
}

/* --- UN MODE QUE LA RECHERCHE A DISQUALIFIÉ ----------------

   Tarifé, mais sans point de retrait à cette adresse. Il reste
   à sa place : le faire disparaître sous le curseur ferait
   chercher au client ce qu'il a fait de travers.

   IL EST ÉTEINT, PAS BARRÉ. Un texte barré se lit comme une
   promotion — « ce prix n'est plus le bon » — alors qu'ici
   c'est le mode entier qui n'est pas disponible. On baisse donc
   le contraste de la ligne et on écrit la raison en dessous.

   Le curseur redevient une flèche et le survol n'allume plus
   rien : rien ne suggère qu'un clic ferait quelque chose. Le
   `disabled` du radio fait le reste, clavier compris. */

.delivery-mode-indisponible {
    cursor: default;
    border-color: rgba(var(--ink-rgb), .10);
    background: none;
}

.delivery-mode-indisponible:hover {
    border-color: rgba(var(--ink-rgb), .10);
}

/* La ligne s'éteint, la raison reste lisible : c'est elle qui
   apprend quelque chose. */
.delivery-mode-indisponible .delivery-mode-corps,
.delivery-mode-indisponible .delivery-mode-prix,
.delivery-mode-indisponible .delivery-mode-icone,
.delivery-mode-indisponible .delivery-mode-logo {
    opacity: .42;
}

.delivery-mode-motif {
    grid-column: 1 / -1;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid rgba(var(--ink-rgb), .12);
    font-family: "DM Sans", sans-serif;
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--grey);
}

.delivery-mode-icone {
    width: 20px;
    height: 20px;
    margin-top: 1px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.1;
    stroke-linecap: round;
    stroke-linejoin: round;
    color: var(--grey);
    transition: color .18s ease;
}

.delivery-mode:has(input:checked) .delivery-mode-icone {
    color: var(--ink);
}

.delivery-mode-corps {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

/* LE TRANSPORTEUR. Anton, capitales, petit et espacé : il se
   lit d'abord parce qu'il est en haut, pas parce qu'il est
   gros. */
.delivery-mode-porteur {
    display: flex;
    align-items: center;
    gap: 6px;
    font-family: "DM Sans", sans-serif;
    font-size: var(--t-micro);
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--grey-light);
    line-height: 1.3;
}

/* LE MODE. C'est lui que le client compare, donc le corps le
   plus lisible de l'option. */
.delivery-mode-titre {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 15px;
    font-weight: 500;
    line-height: 1.3;
    color: var(--ink);
}

.delivery-mode-delai {
    font-size: 12.5px;
    line-height: 1.4;
    color: var(--grey);
}

.delivery-mode-prix {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    font-family: "DM Sans", sans-serif;
    font-size: 16.5px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--ink);
    white-space: nowrap;
    padding-top: 1px;
}

/* --- LE POINT RETENU, DANS L'OPTION ----------------------

   Seconde ligne de la grille, toute la largeur. Vide, elle ne
   prend aucune place : le sélecteur `:empty` évite d'écrire une
   règle d'affichage conditionnel en JavaScript. */

.delivery-mode-point {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 2px 14px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid rgba(var(--ink-rgb), .14);
}

.delivery-mode-point:empty {
    display: none;
}

.delivery-mode-point-label {
    grid-column: 1;
    font-size: var(--t-micro);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--grey);
}

.delivery-mode-point-nom {
    grid-column: 1;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--ink);
}

.delivery-mode-point-adresse {
    grid-column: 1;
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--grey);
}

/* Le bouton occupe les trois lignes de la colonne de droite :
   il reste centré face au bloc quelle que soit la longueur de
   l'adresse. */
.delivery-mode-point-modifier {
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: center;
    padding: 9px 15px;
    background: none;
    border: 1px solid rgba(var(--ink-rgb), .3);
    border-radius: 999px;
    color: var(--ink);
    font-family: inherit;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    cursor: pointer;
    white-space: nowrap;
    transition: border-color .18s ease, background-color .18s ease;
}

.delivery-mode-point-modifier:hover {
    border-color: var(--ink);
    background: rgba(var(--ink-rgb), .07);
}

/* --- LE TRANSPORTEUR, RECONNAISSABLE D'UN COUP D'ŒIL ------

   Un badge de réseau, pas une icône d'application : le logo
   officiel en petit, à ses proportions, collé au nom écrit en
   toutes lettres. Ni cadre, ni fond ajouté. Les images sont des
   recadrages des logos officiels du projet (ARKWER ADMIN/
   MAINTENANCE/generer-logos-transporteurs.mjs). Un transporteur
   sans logo reçoit son initiale, jamais un faux symbole. */
.delivery-logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    height: 16px;
    font-family: "DM Sans", sans-serif;
    font-size: 9px;
    font-weight: 700;
    line-height: 1;
    color: var(--ink);
}

.delivery-logo img {
    display: block;
    width: auto;
    height: 16px;
    max-width: 24px;
    object-fit: contain;
}

.delivery-logo-petit,
.delivery-logo-petit img {
    height: 14px;
}

.delivery-logo-absent {
    min-width: 14px;
    padding: 0 3px;
    border-radius: 3px;
    background: rgba(var(--ink-rgb), .12);
}

/* L'option retenue : cadre renforcé, fond léger, coche sous le prix. */
.delivery-mode-coche {
    display: none;
    position: relative;
    width: 18px;
    height: 18px;
    margin-top: 7px;
    border-radius: 50%;
    background: var(--ink);
}

.delivery-mode:has(input:checked) .delivery-mode-coche {
    display: block;
}

.delivery-mode-coche::after {
    content: "";
    position: absolute;
    left: 6.5px;
    top: 3.5px;
    width: 4px;
    height: 8px;
    border-right: 1.8px solid var(--black);
    border-bottom: 1.8px solid var(--black);
    transform: rotate(45deg);
}

.delivery-point-consulte {
    border-color: rgba(var(--ink-rgb), .5);
}

.delivery-mode-titre .delivery-mode-icone {
    flex-shrink: 0;
    width: 15px;
    height: 15px;
    margin: 0;
    stroke-width: 1.4;
}

/* --- CARTE ET LISTE, UN SEUL SÉLECTEUR --------------------

   Deux vues sur les mêmes points. En grand écran elles sont
   côte à côte, la carte à gauche pour situer, la liste à droite
   pour lire. Sur téléphone la carte passe au-dessus : elle
   répond à « c'est où ? », question qu'on se pose avant de lire
   les adresses. */

.delivery-selecteur {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
    align-items: start;
    margin-top: 14px;
}

/* LA CARTE — js/carte-points.js
 *
 * Une couleur qui sert à lire, pas à décorer. L'eau est une
 * nuance froide à peine marquée ; la terre, chaude et claire ; les
 * pays desservis ressortent d'un cran, le pays recherché d'un
 * autre ; le département recherché porte un voile d'or ARKWER.
 * Rivières et autoroutes n'apparaissent qu'à l'échelle où elles
 * aident à se repérer. Les marqueurs, eux, gardent tout le
 * contraste : ce sont eux qu'on vient chercher.
 *
 * Toutes les couleurs sont ici : le script ne connaît que des
 * classes. */
.delivery-carte {
    --carte-mer: #0C151B;
    --carte-terre: #161616;
    --carte-terre-servie: #1E1E1D;
    --carte-terre-visee: #252524;
    --carte-frontiere: rgba(244, 243, 239, .17);
    --carte-limite: rgba(244, 243, 239, .10);
    --carte-lac: #0E161A;
    --carte-riviere: #2A4553;
    --carte-riviere-nom: #6F93A3;
    --carte-autoroute: #7A6441;
    --carte-route-nom: #A08556;
    --carte-axe: #463F33;
    --carte-accent: #C9A668;
    --carte-accent-rgb: 201, 166, 104;
    --carte-libelle: #A3A19E;
    --carte-halo: #161616;
    --carte-pin: #1C1C1C;
    --carte-encre: #F4F3EF;
    position: relative;
    aspect-ratio: 1 / 1;
    border: 1px solid rgba(var(--ink-rgb), .16);
    border-radius: 10px;
    overflow: hidden;
    background: var(--carte-mer);
}

html[data-theme="light"] .delivery-carte {
    --carte-mer: #D0DFE5;
    --carte-terre: #EBE9E3;
    --carte-terre-servie: #F4F2ED;
    --carte-terre-visee: #FBFAF7;
    --carte-frontiere: rgba(28, 28, 28, .21);
    --carte-limite: rgba(28, 28, 28, .12);
    --carte-lac: #D2DBDD;
    --carte-riviere: #A2C0CB;
    --carte-riviere-nom: #4F7887;
    --carte-autoroute: #C8A96F;
    --carte-route-nom: #8E6F35;
    --carte-axe: #D8C6A6;
    --carte-accent: #8A6A2F;
    --carte-accent-rgb: 138, 106, 47;
    --carte-libelle: #5A5755;
    --carte-halo: #F6F5F1;
    --carte-pin: #FFFFFF;
    --carte-encre: #111111;
}

.carte-svg {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    touch-action: none;
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
}

.carte-mer {
    fill: var(--carte-mer);
}

.carte-fond-local,
.carte-sans-fond .carte-mer {
    fill: var(--carte-terre);
}

.carte-fond-local {
    opacity: 0;
}

.carte-pays {
    fill: var(--carte-terre);
    stroke: var(--carte-frontiere);
    stroke-width: .8;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

.carte-pays-servi {
    fill: var(--carte-terre-servie);
}

.carte-pays-vise {
    fill: var(--carte-terre-visee);
}

.carte-region {
    fill: none;
    stroke: var(--carte-limite);
    stroke-width: .8;
    stroke-dasharray: 3 3;
    vector-effect: non-scaling-stroke;
}

.carte-region-visee {
    fill: rgba(var(--carte-accent-rgb), .07);
    stroke: rgba(var(--carte-accent-rgb), .5);
    stroke-dasharray: none;
}

.carte-lacs {
    fill: var(--carte-lac);
    stroke: var(--carte-riviere);
    stroke-width: .6;
    vector-effect: non-scaling-stroke;
}

.carte-rivieres,
.carte-routes {
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

.carte-rivieres {
    stroke: var(--carte-riviere);
}

.carte-rivieres-majeures { stroke-width: 1.4; }
.carte-rivieres-mineures { stroke-width: .9; }

.carte-routes-autoroutes {
    stroke: var(--carte-autoroute);
    stroke-width: 2.4;
}

.carte-routes-axes {
    stroke: var(--carte-axe);
    stroke-width: 1.4;
}

/* Ce qui ne sert qu'à l'échelle d'une ville. */
.delivery-carte:not([data-echelle="ville"]):not([data-echelle="quartier"]) .carte-routes-axes,
.delivery-carte:not([data-echelle="ville"]):not([data-echelle="quartier"]) .carte-rivieres-mineures {
    display: none;
}

/* Routes et cours d'eau IGN (France, échelles ville et quartier).
   Affichés une fois toutes les cellules de la vue reçues, ils
   remplacent alors les tracés Natural Earth. */
.delivery-carte:not(.carte-ign-pret) .carte-ign,
.delivery-carte.carte-ign-pret .carte-routes-axes,
.delivery-carte.carte-ign-pret .carte-routes-autoroutes,
.delivery-carte.carte-ign-pret .carte-rivieres-majeures,
.delivery-carte.carte-ign-pret .carte-rivieres-mineures {
    display: none;
}

.carte-ign-eau { stroke-width: 1.5; }

.carte-ign-r1 {
    stroke: var(--carte-autoroute);
    stroke-width: 2.2;
}

.carte-ign-r2 {
    stroke: var(--carte-axe);
    stroke-width: 1.1;
}

/* Les départementales : le maillage qui fait reconnaître un coin.
   Elles n'apparaissent qu'à l'échelle du quartier, où elles ont de
   la place — plus haut, elles feraient une pelote. */
.carte-ign-r3 {
    stroke: var(--carte-axe);
    stroke-width: .75;
    opacity: .6;
}

.delivery-carte:not([data-echelle="quartier"]) .carte-ign-r3 { display: none; }

.delivery-carte[data-echelle="ville"] .carte-ign-r2 { stroke-width: .8; }
.delivery-carte[data-echelle="ville"] .carte-ign-eau { stroke-width: 1.1; }

.carte-libelle-point {
    fill: var(--carte-libelle);
}

.carte-libelle-ville,
.carte-libelle-region,
.carte-libelle-eau,
.carte-libelle-route,
.carte-zone-texte {
    font-family: "DM Sans", sans-serif;
    paint-order: stroke;
    stroke: var(--carte-halo);
    stroke-width: 3px;
    stroke-linejoin: round;
    pointer-events: none;
}

.carte-libelle-ville {
    font-size: 11px;
    font-weight: 500;
    fill: var(--carte-libelle);
}

.carte-libelle-ville-majeure {
    font-size: 12px;
    font-weight: 600;
    fill: var(--carte-encre);
}

.carte-libelle-region {
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    fill: var(--carte-libelle);
    opacity: .8;
}

.carte-libelle-eau {
    font-size: 10px;
    font-style: italic;
    font-weight: 500;
    fill: var(--carte-riviere-nom);
}

.carte-libelle-route {
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .04em;
    fill: var(--carte-route-nom);
}

/* LA ZONE RECHERCHÉE : un repère d'or, distinct des points. */
.carte-zone-aire {
    fill: rgba(var(--carte-accent-rgb), .14);
    stroke: rgba(var(--carte-accent-rgb), .35);
    stroke-width: 1;
}

.carte-zone-anneau {
    fill: none;
    stroke: var(--carte-accent);
    stroke-width: 2;
}

.carte-zone-centre {
    fill: var(--carte-accent);
}

.carte-zone-texte {
    font-size: var(--t-micro);
    font-weight: 600;
    fill: var(--carte-accent);
}

.carte-marqueurs,
.carte-libelles,
.carte-zone {
    transition: opacity .2s ease;
}

/* Pendant un mouvement, rien ne glisse : marqueurs, zone et noms
   apparaissent posés. */
.carte-en-mouvement .carte-marqueurs,
.carte-en-mouvement .carte-libelles,
.carte-en-mouvement .carte-zone {
    opacity: 0;
    transition: none;
}

.carte-point,
.carte-grappe {
    cursor: pointer;
}

.carte-cible {
    fill: transparent;
}

/* LE MARQUEUR PORTE LE LOGO DE SON RÉSEAU, dans une capsule
   blanche posée sur sa pointe. Un numéro ne disait ni le
   transporteur ni la nature du point ; cinquante pastilles
   chiffrées ne se lisaient pas davantage.

   Blanc, noir, ARKWER. Le survol soulève par l'ombre plutôt que
   par une mise à l'échelle : l'échelle est déjà portée par
   l'attribut du groupe (retenu, mode, secondaire), et une règle
   CSS l'écraserait. */
.carte-pin-fond {
    fill: var(--carte-pin);
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .32));
    transition: filter 170ms ease;
}

.carte-pin-anneau {
    fill: none;
    stroke: rgba(var(--ink-rgb), .16);
    stroke-width: 1;
    transition: stroke 170ms ease;
}

.carte-logo,
.carte-logo-initiales,
.carte-type-fond,
.carte-type-glyphe,
.carte-grappe-nombre {
    pointer-events: none;
}

.carte-logo-initiales,
.carte-grappe-nombre {
    font-family: "DM Sans", sans-serif;
    font-weight: 700;
    fill: var(--carte-encre);
}

/* La pastille blanche sous le logo : invisible au repos, elle
   n'apparaît que sur le marqueur retenu, dont la capsule devient
   noire — le logo reste lisible sans être inversé. */
.carte-pin-plaque {
    fill: none;
}

/* LA NATURE DU POINT, en pastille au coin de la capsule : le
   magasin ou le casier, avec le tracé exact des modes de
   livraison. Le logo dit qui livre, la pastille dit comment on
   retire. */
.carte-type-fond {
    fill: var(--carte-pin);
    stroke: rgba(var(--ink-rgb), .24);
    stroke-width: .8;
}

.carte-type-glyphe {
    fill: none;
    stroke: var(--carte-encre);
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.carte-point:hover .carte-pin-fond {
    filter: drop-shadow(0 4px 6px rgba(0, 0, 0, .42));
}

.carte-point:hover .carte-pin-anneau {
    stroke: rgba(var(--ink-rgb), .34);
}

.carte-point-actif .carte-pin-fond {
    fill: var(--carte-encre);
    filter: drop-shadow(0 4px 7px rgba(0, 0, 0, .45));
}

.carte-point-actif .carte-pin-plaque {
    fill: var(--carte-pin);
}

.carte-point-actif .carte-pin-anneau {
    stroke: var(--carte-accent);
    stroke-width: 1.6;
}

.carte-point-actif .carte-type-fond {
    stroke: var(--carte-accent);
    stroke-width: 1.2;
}

.carte-point-ferme {
    opacity: .45;
    cursor: default;
}

/* LA GRAPPE dit deux choses, et deux seulement : quels réseaux,
   et combien de points. Le chiffre est une quantité — plus jamais
   l'identité d'un point. */
.carte-grappe-fond {
    fill: var(--carte-pin);
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .3));
    transition: filter 170ms ease;
}

.carte-grappe-anneau {
    fill: none;
    stroke: rgba(var(--ink-rgb), .16);
    stroke-width: 1;
    transition: stroke 170ms ease;
}

.carte-grappe-nombre {
    font-size: 11.5px;
}

.carte-grappe:hover .carte-grappe-fond {
    filter: drop-shadow(0 4px 6px rgba(0, 0, 0, .4));
}

.carte-grappe:hover .carte-grappe-anneau {
    stroke: rgba(var(--ink-rgb), .34);
}

.carte-grappe-active .carte-grappe-anneau {
    stroke: var(--carte-accent);
    stroke-width: 1.6;
}

.carte-commandes {
    position: absolute;
    top: 10px;
    right: 10px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.carte-bouton {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid rgba(var(--ink-rgb), .2);
    border-radius: 8px;
    background: var(--black);
    color: var(--ink);
    cursor: pointer;
    transition: border-color .18s ease;
}

.carte-bouton svg {
    width: 14px;
    height: 14px;
}

.carte-bouton:hover:not(:disabled) {
    border-color: var(--ink);
}

.carte-bouton:disabled {
    opacity: .35;
    cursor: default;
}

.carte-bouton[hidden],
.carte-legende[hidden],
.carte-message[hidden] {
    display: none;
}

.carte-legende {
    position: absolute;
    top: 10px;
    left: 10px;
    display: flex;
    flex-wrap: wrap;
    gap: 3px 10px;
    max-width: calc(100% - 66px);
    padding: 5px 9px;
    border-radius: 7px;
    background: rgba(var(--black-rgb), .84);
    font-family: "DM Sans", sans-serif;
    font-size: var(--t-micro);
    line-height: 1.4;
    color: var(--grey-light);
    pointer-events: none;
}

.carte-legende span {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    white-space: nowrap;
}

.carte-legende svg {
    width: 11px;
    height: 13px;
    overflow: visible;
}

.carte-legende-zone svg {
    color: var(--carte-accent);
}

.carte-echelle {
    position: absolute;
    left: 10px;
    bottom: 9px;
    display: flex;
    align-items: flex-end;
    gap: 6px;
    font-family: "DM Sans", sans-serif;
    font-size: var(--t-micro);
    line-height: 1;
    color: var(--grey);
    pointer-events: none;
}

.carte-echelle-barre {
    display: block;
    height: 5px;
    border: 1.5px solid currentColor;
    border-top: 0;
}

.carte-message,
.delivery-carte-attente {
    position: absolute;
    left: 50%;
    max-width: calc(100% - 32px);
    width: max-content;
    margin: 0;
    padding: 9px 13px;
    border: 1px solid rgba(var(--ink-rgb), .14);
    border-radius: 8px;
    background: var(--black);
    font-family: "DM Sans", sans-serif;
    font-size: 12.5px;
    line-height: 1.45;
    text-align: center;
}

.carte-message {
    top: 50%;
    transform: translate(-50%, -50%);
    color: var(--ink);
}

/* La consigne d'attente, écrite dans le HTML : visible uniquement
   avant la première recherche. */
.delivery-carte-attente {
    top: 10px;
    left: 10px;
    width: auto;
    max-width: calc(100% - 64px);
    padding: 7px 11px;
    transform: none;
    font-size: 12px;
    text-align: left;
    color: var(--grey-light);
    display: none;
}

/* Le repère hors cadre : la ville la plus proche, au bord. */
.carte-repere-fond {
    fill: var(--black);
    fill-opacity: .88;
    stroke: rgba(var(--ink-rgb), .16);
    stroke-width: 1;
}

.carte-repere-texte {
    font-family: "DM Sans", sans-serif;
    font-size: var(--t-micro);
    font-weight: 600;
    fill: var(--ink);
    pointer-events: none;
}

[data-etat="attente"] .delivery-carte-attente {
    display: block;
}

/* UNE CARTE À SA TAILLE : pleine largeur au-dessus de la liste en
   grand écran, assez grande pour s'y promener. Carrée sur téléphone
   (voir plus bas). */
.delivery-selecteur .delivery-carte {
    aspect-ratio: 16 / 10;
}

.carte-fiche-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 11px;
}

.carte-fiche-actions .carte-fiche-choisir {
    margin-top: 0;
}

.carte-fiche-statut {
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ink);
}

.carte-fiche-retirer {
    margin-left: auto;
    min-height: 34px;
    padding: 0 12px;
    border: 1px solid rgba(var(--ink-rgb), .3);
    border-radius: 999px;
    background: none;
    color: var(--ink);
    font-family: "DM Sans", sans-serif;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    cursor: pointer;
}

.carte-fiche-retirer:hover {
    border-color: var(--ink);
    background: rgba(var(--ink-rgb), .06);
}

/* LA CARTE SE MANIE : glisser, molette, pincer. */
.carte-glisse .carte-svg {
    cursor: grabbing;
}

/* LE MODE CHOISI D'ABORD. Les autres points restent là, plus petits
   et estompés : accessibles, jamais au premier plan. */
/* HORS DU MODE CHOISI : légèrement en retrait, jamais effacé.
   Un prestataire qu'on ne met pas en avant reste un prestataire
   disponible. */
.carte-point-secondaire,
.carte-grappe-secondaire {
    opacity: .78;
}

.carte-point-secondaire .carte-pin-fond,
.carte-grappe-secondaire .carte-grappe-fond {
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .22));
}

/* Fiche ouverte sur ce point, sans qu'il soit encore retenu. */
.carte-point-consulte .carte-pin-anneau {
    stroke: var(--carte-accent);
    stroke-width: 1.4;
}

/* La légende porte les mêmes logos que les marqueurs : elle
   explique ce qu'on voit, et non une symbolique parallèle. */
.carte-legende-reseau img {
    width: 14px;
    height: 14px;
    border-radius: 3px;
    object-fit: contain;
}

.carte-legende-icone {
    display: inline-flex;
    align-items: center;
}

/* Le magasin et le casier, du même trait que les modes de
   livraison : légende et fiche montrent le signe du marqueur. */
.carte-legende .carte-legende-glyphe,
.carte-fiche-glyphe svg {
    width: 13px;
    height: 13px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.carte-fiche-type {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 2px 0 0;
    font-size: 11.5px;
    color: var(--grey);
}

.carte-fiche-glyphe {
    display: inline-flex;
    flex-shrink: 0;
}

/* Les horaires du jour, sous la distance : une ligne, jamais la
   semaine entière — la fiche reste une fiche. */
.carte-fiche-horaires {
    margin: 2px 0 0;
    font-size: 11.5px;
    color: var(--grey);
}

.carte-legende-prio {
    color: var(--ink);
    font-weight: 600;
}

.carte-credits {
    position: absolute;
    right: 8px;
    bottom: 5px;
    margin: 0;
    font-family: "DM Sans", sans-serif;
    font-size: 9px;
    color: var(--grey);
    opacity: .85;
}

/* LA FICHE D'UN POINT : au-dessus du marqueur en grand écran, en bas
   de la carte sur un écran étroit. */
.carte-fiche {
    position: absolute;
    z-index: 4;
    width: 252px;
    padding: 12px 14px 13px;
    border: 1px solid rgba(var(--ink-rgb), .16);
    border-radius: 10px;
    background: var(--black);
    box-shadow: 0 12px 30px rgba(0, 0, 0, .28);
    font-family: "DM Sans", sans-serif;
    color: var(--ink);
}

.carte-fiche[hidden] {
    display: none;
}

.carte-fiche-bas {
    left: 8px;
    right: 8px;
    bottom: 8px;
    width: auto;
    padding: 9px 12px 10px;
}

/* Sur une petite carte, la fiche reste compacte : elle ne doit
   jamais masquer la moitié du plan. */
.carte-fiche-bas .carte-fiche-tete {
    margin-bottom: 3px;
}

.carte-fiche-bas .carte-fiche-nom {
    font-size: 13.5px;
}

/* Une ligne par information. L'adresse et la distance se
   suivaient en ligne, reliées par un « · » : sur 375 px, la ligne
   se coupait juste après le séparateur, qui restait suspendu en
   bout de ligne. Trois lignes courtes se lisent mieux qu'une
   phrase cassée, et la fiche ne grandit pas pour autant. */
.carte-fiche-bas .carte-fiche-adresse,
.carte-fiche-bas .carte-fiche-meta,
.carte-fiche-bas .carte-fiche-horaires {
    display: block;
    margin: 1px 0 0;
    font-size: 12px;
}

.carte-fiche-bas .carte-fiche-actions {
    margin-top: 8px;
}

.carte-fiche-bas .carte-fiche-choisir {
    min-height: 36px;
}

.carte-en-mouvement .carte-fiche {
    visibility: hidden;
}

.carte-fiche-tete {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 26px 6px 0;
    font-size: var(--t-micro);
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--grey-light);
}

.carte-fiche-tete img {
    display: block;
    width: auto;
    height: 14px;
    object-fit: contain;
}

.carte-fiche-fermer {
    position: absolute;
    top: 6px;
    right: 6px;
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: none;
    color: var(--grey);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
}

.carte-fiche-fermer:hover {
    color: var(--ink);
    background: rgba(var(--ink-rgb), .06);
}

.carte-fiche-nom {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
}

.carte-fiche-adresse {
    margin: 3px 0 0;
    font-size: 12.5px;
    line-height: 1.4;
    color: var(--grey);
}

.carte-fiche-meta {
    margin: 6px 0 0;
    font-size: 12px;
    color: var(--grey-light);
}

.carte-fiche-choisir {
    display: block;
    width: 100%;
    min-height: 40px;
    margin-top: 11px;
    padding: 0 12px;
    border: 1px solid var(--ink);
    border-radius: 7px;
    background: var(--ink);
    color: var(--accent-ink);
    font-family: "DM Sans", sans-serif;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    cursor: pointer;
}

.carte-fiche-choisir:hover:not(:disabled) {
    background: var(--accent-hover);
    border-color: var(--accent-hover);
}

.carte-fiche-choisir:disabled {
    background: transparent;
    color: var(--ink);
    border-color: rgba(var(--ink-rgb), .28);
    cursor: default;
}

/* --- LA LISTE DE POINTS ----------------------------------- */

.delivery-points {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
    gap: 8px;
}

/* LE VOILE DU BAS : « la liste continue ».
 *
 * Un masque, et non un dégradé peint par-dessus : la liste
 * défile, un calque fixe en couleur de fond aurait suivi le
 * contenu ou exigé un conteneur de plus. Le masque, lui, rend
 * les derniers pixels progressivement transparents quel que
 * soit le thème — il n'a aucune couleur à connaître.
 *
 * La classe est posée par le script UNIQUEMENT quand la liste
 * déborde ET qu'on n'est pas au bas : jamais sur une liste
 * complète, où elle mentirait. */
.delivery-points-suite {
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 34px), transparent 100%);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 34px), transparent 100%);
}

/* --- LES FILTRES DE NATURE ---------------------------------

   Trois onglets au plus — Tous, Points relais, Casiers — et
   seulement quand les résultats en mêlent réellement plusieurs.
   Ce sont des FILTRES, jamais un préalable : le client a déjà
   ses points sous les yeux quand il les rencontre.

   Ils empruntent la forme des pastilles de filtre du catalogue
   plutôt que d'inventer un troisième vocabulaire pour le même
   geste. Le compte est écrit dans l'onglet : « Casiers 9 »
   permet de décider s'il vaut la peine d'être ouvert. */

.delivery-filtres {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 16px 0 14px;
}

.delivery-filtre {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    min-height: 38px;
    padding: 0 14px;

    background: none;
    border: 1px solid rgba(var(--ink-rgb), .16);
    border-radius: 999px;
    color: var(--grey);
    cursor: pointer;

    font-family: "DM Sans", sans-serif;
    font-size: 13px;
    letter-spacing: .01em;

    transition: border-color .18s ease, color .18s ease, background-color .18s ease;
}

.delivery-filtre:hover {
    border-color: rgba(var(--ink-rgb), .34);
    color: var(--ink);
}

/* L'onglet actif ne se distingue pas que par la couleur : son
   trait passe à l'encre pleine et son fond se teinte. */
.delivery-filtre-actif {
    border-color: var(--ink);
    background: rgba(var(--ink-rgb), .045);
    color: var(--ink);
}

.delivery-filtre:focus-visible {
    outline: 2px solid var(--ink);
    outline-offset: 2px;
}

.delivery-filtre-nombre {
    font-size: 12px;
    color: var(--grey);
}

.delivery-filtre-actif .delivery-filtre-nombre {
    color: var(--ink);
}

/* « facultatif » à côté d'un intitulé : le client ne doit pas
   croire qu'il lui manque une information pour chercher. */
.checkout-field-option {
    margin-left: 6px;
    font-size: var(--t-micro);
    letter-spacing: .04em;
    text-transform: none;
    color: var(--grey);
}

/* --- « VOIR LES N AUTRES POINTS » --------------------------

   Un lien souligné, pas un bouton plein : il n'est pas l'action
   de cette page — la sienne, c'est de CHOISIR un point. Le
   mettre au même poids qu'une fiche ferait hésiter entre les
   deux.

   Il est aligné à gauche sur la colonne de la liste et garde
   une cible de 44 px de haut : c'est le minimum qu'on vise au
   doigt sans le rater. */

.delivery-points-reste {
    margin-top: 10px;
}

.delivery-points-plus {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0;

    background: none;
    border: 0;
    color: var(--grey);
    cursor: pointer;

    font-family: "DM Sans", sans-serif;
    font-size: 13.5px;
    letter-spacing: .01em;
    text-decoration: underline;
    text-underline-offset: 3px;

    transition: color .18s ease;
}

.delivery-points-plus:hover,
.delivery-points-plus:focus-visible {
    color: var(--ink);
}

.delivery-point {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: start;
    gap: 12px;
    width: 100%;

    /* SANS CETTE LIGNE, LES ADRESSES SE CHEVAUCHENT.
       .delivery-points est un conteneur flex à hauteur bornée :
       ses enfants sont donc compressibles par défaut, et vingt
       points dans 430 px se voyaient écraser leur hauteur
       jusqu'à ce que le nom d'un point passe sur l'adresse du
       précédent. Relevé au premier rendu de la liste. */
    flex-shrink: 0;
    padding: 12px 14px;
    background: none;
    border: 1px solid rgba(var(--ink-rgb), .16);
    border-radius: 9px;
    color: var(--ink);
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color .18s ease, background-color .18s ease;
}

.delivery-point:hover:not(:disabled) {
    border-color: rgba(var(--ink-rgb), .34);
}

/* Même traitement que la pastille de la carte : le point retenu
   est plein, les autres sont vides. Les deux vues disent la même
   chose de la même façon. */
.delivery-point-actif {
    border-color: var(--ink);
    background: rgba(var(--ink-rgb), .045);
}

.delivery-point-rang {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin-top: 1px;
    border: 1px solid rgba(var(--ink-rgb), .3);
    border-radius: 50%;
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}

.delivery-point-actif .delivery-point-rang {
    background: var(--ink);
    border-color: var(--ink);
    color: var(--black);
}

.delivery-point-corps {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.delivery-point-porteur {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 3px;
    font-family: "DM Sans", sans-serif;
    font-size: var(--t-micro);
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--grey-light);
}

.delivery-point-nom {
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
}

.delivery-point-adresse {
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--grey);
}

.delivery-point-note {
    margin-top: 3px;
    font-size: 11.5px;
    letter-spacing: .03em;
    color: var(--grey);
}

.delivery-point-ferme,
.delivery-point:disabled {
    opacity: .45;
    cursor: not-allowed;
}

/* --- DEUX GROUPES DANS LA LISTE ----------------------------

   Le mode choisi d'abord, les autres points proches ensuite :
   choisir un point ou un mode ne fait jamais disparaître un
   prestataire. Deux colonnes en grand écran, une sur téléphone. */
.delivery-points-groupe {
    grid-column: 1 / -1;
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 8px 0 0;
    font-family: "DM Sans", sans-serif;
    font-size: var(--t-micro);
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--grey-light);
}

.delivery-points-groupe:first-child {
    margin-top: 0;
}

.delivery-points-groupe span {
    font-weight: 500;
    letter-spacing: .03em;
    text-transform: none;
    color: var(--grey);
}

.delivery-points-plus-groupe {
    grid-column: 1 / -1;
    justify-self: start;
}

.delivery-point-actif .delivery-point-porteur::after {
    content: "✓ Point retenu";
    margin-left: auto;
    padding-left: 8px;
    color: var(--ink);
    letter-spacing: .05em;
    white-space: nowrap;
}

.delivery-recap-retirer {
    display: inline-block;
    margin-top: 10px;
    padding: 8px 14px;
    border: 1px solid rgba(var(--ink-rgb), .3);
    border-radius: 999px;
    background: none;
    color: var(--ink);
    font-family: inherit;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    cursor: pointer;
}

.delivery-recap-retirer:hover {
    border-color: var(--ink);
    background: rgba(var(--ink-rgb), .06);
}

@media (max-width: 760px) {
    .delivery-points {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* --- LE POINT RETENU (bloc du sélecteur) ------------------- */

.delivery-recap {
    margin-top: 14px;
    padding: 14px 16px;
    border: 1px solid var(--ink);
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.delivery-recap.hidden {
    display: none;
}

.delivery-recap-porteur {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 5px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--grey-light);
}

.delivery-recap-nom {
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--ink);
}

.delivery-recap-adresse {
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--grey);
}

.delivery-recap-id {
    margin-top: 4px;
    font-size: 11.5px;
    letter-spacing: .04em;
    color: var(--grey);
}

.delivery-recap-horaires {
    margin-top: 8px;
    font-size: 12px;
    color: var(--grey);
}

.delivery-recap-horaires summary {
    cursor: pointer;
    color: var(--ink);
    font-size: 11.5px;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.delivery-recap-horaires p {
    margin: 6px 0 0;
    line-height: 1.6;
    white-space: pre-line;
}

/* --- TÉLÉPHONE --------------------------------------------

   Ce n'est pas la version large rétrécie.

   · Le sélecteur se dépile, CARTE D'ABORD : « c'est où ? » se
     pose avant « quelle adresse ? ».
   · La carte perd son format carré — un carré de 375 px de côté
     mangerait la moitié de l'écran — et garde une hauteur
     lisible.
   · Les cibles tactiles montent à 48 px pour l'option et à
     44 px pour le bouton Modifier, qui passe sur sa propre
     ligne : sur 375 px, une adresse et un bouton côte à côte
     laissent l'un des deux illisible.
   · Aucune taille de texte ne descend sous 12 px. */

@media (max-width: 760px) {

    .delivery-selecteur {
        grid-template-columns: minmax(0, 1fr);
        gap: 12px;
    }

    /* Carrée sur téléphone : la vue locale doit laisser la place
       aux communes voisines, pas seulement aux marqueurs. */
    .delivery-selecteur .delivery-carte {
        aspect-ratio: 1 / 1;
        max-height: 62vh;
    }

    /* PLUS DE DÉFILEMENT DANS LE DÉFILEMENT.
     *
     * La liste avait son propre plafond — 58 vh — et donc sa
     * propre barre. Au doigt, c'est un piège : on veut faire
     * défiler la PAGE, on pose le pouce sur la liste, et c'est
     * elle qui bouge. Relevé en test le 10/09/2026 : la
     * troisième fiche se retrouvait coupée en haut, la page
     * n'avait pas bougé d'un pixel.
     *
     * Ce plafond existait pour une bonne raison : vingt points
     * font 2 581 px, et le bouton de paiement se retrouvait à
     * trois écrans du choix. Cette raison a disparu — la liste
     * n'affiche plus que SIX points, et « voir les N autres »
     * laisse le client décider d'allonger la page. On borne
     * désormais par le NOMBRE, pas par une barre de défilement.
     *
     * La carte, elle, garde son plafond : c'est une image, pas
     * une liste. */
    .delivery-points {
        max-height: none;
        overflow-y: visible;
    }

    /* Le voile n'a plus rien à annoncer : rien n'est coupé. */
    .delivery-points-suite {
        -webkit-mask-image: none;
        mask-image: none;
    }

}

@media (max-width: 600px) {

    .delivery-mode {
        padding: 14px;
        gap: 4px 12px;
    }

    .delivery-mode-titre {
        font-size: 14.5px;
    }

    .delivery-mode-prix {
        font-size: 16px;
    }

    /* Le bouton reprend une ligne pleine sous l'adresse. */
    .delivery-mode-point {
        grid-template-columns: minmax(0, 1fr);
    }

    /* 44 px de haut, pas 40 : c'est la cible tactile qu'on rate
       le moins souvent, et « Modifier » est le seul moyen de
       revenir sur son point sans refaire son choix. */
    .delivery-mode-point-modifier {
        grid-column: 1;
        grid-row: auto;
        justify-self: start;
        margin-top: 10px;
        padding: 14px 20px;
        font-size: 12px;
    }

    .delivery-point {
        padding: 13px 14px;
        min-height: 48px;
    }

}

/* .delivery-tab / .delivery-tabs : anciens onglets de mode,
   remplacés par les cartes .delivery-mode ci-dessus. Plus
   aucune page ne les emploie, les règles sont retirées. */

.checkout-form-grid.hidden {
    display: none;
}

.checkout-fees-note {
    margin: 10px 0 0;
    font-size: 11px;
    color: var(--grey);
    text-align: center;
}

/* --- SÉLECTEUR DE POINT RELAIS (widget Mondial Relay) ----

   Le widget arrive avec sa propre feuille de style, servie par
   Mondial Relay. On ne la remplace pas — la réécrire entière
   nous rendrait dépendants de leur balisage interne, qui change
   sans préavis. On l'ENCADRE : le conteneur porte les couleurs
   et la typographie ARKWER, et quelques règles ramènent le
   texte à notre palette.

   Priorité au mobile : la liste est bornée en hauteur et
   défile, pour que le bouton de paiement ne parte jamais hors
   de portée du pouce. */

.delivery-point-label {
    display: block;
    margin: 18px 0 8px;
    font-size: 12px;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--grey);
}

.delivery-widget {
    background: var(--black);
    border: 1px solid rgba(var(--ink-rgb), .18);
    border-radius: 10px;
    padding: 10px;
    max-height: 420px;
    overflow-y: auto;
    font-family: "DM Sans", sans-serif;
    color: var(--ink);
}

/* Les sélecteurs ci-dessous passent par #Zone_Widget : leur
   spécificité d'identifiant l'emporte sur les classes de la
   feuille Mondial Relay, sans avoir à multiplier les
   !important. Les rares déclarations en ligne marquées
   !important par le widget lui-même restent hors d'atteinte —
   c'est une limite du procédé, pas un oubli. */

#Zone_Widget * {
    font-family: "DM Sans", sans-serif !important;
}

/* Le widget peint sa propre racine en blanc : sans cette
   règle, un grand rectangle blanc s'installe au milieu de la
   page de commande. */
#Zone_Widget .MR-Widget,
#Zone_Widget .MRW-LockerModal,
#Zone_Widget .PR-AutoCplCity,
#Zone_Widget .MRW-fl-Select {
    background: var(--black);
}

#Zone_Widget .MRW-Title {
    background: transparent;
    color: var(--grey);
}

/* Nom du point, titres et surlignage de recherche : le magenta
   Mondial Relay est remplacé par l'encre ARKWER. */
#Zone_Widget .PR-Name,
#Zone_Widget .titre,
#Zone_Widget strong {
    color: var(--ink);
}

#Zone_Widget .surligne {
    background: transparent;
    color: var(--ink);
    text-decoration: underline;
}

#Zone_Widget .PR-List-Item,
#Zone_Widget .PR-List-Item div {
    color: var(--grey-light);
}

/* Le nom du point passe devant son adresse : c'est lui que le
   client cherche du regard dans la liste. */
#Zone_Widget .PR-List-Item .PR-Name {
    color: var(--ink);
    font-weight: 500;
}

/* Horaires : gris foncé d'origine, illisible sur fond noir. */
#Zone_Widget .PR-Hours,
#Zone_Widget .PR-Hours th,
#Zone_Widget .PR-Hours td,
#Zone_Widget .PR-Hours tr {
    background: transparent;
    color: var(--grey);
}

#Zone_Widget input[type="text"],
#Zone_Widget select {
    background: rgba(var(--ink-rgb), .04);
    border: 1px solid rgba(var(--ink-rgb), .18);
    border-radius: 7px;
    color: var(--ink);
    padding: 9px 11px;
    font-size: 14px;
}

/* Le vert InPost du bouton de recherche n'a rien à faire ici. */
#Zone_Widget .MRW-BtGo,
#Zone_Widget .MRW-BtGeoGo,
#Zone_Widget .btn {
    background: var(--ink);
    color: var(--accent-ink);
    border: none;
    border-radius: 7px;
}

#Zone_Widget .MRW-Errors {
    background: transparent;
    color: var(--grey-light);
}

@media (max-width: 1000px) {
    .delivery-widget {
        max-height: 340px;
        padding: 8px;
    }
}

@media (max-width: 1000px) {
    .checkout-page {
        padding: 30px 35px 90px;
    }
    .checkout-layout {
        grid-template-columns: minmax(0, 1fr); /* 1fr seul laissait la colonne s'élargir à son contenu : 11 px de trop à 375 px (29/10/2026) */
        gap: 45px;
    }
    .checkout-summary {
        position: static;
    }
}

@media (max-width: 700px) {
    .checkout-page {
        padding: 20px 18px 70px;
    }
    .checkout-item {
        grid-template-columns: 60px 1fr;
        grid-template-areas:
            "image info"
            "image price";
        row-gap: 8px;
    }
    .checkout-item-image {
        grid-area: image;
        width: 60px;
        height: 60px;
    }
    .checkout-item-info {
        grid-area: info;
    }
    .checkout-item-price {
        grid-area: price;
    }
    .checkout-form-grid {
        grid-template-columns: 1fr;
    }
}

/* ---------------------------
   RESPONSIVE PANIER

   Le panier vit à DEUX largeurs très différentes selon la page
   qui l'accueille :

     cart.html          — pleine page, jusqu'à 1300px ;
     compte-panier.html — dans la coquille de Mon ARKWER, où la
                          sidebar prend 208px : il ne reste que
                          ~870px, et 480px pour la liste une fois
                          les 320px du résumé et l'écart retirés.

   Une media query ne voit que la FENÊTRE. Sur un grand écran,
   celle du compte restait donc en disposition « large » alors que
   la place manquait : la colonne du nom tombait à 42px et le
   titre s'écrivait un mot par ligne. C'était visible uniquement
   une fois connecté — d'où une casse qui a longtemps échappé.

   Les règles de disposition passent donc en @container : elles
   suivent la largeur réellement disponible, d'où qu'elle vienne.
   Restent en media query celles qui dépendent bien de la fenêtre
   — les marges de la page elle-même, qui ne peut pas s'interroger.
--------------------------- */

/* Le panier est un conteneur de requête : sans cette déclaration,
   toutes les règles « @container panier » ci-dessous sont ignorées
   et la ligne d'article garde ses six colonnes de bureau sur un
   téléphone (débordement de 71 px, résumé posé sur l'article —
   constaté le 21/10/2026 : la règle avait été amputée, il ne
   restait que « .cart-page, » orphelin). */
/* « Mon panier » (compte-panier.html) n'a plus de coquille
   .compte-shell-contenu : son contenu vit dans main.compte-page. */
.cart-page,
.compte-page:has(.cart-content) {
    container-type: inline-size;
    container-name: panier;
}

@media (max-width: 1000px) {
    .cart-page {
        padding: 30px 35px 90px;
    }
}

@media (max-width: 700px) {
    .cart-page {
        padding: 20px 18px 70px;
    }
    .cart-title-row {
        flex-direction: column;
        align-items: flex-start;
        gap: 14px;
    }
}

/* Sous ~1000px de place, le résumé ne tient plus à côté de la
   liste : il passe dessous et cesse d'être collant. */
@container panier (max-width: 1000px) {
    .cart-content {
        grid-template-columns: 1fr;
        gap: 45px;
    }
    .cart-summary {
        position: static;
    }
}

/* Sous ~700px, la ligne d'article abandonne ses six colonnes
   pour un empilement autour de la vignette. */
@container panier (max-width: 700px) {
    .cart-item {
        grid-template-columns: auto 70px 1fr;
        grid-template-areas:
            "check image info"
            "check image qty"
            "check image price"
            ". remove remove";
        row-gap: 10px;
    }
    .cart-item-check {
        grid-area: check;
    }
    .cart-item-image {
        grid-area: image;
        width: 70px;
        height: 70px;
    }
    .cart-item-info {
        grid-area: info;
    }
    .cart-item-qty {
        grid-area: qty;
        width: fit-content;
    }
    .cart-item-price {
        grid-area: price;
        text-align: left;
    }
    .cart-item-remove {
        grid-area: remove;
        justify-self: end;
    }
}

/* =======================================================
   FILTRES CATALOGUE (pages catégorie)
======================================================= */

.filter-bar{

    display:flex;

    align-items:center;

    flex-wrap:wrap;

    gap:10px;

    margin-bottom:40px;

    padding-bottom:24px;

    border-bottom:1px solid var(--line);

}

/* Quand la barre couvre plusieurs sections (ex: Tee-Shirts + Shorts sur
   l'accueil), elle n'est plus imbriquée dans .category-section : on lui
   redonne le même alignement/marges pour rester visuellement cohérente. */

.catalog-filter-scope > .filter-bar{

    max-width:1700px;

    margin-left:auto;

    margin-right:auto;

    padding-left:40px;

    padding-right:40px;

    box-sizing:border-box;

}

.filter-pill{

    position:relative;

}

.filter-pill-toggle{

    display:inline-flex;

    align-items:center;

    gap:7px;

    padding:10px 18px;

    border:1px solid var(--line);

    border-radius:6px;

    font-size:12.5px;

    font-weight:500;

    letter-spacing:.3px;

    color:var(--grey-light);

    cursor:pointer;

    transition:var(--transition);

    user-select:none;

}

.filter-pill-toggle::after{

    content:"";

    width:0;

    height:0;

    border-left:4px solid transparent;

    border-right:4px solid transparent;

    border-top:5px solid currentColor;

    transition:transform .25s ease;

}

.filter-pill.open .filter-pill-toggle::after{

    transform:rotate(180deg);

}

.filter-pill:hover .filter-pill-toggle,
.filter-pill.open .filter-pill-toggle{

    border-color:rgba(var(--ink-rgb), .35);

    color:var(--ink);

}

.filter-pill.active .filter-pill-toggle{

    border-color:var(--ink);

    color:var(--ink);

    background:rgba(var(--ink-rgb), .06);

}

.filter-panel{

    display:none;

    position:absolute;

    top:calc(100% + 12px);

    left:0;

    min-width:220px;

    padding:18px;

    background:var(--card);

    box-shadow:0 18px 40px rgba(10, 10, 10, .28);

    border:1px solid var(--line);

    border-radius:14px;

    z-index:50;

}

.filter-pill.open .filter-panel{

    display:block;

}

.filter-panel label{

    display:flex;

    align-items:center;

    gap:10px;

    padding:8px 0;

    font-size:13px;

    color:var(--grey-light);

    cursor:pointer;

    white-space:nowrap;

}

.filter-panel label:hover{

    color:var(--ink);

}

.filter-panel input[type="radio"],
.filter-panel input[type="checkbox"]{

    accent-color:var(--ink);

    width:15px;

    height:15px;

    flex-shrink:0;

}

.filter-panel a{

    display:block;

    padding:8px 0;

    font-size:13px;

    color:var(--grey-light);

    white-space:nowrap;

    transition:color .2s ease;

}

.filter-panel a:hover{

    color:var(--ink);

}

.filter-price-inputs{

    display:flex;

    align-items:center;

    gap:10px;

    margin-bottom:14px;

}

.filter-price-inputs input{

    width:80px;

    padding:8px 10px;

    background:rgba(var(--ink-rgb), .05);

    border:1px solid var(--line);

    border-radius:8px;

    color:var(--ink);

    font-family:inherit;

    font-size:13px;

}

.filter-apply-btn{

    width:100%;

    padding:10px;

    background:var(--ink);

    color:var(--accent-ink);

    border:none;

    border-radius:30px;

    font-size:12px;

    font-weight:600;

    letter-spacing:1px;

    text-transform:uppercase;

    cursor:pointer;

    transition:var(--transition);

}

.filter-apply-btn:hover{

    transform:translateY(-2px);

}

.filter-panel-more{

    min-width:240px;

}

.filter-group{

    margin-bottom:18px;

}

.filter-group:last-child{

    margin-bottom:0;

}

.filter-group-title{

    margin-bottom:6px;

    font-size:11px;

    font-weight:700;

    letter-spacing:1.5px;

    text-transform:uppercase;

    color:var(--ink);

}

.filter-empty-note{

    max-width:200px;

    font-size:12.5px;

    color:var(--grey);

    line-height:1.6;

    white-space:normal;

}

.filter-reset-btn{

    padding:10px 16px;

    background:none;

    border:1px solid transparent;

    color:var(--grey);

    font-size:12.5px;

    text-decoration:underline;

    cursor:pointer;

    transition:color .2s ease;

}

.filter-reset-btn:hover{

    color:var(--ink);

}

.filter-panel-close{

    display:block;

    margin-top:6px;

    padding-top:12px;

    border-top:1px solid var(--line);

    text-align:right;

    font-size:12px;

    color:var(--grey-light);

    cursor:pointer;

    transition:color .2s ease;

}

.filter-panel-close:hover{

    color:var(--ink);

}

@media(max-width:700px){

    .filter-bar{

        gap:8px;

    }

    .filter-pill-toggle{

        padding:8px 14px;

        font-size:12px;

    }

}

/* =========================================================
   FILTRER — la barre des grilles filtrables (js/filtres.js)

   Cinq filtres de même rang : Prix, Catégorie, Taille, Marque,
   État. Le tri est à part, même forme mais autre matière.

   - Contrôles en capsules : contour fin, hauteur compacte,
     largeur au contenu.
   - Ouvert = capsule inversée (encre pleine), le panneau part
     de sous elle. Actif = contour encre + point azur.
   - Aucun nombre affiché : ni résultats, ni sélections.
   - Surfaces : les jetons de la page (--acc-*) fournissent la
     zone ; le composant ne pose que ses capsules et panneaux.
========================================================= */

/* ---------------------------------------------------------
   MARGES — comme l'ancienne barre : la barre s'aligne sur la
   grille qu'elle filtre, jamais sur le bord de l'écran.
   Les valeurs suivent les gouttières des sections : 40 px,
   25 px sous 1000 px, 18 px sous 700 px.
--------------------------------------------------------- */

/* La grille de l'accueil remonte de 40 px pour venir buter sous
   l'ancienne barre (.accueil-catalogue-section, margin-top: -40px).
   Sous la nouvelle, ce tirage recouvrait ce qui suit les capsules —
   filtres actifs et message de proximité. On l'annule ici, et
   seulement ici : les autres pages gardent leur réglage. */
.pf + .accueil-catalogue-section { margin-top: 0; }

.catalog-filter-scope > .pf {
    max-width: 1700px;
    margin-left: auto;
    margin-right: auto;
    padding-left: 40px;
    padding-right: 40px;
}

@media (max-width: 1000px) {
    .catalog-filter-scope > .pf {
        padding-left: 25px;
        padding-right: 25px;
    }
}

@media (max-width: 700px) {
    .catalog-filter-scope > .pf {
        padding-left: 18px;
        padding-right: 18px;
    }
}

/* ---------------------------------------------------------
   JETONS — branchés sur les surfaces de la page
--------------------------------------------------------- */

.pf {
    --pf-encre: var(--ink);
    --pf-encre-rgb: var(--ink-rgb);
    --pf-sur-encre: var(--black);
    --pf-page: var(--black);
    --pf-controle: var(--acc-controle, var(--card));
    --pf-panneau: var(--acc-carte-surface, var(--card));
    --pf-filet: rgba(var(--pf-encre-rgb), .1);
    --pf-bord: rgba(var(--pf-encre-rgb), .16);
    --pf-bord-fort: rgba(var(--pf-encre-rgb), .34);
    --pf-sourd: var(--grey);
    --pf-doux: rgba(var(--pf-encre-rgb), .06);
    --pf-ombre: 0 16px 36px -16px rgba(10, 10, 10, .22), 0 2px 6px -2px rgba(10, 10, 10, .06);
    --pf-azur: #9EE5FF;
    --pf-capsule: 999px;
    --pf-anim: 140ms cubic-bezier(.2, 0, 0, 1);

    position: relative;
    margin: 0 0 22px;
    font-family: "DM Sans", sans-serif;
    color: var(--pf-encre);
}

/* Au-dessus des cartes (panier : z-index 3), sous l'en-tête (5000). */
.pf > .pf-barre { position: relative; z-index: 10; }
.pf > .pf-actifs { position: relative; z-index: 9; }

.pf *,
.pf *::before,
.pf *::after { box-sizing: border-box; }

:where(.pf) button {
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.pf :focus-visible {
    outline: 2px solid var(--pf-encre);
    outline-offset: 2px;
}

.pf-cache {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.pf-chevron {
    flex: none;
    width: 10px;
    height: 10px;
    transition: transform var(--pf-anim);
}

[aria-expanded="true"] > .pf-chevron { transform: rotate(180deg); }

.pf-icone { flex: none; width: 16px; height: 16px; }

/* Le point : un filtre est posé. Jamais de nombre. */
.pf-point {
    flex: none;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--pf-azur);
    box-shadow: 0 0 0 1px rgba(10, 10, 10, .14);
}

:root:not([data-theme="light"]) .pf { --pf-ombre: 0 18px 40px -14px rgba(0, 0, 0, .6); }

/* ---------------------------------------------------------
   CAPSULE — la forme commune des contrôles
--------------------------------------------------------- */

.pf-declencheur,
.pf-tri {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 38px;
    padding: 0 14px 0 16px;
    border: 1px solid var(--pf-bord);
    border-radius: var(--pf-capsule);
    background: var(--pf-controle);
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: .09em;
    text-transform: uppercase;
    white-space: nowrap;
    transition: background-color var(--pf-anim), border-color var(--pf-anim), color var(--pf-anim);
}

.pf-declencheur:hover,
.pf-tri:hover { border-color: var(--pf-bord-fort); }

.pf-declencheur.pf-actif { border-color: var(--pf-encre); }

/* Ouvert : capsule inversée. */
.pf-declencheur[aria-expanded="true"],
.pf-tri[aria-expanded="true"] {
    background: var(--pf-encre);
    border-color: var(--pf-encre);
    color: var(--pf-sur-encre);
}

/* ---------------------------------------------------------
   BARRE — BUREAU (≥ 1024 px)
--------------------------------------------------------- */

/* Les six contrôles forment un seul groupe, calé à gauche sur la
   grille. Le tri suit le dernier filtre à courte distance : assez
   pour le distinguer, jamais assez pour qu'il paraisse ailleurs. */
.pf-barre {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0;
}

.pf-groupe {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.pf-bloc {
    position: relative;
    display: flex;
}

/* Trier ouvre la barre : rigoureusement la même capsule que les
   filtres — hauteur, fond, contour, forme, casse et graisse. Seul
   l'espacement l'en détache, et il reste court. */
.pf-bloc-tri { margin-right: 24px; }

/* ---------------------------------------------------------
   PANNEAUX DÉROULANTS — taille au contenu
--------------------------------------------------------- */

.pf-panneau {
    position: absolute;
    top: calc(100% + 10px);
    left: 0;
    z-index: 40;
    width: max-content;
    min-width: 248px;
    max-width: min(380px, calc(100vw - 32px));
    max-height: min(540px, calc(100vh - 240px));
    display: flex;
    flex-direction: column;
    background: var(--pf-panneau);
    border: 1px solid var(--pf-filet);
    border-radius: 14px;
    box-shadow: var(--pf-ombre);
    translate: var(--pf-decalage, 0) 0;
    animation: pf-apparaitre var(--pf-anim) both;
}

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

.pf-panneau-prix { width: 320px; }
.pf-panneau-taille { width: 324px; }
.pf-panneau-marque { width: 288px; }
.pf-panneau-etat { width: 296px; }

/* Le tri étant à gauche, son panneau s'ouvre vers la droite comme
   celui des filtres. */
.pf-panneau-tri { min-width: 212px; }

.pf-panneau-tete {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 8px 2px 18px;
}

.pf-panneau-titre {
    margin: 0 auto 0 0;
    font-size: var(--t-micro);
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--pf-sourd);
}

.pf-panneau-corps {
    overflow-y: auto;
    padding: 6px 18px 18px;
    overscroll-behavior: contain;
}

.pf-fermer {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    color: var(--pf-sourd);
    transition: color var(--pf-anim), background-color var(--pf-anim);
}

.pf-fermer:hover { color: var(--pf-encre); background: var(--pf-doux); }

.pf-fermer svg { width: 14px; height: 14px; }

.pf-lien {
    min-height: 32px;
    font-size: 12.5px;
    color: var(--pf-sourd);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 4px;
    transition: color var(--pf-anim);
}

.pf-lien:hover:not(:disabled) { color: var(--pf-encre); }

.pf-lien:disabled { opacity: .4; cursor: default; }

/* ---------------------------------------------------------
   PRIX — double curseur, sans tranches ni compteur
--------------------------------------------------------- */

.pf-prix-valeurs {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin: 8px 0 18px;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: .01em;
}

.pf-prix-sep { color: var(--pf-sourd); font-weight: 400; }

.pf-plage {
    position: relative;
    height: 24px;
    margin: 0 10px;
}

.pf-plage-rail,
.pf-plage-active {
    position: absolute;
    top: 50%;
    height: 2px;
    translate: 0 -50%;
    border-radius: 2px;
    pointer-events: none;
}

.pf-plage-rail {
    left: -10px;
    right: -10px;
    background: var(--pf-bord);
}

.pf-plage-active {
    left: var(--a, 0%);
    right: calc(100% - var(--b, 100%));
    background: var(--pf-encre);
}

/* Deux <input range> superposés : seule la poignée reste cliquable. */
.pf-curseur {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 24px;
    margin: 0;
    background: none;
    pointer-events: none;
    -webkit-appearance: none;
    appearance: none;
}

.pf-curseur::-webkit-slider-runnable-track { height: 24px; background: none; }
.pf-curseur::-moz-range-track { height: 24px; background: none; }

.pf-curseur::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 20px;
    height: 20px;
    margin-top: 2px;
    border: 1px solid var(--pf-encre);
    border-radius: 50%;
    background: var(--pf-panneau);
    box-shadow: 0 1px 4px rgba(10, 10, 10, .25);
    cursor: grab;
    pointer-events: auto;
}

.pf-curseur::-moz-range-thumb {
    width: 20px;
    height: 20px;
    border: 1px solid var(--pf-encre);
    border-radius: 50%;
    background: var(--pf-panneau);
    box-shadow: 0 1px 4px rgba(10, 10, 10, .25);
    cursor: grab;
    pointer-events: auto;
}

.pf-curseur:focus-visible { outline: 0; }

.pf-curseur:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--pf-encre); outline-offset: 2px; }
.pf-curseur:focus-visible::-moz-range-thumb { outline: 2px solid var(--pf-encre); outline-offset: 2px; }

/* Saisie libre du prix : deux champs en capsule, sous le curseur. */
.pf-saisies {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    margin-top: 14px;
}

.pf-champ {
    flex: 1;
    min-width: 0;
}

.pf-champ label {
    display: block;
    margin: 0 0 6px 14px;
    font-size: 11.5px;
    color: var(--pf-sourd);
}

.pf-saisie {
    display: flex;
    align-items: center;
    height: 40px;
    padding: 0 14px;
    border: 1px solid var(--pf-bord);
    border-radius: var(--pf-capsule);
    background: var(--pf-page);
    font-size: 13px;
    color: var(--pf-sourd);
    transition: border-color var(--pf-anim);
}

.pf-saisie:focus-within { border-color: var(--pf-encre); }

.pf-saisie input {
    flex: 1;
    min-width: 0;
    width: 100%;
    height: 100%;
    border: 0;
    outline: 0;
    background: none;
    font: inherit;
    font-size: 14px;
    color: var(--pf-encre);
    -moz-appearance: textfield;
}

.pf-saisie input::-webkit-outer-spin-button,
.pf-saisie input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.pf-saisie input::placeholder { color: var(--pf-sourd); opacity: .8; }

.pf-tiret-prix {
    padding-bottom: 11px;
    color: var(--pf-sourd);
}

.pf-feuille .pf-saisie { height: 48px; }

/* Repli par proximité : une phrase, pas un bandeau. */
.pf-avis {
    margin: 12px 0 0;
    font-size: 13px;
    color: var(--pf-sourd);
}

.pf-plage-bornes {
    display: flex;
    justify-content: space-between;
    margin: 10px 0 0;
    font-size: 12px;
    color: var(--pf-sourd);
}

/* ---------------------------------------------------------
   LISTES À COCHER — Catégorie, Marque, État
--------------------------------------------------------- */

.pf-liste { display: flex; flex-direction: column; }

.pf-option {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 40px;
    font-size: 14px;
    line-height: 1.3;
    cursor: pointer;
}

.pf-input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    margin: 0;
    pointer-events: none;
}

.pf-case {
    position: relative;
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 17px;
    height: 17px;
    border: 1.25px solid var(--pf-bord-fort);
    border-radius: 5px;
    color: var(--pf-sur-encre);
    transition: background-color var(--pf-anim), border-color var(--pf-anim);
}

.pf-case svg { width: 12px; height: 12px; opacity: 0; }

.pf-option:hover .pf-case { border-color: var(--pf-encre); }

.pf-input:checked + .pf-case {
    background: var(--pf-encre);
    border-color: var(--pf-encre);
}

.pf-input:checked + .pf-case svg { opacity: 1; }

.pf-input:focus-visible + .pf-case {
    outline: 2px solid var(--pf-encre);
    outline-offset: 2px;
}

.pf-libelle { color: var(--pf-encre); }

.pf-input:checked ~ .pf-libelle { font-weight: 600; }

.pf-vide {
    margin: 10px 0 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--pf-sourd);
}

/* Marque : recherche en capsule, liste qui peut grandir. */
.pf-recherche { position: relative; margin: 4px 0 8px; }

.pf-recherche svg {
    position: absolute;
    left: 14px;
    top: 50%;
    width: 15px;
    height: 15px;
    translate: 0 -50%;
    color: var(--pf-sourd);
    pointer-events: none;
}

.pf-recherche input {
    width: 100%;
    height: 38px;
    padding: 0 14px 0 38px;
    border: 1px solid var(--pf-bord);
    border-radius: var(--pf-capsule);
    background: var(--pf-page);
    font: inherit;
    font-size: 13.5px;
    color: var(--pf-encre);
    outline: 0;
}

.pf-recherche input:focus { border-color: var(--pf-encre); }

.pf-liste-marques {
    max-height: 280px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* ---------------------------------------------------------
   TAILLE — capsules, puis « Plus de tailles » (second niveau)
--------------------------------------------------------- */

.pf-tailles {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 4px 0 0;
}

.pf-taille { position: relative; cursor: pointer; }

.pf-taille > span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 48px;
    min-height: 38px;
    padding: 0 12px;
    border: 1px solid var(--pf-bord);
    border-radius: var(--pf-capsule);
    font-size: 13px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    transition: background-color var(--pf-anim), border-color var(--pf-anim), color var(--pf-anim);
}

.pf-taille:hover > span { border-color: var(--pf-encre); }

.pf-taille .pf-input:checked + span {
    background: var(--pf-encre);
    border-color: var(--pf-encre);
    color: var(--pf-sur-encre);
    font-weight: 600;
}

.pf-taille .pf-input:focus-visible + span {
    outline: 2px solid var(--pf-encre);
    outline-offset: 2px;
}

/* Tailles retenues dans un autre système : visibles au premier niveau. */
.pf-tailles-autres {
    margin-top: 8px;
    padding-top: 12px;
    border-top: 1px solid var(--pf-filet);
}

.pf-systemes {
    margin-top: 16px;
    padding-top: 6px;
    border-top: 1px solid var(--pf-filet);
}

.pf-systemes-titre {
    margin: 10px 0 2px;
    font-size: var(--t-micro);
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--pf-sourd);
}

.pf-systeme {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    min-height: 42px;
    font-size: 14px;
    text-align: left;
    transition: color var(--pf-anim);
}

.pf-systeme .pf-fleche {
    flex: none;
    width: 14px;
    height: 14px;
    color: var(--pf-sourd);
    transition: transform var(--pf-anim);
}

.pf-systeme:hover .pf-fleche { transform: translateX(2px); color: var(--pf-encre); }

.pf-retour-ligne {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}

.pf-retour {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 32px;
    font-size: 12.5px;
    color: var(--pf-sourd);
    transition: color var(--pf-anim);
}

.pf-retour:hover { color: var(--pf-encre); }

.pf-retour svg { width: 13px; height: 13px; }

.pf-systeme-titre {
    margin: 0;
    font-size: 13.5px;
    font-weight: 600;
}

/* ---------------------------------------------------------
   TRI
--------------------------------------------------------- */

.pf-tri-liste {
    display: flex;
    flex-direction: column;
    padding: 6px;
}

.pf-tri-option {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 40px;
    padding: 0 16px 0 12px;
    border-radius: 10px;
    font-size: 13.5px;
    text-align: left;
    white-space: nowrap;
}

.pf-tri-option:hover { background: var(--pf-doux); }

.pf-tri-option[aria-checked="true"] { font-weight: 600; }

.pf-tri-coche { display: inline-flex; width: 14px; height: 14px; }

.pf-tri-coche svg { width: 14px; height: 14px; }

/* ---------------------------------------------------------
   FILTRES ACTIFS
   Le bouton porte la cible ; la capsule visible est dedans.
--------------------------------------------------------- */

.pf-actifs { padding-top: 14px; }

.pf-actifs-liste {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.pf-actifs-liste > li[hidden] { display: none; }

.pf-puce {
    display: inline-flex;
    align-items: center;
    min-height: 34px;
}

.pf-puce-corps {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 30px;
    padding: 0 5px 0 13px;
    border: 1px solid var(--pf-bord);
    border-radius: var(--pf-capsule);
    background: var(--pf-controle);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    white-space: nowrap;
    transition: border-color var(--pf-anim);
}

.pf-puce-x {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--pf-doux);
    transition: background-color var(--pf-anim), color var(--pf-anim);
}

.pf-puce-x svg { width: 10px; height: 10px; }

.pf-puce:hover .pf-puce-corps { border-color: var(--pf-encre); }

.pf-puce:hover .pf-puce-x { background: var(--pf-encre); color: var(--pf-sur-encre); }

.pf-puce:focus-visible { outline: 0; }

.pf-puce:focus-visible .pf-puce-corps { outline: 2px solid var(--pf-encre); outline-offset: 2px; }

.pf-puce-plus .pf-puce-corps {
    min-width: 44px;
    justify-content: center;
    padding: 0 12px;
    letter-spacing: 0;
}

.pf-li-effacer { margin-left: 6px; }

/* Sous 1024 px, la barre défile horizontalement au lieu de se replier
   derrière un bouton : les six contrôles restent visibles et se
   touchent directement. Le défilement appartient à la barre seule —
   la page, elle, ne déborde pas. */
.pf-barre-tactile {
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    scroll-padding-inline: 4px;
}

.pf-barre-tactile::-webkit-scrollbar { display: none; }

.pf-barre-tactile .pf-groupe { flex-wrap: nowrap; }

/* Une capsule ne se comprime pas : elle sort du cadre et on la fait
   venir en faisant glisser la barre. */
.pf-barre-tactile .pf-bloc { flex: none; }

@media (max-width: 1023px) {
    .pf-declencheur,
    .pf-tri { min-height: 44px; }
}

@media (max-width: 767px) {

    .pf { margin-bottom: 16px; }

    .pf-actifs { padding-top: 10px; }
}

/* Tactile : cibles de 44 px. */
@media (max-width: 1023px) {
    .pf-puce,
    .pf-tout-effacer { min-height: 44px; }
    .pf-puce-corps { height: 34px; }
    .pf-actifs-liste { row-gap: 0; }
    .pf-tri-option { min-height: 44px; }
}

/* ---------------------------------------------------------
   FEUILLE — tiroir (tablette) / plein écran (téléphone)
--------------------------------------------------------- */

html.pf-verrou,
html.pf-verrou body { overflow: hidden; }

.pf-voile {
    position: fixed;
    inset: 0;
    z-index: 5100;  /* au-dessus de l'en-tête (5000), sous le menu (6000) */
    background: rgba(10, 10, 10, .38);
    animation: pf-fondu 180ms ease both;
}

@keyframes pf-fondu { from { opacity: 0; } }

.pf-feuille {
    position: fixed;
    z-index: 5200;
    top: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    width: min(420px, 100%);
    background: var(--pf-panneau);
    border-left: 1px solid var(--pf-filet);
    animation: pf-tiroir 220ms cubic-bezier(.2, 0, 0, 1) both;
}

@keyframes pf-tiroir { from { transform: translateX(24px); opacity: 0; } }

.pf-feuille-mobile,
.pf-feuille-tri {
    left: 0;
    width: 100%;
    border-left: 0;
    animation-name: pf-feuille;
}

@keyframes pf-feuille { from { transform: translateY(24px); opacity: 0; } }

.pf-feuille-tri {
    top: auto;
    border-top: 1px solid var(--pf-filet);
    border-radius: 18px 18px 0 0;
    padding-bottom: env(safe-area-inset-bottom, 0);
}

.pf-feuille-tete {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 68px;
    padding: 0 16px 0 28px;
}

.pf-feuille-titre {
    margin: 0;
    font-family: "Anton", sans-serif;
    font-size: 28px;
    font-weight: 400;
    letter-spacing: .02em;
    line-height: 1;
    text-transform: uppercase;
}

.pf-fermer-feuille {
    width: 44px;
    height: 44px;
    border: 1px solid var(--pf-bord);
    color: var(--pf-encre);
}

.pf-fermer-feuille svg { width: 14px; height: 14px; }

.pf-feuille-corps {
    flex: 1;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 0 28px 24px;
    border-top: 1px solid var(--pf-filet);
}

.pf-acc { border-bottom: 1px solid var(--pf-filet); }

.pf-acc-h { margin: 0; font: inherit; }

.pf-acc-tete {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: 62px;
    text-align: left;
}

.pf-acc-titre {
    flex: none;
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
}

.pf-acc-resume {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: right;
    font-size: 13px;
    color: var(--pf-sourd);
}

.pf-acc-corps { padding: 0 0 22px; }

/* Dans la feuille, tout se touche au doigt. */
.pf-feuille .pf-option { min-height: 48px; font-size: 15px; }
.pf-feuille .pf-taille > span { min-height: 46px; min-width: 58px; font-size: 14px; }
.pf-feuille .pf-systeme { min-height: 48px; font-size: 15px; }
.pf-feuille .pf-retour { min-height: 44px; }
.pf-feuille .pf-recherche input { height: 46px; }
.pf-feuille .pf-liste-marques { max-height: none; }
.pf-feuille .pf-plage { height: 32px; }
.pf-feuille .pf-curseur { height: 32px; }
.pf-feuille .pf-curseur::-webkit-slider-thumb { width: 26px; height: 26px; margin-top: 3px; }
.pf-feuille .pf-curseur::-moz-range-thumb { width: 26px; height: 26px; }
.pf-feuille .pf-prix-valeurs { font-size: 18px; }

.pf-feuille-pied {
    flex: none;
    display: flex;
    align-items: center;
    gap: 20px;
    padding: 14px 28px calc(14px + env(safe-area-inset-bottom, 0));
    border-top: 1px solid var(--pf-filet);
    background: var(--pf-panneau);
}

.pf-pied-effacer { min-height: 48px; }

.pf-voir {
    flex: 1;
    min-height: 52px;
    border-radius: var(--pf-capsule);
    background: var(--pf-encre) !important;
    color: var(--pf-sur-encre) !important;
    font-size: 12px !important;
    font-weight: 600 !important;
    letter-spacing: .14em;
    text-transform: uppercase;
}

.pf-tri-liste-feuille { padding: 4px 16px 16px; }

.pf-tri-liste-feuille .pf-tri-option {
    justify-content: space-between;
    min-height: 56px;
    padding: 0 12px;
    border-radius: 0;
    font-size: 16px;
    border-bottom: 1px solid var(--pf-filet);
}

.pf-tri-liste-feuille .pf-tri-option:last-child { border-bottom: 0; }

@media (max-width: 767px) {
    .pf-feuille-tete { padding-left: 20px; }
    .pf-feuille-corps { padding: 0 20px 24px; }
    .pf-feuille-pied { padding-left: 20px; padding-right: 20px; }
}

@media (prefers-reduced-motion: reduce) {
    .pf *,
    .pf *::before,
    .pf *::after { animation: none !important; transition: none !important; }
}


/* =======================================================
   BACK-OFFICE (admin.html)
   Réutilise au maximum les briques existantes du site
   (.checkout-field, .auth-form, .auth-submit-btn...) —
   ci-dessous, uniquement ce qui leur manque.
======================================================= */

.admin-navbar-tag{

    margin-left:14px;

    padding:4px 10px;

    border:1px solid var(--line);

    border-radius:999px;

    color:var(--grey);

    font-size:11px;

    letter-spacing:1px;

    text-transform:uppercase;

}

.admin-current-user{

    color:var(--grey);

    font-size:12.5px;

}

.admin-page{

    max-width:1500px;

    margin:0 auto;

    padding:40px 40px 120px;

}

/* ---------- Écrans d'accès ---------- */

.admin-gate{

    max-width:420px;

    margin:70px auto;

    text-align:center;

}

.admin-gate-title{

    margin-bottom:14px;

    font-size:24px;

    font-weight:700;

    letter-spacing:1px;

    text-transform:uppercase;

}

.admin-gate-text{

    margin-bottom:28px;

    color:var(--grey-light);

    font-size:14px;

    line-height:1.7;

}

.admin-gate code{

    padding:2px 6px;

    border-radius:4px;

    background:rgba(var(--ink-rgb),.08);

    font-size:13px;

}

/* Pas de style="..." dans le HTML : la politique de sécurité
   du site (style-src 'self', sans unsafe-inline) bloque les
   styles en ligne, qui seraient donc simplement ignorés. */

.admin-gate-footnote{

    margin-top:26px;

}

.admin-foot-flush{

    padding-left:0;

    padding-right:0;

    border-top:none;

}

/* ---------- Onglets ---------- */

.admin-tabs{

    display:flex;

    gap:8px;

    margin-bottom:34px;

    border-bottom:1px solid var(--line);

}

.admin-tab{

    padding:12px 20px;

    border:none;

    border-bottom:2px solid transparent;

    background:transparent;

    color:var(--grey);

    font-size:13px;

    font-weight:600;

    letter-spacing:.5px;

    cursor:pointer;

    transition:color .2s ease, border-color .2s ease;

}

.admin-tab:hover{

    color:var(--ink);

}

.admin-tab.active{

    border-bottom-color:var(--ink);

    color:var(--ink);

}

/* ---------- En-tête de panneau ---------- */

.admin-panel-head{

    display:flex;

    flex-wrap:wrap;

    align-items:center;

    justify-content:space-between;

    gap:16px;

    margin-bottom:22px;

}

.admin-panel-title{

    display:flex;

    align-items:baseline;

    gap:12px;

}

.admin-panel-title h2{

    font-size:18px;

    font-weight:700;

    letter-spacing:1px;

    text-transform:uppercase;

}

.admin-count{

    color:var(--grey);

    font-size:12.5px;

}

.admin-panel-actions{

    display:flex;

    align-items:center;

    gap:10px;

}

.admin-search{

    width:260px;

    padding:10px 14px;

    border:1px solid var(--line);

    border-radius:8px;

    background:transparent;

    color:var(--ink);

    font-size:13px;

}

.admin-search:focus{

    outline:none;

    border-color:var(--ink);

}

.admin-help{

    max-width:760px;

    margin-bottom:20px;

    color:var(--grey-light);

    font-size:13px;

    line-height:1.7;

}

/* ---------- Boutons ---------- */

.admin-btn{

    padding:10px 18px;

    border:1px solid var(--line);

    border-radius:8px;

    background:transparent;

    color:var(--ink);

    font-size:12.5px;

    font-weight:600;

    cursor:pointer;

    transition:background .2s ease, border-color .2s ease, color .2s ease;

}

.admin-btn:hover:not(:disabled){

    border-color:var(--ink);

}

.admin-btn:disabled{

    opacity:.45;

    cursor:not-allowed;

}

.admin-btn-primary{

    border-color:var(--ink);

    background:var(--ink);

    color:var(--accent-ink);

}

.admin-btn-primary:hover:not(:disabled){

    background:var(--accent-hover);

}

.admin-btn-danger{

    border-color:rgba(226,114,111,.5);

    color:#e2726f;

}

.admin-btn-danger:hover:not(:disabled){

    border-color:#e2726f;

}

.admin-btn-small{

    padding:6px 12px;

    font-size:11.5px;

}

/* ---------- Tableau ---------- */

.admin-table-wrap{

    overflow-x:auto;

    border:1px solid var(--line);

    border-radius:10px;

}

.admin-table{

    width:100%;

    border-collapse:collapse;

    font-size:13px;

}

.admin-table th{

    padding:12px 14px;

    border-bottom:1px solid var(--line);

    color:var(--grey);

    font-size:11px;

    font-weight:600;

    letter-spacing:1px;

    text-align:left;

    text-transform:uppercase;

    white-space:nowrap;

}

.admin-table td{

    padding:12px 14px;

    border-bottom:1px solid var(--line);

    vertical-align:middle;

}

.admin-table tr:last-child td{

    border-bottom:none;

}

.admin-table tbody tr:hover{

    background:rgba(var(--ink-rgb),.03);

}

.admin-thumb{

    display:block;

    width:46px;

    height:46px;

    border-radius:6px;

    object-fit:contain;

    background:rgba(var(--ink-rgb),.04);

}

.admin-thumb-empty{

    border:1px dashed var(--line);

}

.admin-muted{

    color:var(--grey);

}

.admin-code{

    padding:3px 8px;

    border-radius:5px;

    background:rgba(var(--ink-rgb),.07);

    font-size:12.5px;

    letter-spacing:1px;

}

/* ---------- Étiquettes d'état ---------- */

.admin-pill{

    display:inline-block;

    padding:3px 9px;

    border:1px solid var(--line);

    border-radius:999px;

    font-size:var(--t-micro);

    font-weight:600;

    letter-spacing:.5px;

    text-transform:uppercase;

    white-space:nowrap;

}

.admin-pill-ok{

    border-color:rgba(34,197,94,.45);

    color:#22c55e;

}

.admin-pill-warn{

    border-color:rgba(226,114,111,.45);

    color:#e2726f;

}

.admin-pill-star{

    border-color:rgba(var(--gold-rgb),.55);

    color:var(--gold);

}

/* ---------- Fiche d'édition (panneau latéral) ---------- */

.admin-drawer-overlay{

    position:fixed;

    inset:0;

    /* Au-dessus de la barre du site (.navbar, 5000) : à 200, elle
       cachait le titre et la croix du tiroir (constaté le 26/10/2026). */
    z-index:5100;

    display:flex;

    justify-content:flex-end;

    background:rgba(10, 10, 10, .68);

    -webkit-backdrop-filter:blur(3px);
    backdrop-filter:blur(3px);

}

.admin-drawer{

    display:flex;

    flex-direction:column;

    width:min(760px,100%);

    height:100%;

    border-left:1px solid var(--line);

    background:var(--black);

}

.admin-drawer-head{

    display:flex;

    align-items:center;

    justify-content:space-between;

    padding:22px 28px;

    border-bottom:1px solid var(--line);

}

.admin-drawer-head h2{

    font-size:16px;

    font-weight:700;

    letter-spacing:1px;

    text-transform:uppercase;

}

.admin-drawer-close{

    border:none;

    background:transparent;

    color:var(--ink);

    font-size:26px;

    line-height:1;

    cursor:pointer;

}

.admin-drawer-body{

    flex:1;

    overflow-y:auto;

    padding:26px 28px;

}

.admin-drawer-foot{

    display:flex;

    align-items:center;

    justify-content:space-between;

    gap:12px;

    padding:18px 28px;

    border-top:1px solid var(--line);

}

.admin-drawer-foot-right{

    display:flex;

    gap:10px;

    margin-left:auto;

}

.admin-req{

    color:#e2726f;

}

.admin-field-help{

    margin-top:5px;

    color:var(--grey);

    font-size:11.5px;

    line-height:1.5;

}

.admin-drawer textarea{

    width:100%;

    padding:12px 14px;

    border:1px solid var(--line);

    border-radius:10px;

    background:transparent;

    color:var(--ink);

    font-family:inherit;

    font-size:13px;

    line-height:1.6;

    resize:vertical;

}

.admin-drawer select{

    width:100%;

    padding:12px 14px;

    border:1px solid var(--line);

    border-radius:10px;

    background:var(--black);

    color:var(--ink);

    font-family:inherit;

    font-size:13px;

}

.admin-drawer textarea:focus,
.admin-drawer select:focus{

    outline:none;

    border-color:var(--ink);

}

/* ---------- Interrupteurs ---------- */

.admin-toggles{

    display:flex;

    flex-wrap:wrap;

    gap:22px;

    margin-top:24px;

    padding:18px 20px;

    border:1px solid var(--line);

    border-radius:10px;

}

.admin-toggle{

    display:inline-flex;

    align-items:center;

    gap:9px;

    font-size:13px;

    cursor:pointer;

}

.admin-toggle input{

    width:16px;

    height:16px;

    accent-color:var(--ink);

    cursor:pointer;

}

/* ---------- Photos ---------- */

.admin-photos{

    margin-top:30px;

    padding-top:26px;

    border-top:1px solid var(--line);

}

.admin-photos h3{

    margin-bottom:8px;

    font-size:13px;

    font-weight:700;

    letter-spacing:1px;

    text-transform:uppercase;

}

.admin-photo-grid{

    display:grid;

    grid-template-columns:repeat(auto-fill,minmax(130px,1fr));

    gap:12px;

    margin:16px 0;

}

.admin-photo{

    position:relative;

    aspect-ratio:1;

    overflow:hidden;

    border:1px solid var(--line);

    border-radius:8px;

    background:rgba(var(--ink-rgb),.04);

}

.admin-photo img{

    width:100%;

    height:100%;

    object-fit:contain;

}

.admin-photo-main{

    position:absolute;

    top:6px;

    left:6px;

    padding:3px 8px;

    border-radius:999px;

    background:rgba(10, 10, 10, .72);

    color:#F4F3EF;

    font-size:9.5px;

    font-weight:600;

    letter-spacing:.5px;

    text-transform:uppercase;

}

.admin-photo-actions{

    position:absolute;

    right:0;

    bottom:0;

    left:0;

    display:flex;

    justify-content:center;

    gap:4px;

    padding:6px;

    background:rgba(10, 10, 10, .62);

    opacity:0;

    transition:opacity .2s ease;

}

.admin-photo:hover .admin-photo-actions{

    opacity:1;

}

/* Gestion des photos : vitrine, puis galerie numérotée ; actions
   toujours visibles (le menu au survol déroutait), glisser-déposer. */
.admin-photo-grid .admin-photo{

    cursor:grab;

    touch-action:pan-y;

    user-select:none;

    -webkit-user-select:none;

    -webkit-touch-callout:none;

}

.admin-photo-grid .admin-photo-actions{

    opacity:1;

    flex-wrap:wrap;

}

.admin-photo-actions button:not([data-del]):not([data-gauche]):not([data-droite]){

    width:auto;

    padding:0 8px;

    font-size:11px;

    font-weight:600;

}

.admin-photo-vitrine{

    border:2px solid var(--black);

}

.admin-photo-vitrine-auto{

    border:2px dashed var(--line);

    cursor:default;

}

.admin-photo-vitrine-auto img{

    opacity:.45;

}

.admin-photo-source{

    opacity:.35;

}

.admin-photo-cible{

    outline:3px solid var(--black);

    outline-offset:2px;

}

.admin-photo-fantome{

    position:fixed;

    top:0;

    left:0;

    z-index:10000;

    pointer-events:none;

    opacity:.9;

    box-shadow:0 12px 30px rgba(0, 0, 0, .25);

    cursor:grabbing;

}

.admin-photo-actions button{

    width:26px;

    height:26px;

    border:none;

    border-radius:5px;

    background:rgba(244, 243, 239, .9);

    color:#1C1C1C;

    font-size:13px;

    line-height:1;

    cursor:pointer;

}

.admin-upload-status{

    margin-top:10px;

    color:var(--grey-light);

    font-size:12.5px;

}

/* ---------- Codes vendeur ---------- */

.admin-invite-form{

    display:flex;

    flex-wrap:wrap;

    align-items:flex-end;

    gap:14px;

    margin-bottom:26px;

    padding:20px;

    border:1px solid var(--line);

    border-radius:10px;

}

.admin-invite-form .checkout-field{

    min-width:230px;

}

/* ---------- Propositions ---------- */

.admin-cards{

    display:grid;

    grid-template-columns:repeat(auto-fill,minmax(320px,1fr));

    gap:16px;

}

.admin-card{

    padding:20px;

    border:1px solid var(--line);

    border-radius:10px;

}

.admin-card-head{

    display:flex;

    align-items:center;

    justify-content:space-between;

    gap:12px;

    margin-bottom:10px;

}

.admin-card p{

    margin-bottom:10px;

    font-size:13px;

    line-height:1.6;

}

.admin-card-actions{

    display:flex;

    gap:8px;

    margin-top:14px;

}

/* ---------- Notification ---------- */

.admin-toast{

    position:fixed;

    left:50%;

    bottom:26px;

    z-index:5200;

    max-width:calc(100vw - 40px);

    padding:14px 24px;

    border-radius:10px;

    background:var(--ink);

    color:var(--accent-ink);

    font-size:13px;

    font-weight:500;

    box-shadow:0 14px 36px rgba(10, 10, 10, .4);

    transform:translateX(-50%);

}

.admin-toast-error{

    background:#b4231f;

    color:#F4F3EF;

}

@media(max-width:900px){

    .admin-page{

        padding:24px 18px 90px;

    }

    .admin-panel-head{

        align-items:flex-start;

        flex-direction:column;

    }

    .admin-search{

        width:100%;

    }

    .admin-drawer-body{

        padding:20px 18px;

    }

}

/* =======================================================
   AUTHENTIFICATION (modal de connexion)
======================================================= */

.auth-modal-overlay{

    display:none;

    position:fixed;

    inset:0;

    /* Au-dessus de la barre de navigation (5000) et de ses
       résultats de recherche (6000) : à 200, la barre fixe
       recouvrait le titre de la fenêtre. */
    z-index:6500;

    align-items:center;

    justify-content:center;

    padding:20px;

    background:rgba(10, 10, 10, .75);

}

.auth-modal-overlay.open{

    display:flex;

}

.auth-modal{
    position:relative;
    width:min(400px,100%);
    max-height:88vh;
    overflow-y:auto;
    padding:38px 32px 26px;
    background:var(--dark);
    border:1px solid var(--line);
    border-radius:16px;
}

/* La croix se voit du premier coup d'œil : cette fenêtre
   s'ouvre aussi en plein achat (offre de bienvenue), et un
   client qui ne la trouve pas abandonne la page, pas la
   fenêtre. 44 px : la cible tactile minimale. */
.auth-modal-close{
    position:absolute;
    top:10px;
    right:10px;
    display:flex;
    align-items:center;
    justify-content:center;
    width:40px;
    height:40px;
    padding:0;
    border:0;
    border-radius:10px;
    background:transparent;
    color:var(--grey-light);
    font-size:0;
    line-height:0;
    cursor:pointer;
    transition:background-color .2s ease, color .2s ease;
}

.auth-modal-close::before,
.auth-modal-close::after{
    content:"";
    position:absolute;
    width:16px;
    height:1.75px;
    border-radius:2px;
    background:currentColor;
}

.auth-modal-close::before{ transform:rotate(45deg); }
.auth-modal-close::after{ transform:rotate(-45deg); }

.auth-modal-close:hover,
.auth-modal-close:focus-visible{
    background:rgba(var(--ink-rgb), .07);
    color:var(--ink);
    outline:none;
}

.auth-modal:focus{ outline:none; }

.auth-modal-title{
    margin:0 0 24px;
    font-size:21px;
    font-weight:700;
    letter-spacing:.5px;
    line-height:1.2;
    text-align:center;
}

.auth-google-btn{
    display:flex;
    align-items:center;
    justify-content:center;
    gap:10px;
    width:100%;
    min-height:46px;
    padding:12px 14px;
    background:var(--white);
    color:#1C1C1C;
    /* Liseré : en thème clair le bouton blanc se fondait
       dans le fond de la fenêtre. */
    border:1px solid var(--line);
    border-radius:10px;
    font-size:13.5px;
    font-weight:600;
    cursor:pointer;
    transition:var(--transition);
}

.auth-google-btn:hover{

    transform:translateY(-2px);

}

.auth-google-btn:disabled{

    opacity:.6;

    cursor:default;

    transform:none;

}

.auth-divider{
    display:flex;
    align-items:center;
    gap:14px;
    margin:18px 0 16px;
    color:var(--grey);
    font-size:10.5px;
    letter-spacing:1.2px;
    text-transform:uppercase;
}

.auth-divider::before,
.auth-divider::after{

    content:"";

    flex:1;

    height:1px;

    background:var(--line);

}

.auth-form label{
    display:block;
    margin-bottom:7px;
    font-size:12px;
    color:var(--grey-light);
    letter-spacing:.4px;
}

.auth-form input{
    width:100%;
    min-height:46px;
    padding:12px 14px;
    margin-bottom:14px;
    background:rgba(var(--ink-rgb),.05);
    border:1px solid var(--line);
    border-radius:10px;
    color:var(--ink);
    font-family:inherit;
    font-size:14px;
}

.auth-form input::placeholder{

    color:rgba(var(--ink-rgb),.38);

}

.auth-form input:focus{

    outline:none;

    border-color:var(--ink);

}

/* --white et --black ne suivent PAS le thème : --white vaut
   toujours blanc, et --black vaut crème en thème clair. Ce
   bouton était donc blanc avec un texte crème, illisible.
   --ink / --accent-ink s'inversent correctement, eux. */
.auth-submit-btn{
    width:100%;
    min-height:46px;
    padding:13px;
    background:var(--ink);
    color:var(--accent-ink);
    border:none;
    border-radius:30px;
    font-size:12px;
    font-weight:600;
    letter-spacing:1px;
    text-transform:uppercase;
    cursor:pointer;
    transition:var(--transition);
}

.auth-submit-btn:hover{

    transform:translateY(-2px);

}

.auth-submit-btn:disabled{

    opacity:.5;

    cursor:default;

    transform:none;

}

.auth-secondary-btn{
    display:block;
    width:100%;
    margin-top:12px;
    padding:4px 0;
    background:none;
    border:none;
    color:var(--grey-light);
    font-size:12.5px;
    text-decoration:underline;
    cursor:pointer;
    text-align:center;
}

.auth-secondary-btn:hover{

    color:var(--ink);

}

.auth-code-note{

    margin-bottom:16px;

    font-size:13px;

    color:var(--grey-light);

    text-align:center;

}

.auth-error{

    margin-top:14px;

    font-size:12.5px;

    color:#e5484d;

    text-align:center;

}

.auth-success{

    margin-top:14px;

    font-size:12.5px;

    color:#22c55e;

    text-align:center;

}

/* Bloc « Vos données » sous les formulaires : discret, il
   rassure sans concurrencer le bouton d'action. */
/* CONFIANCE DE CONNEXION : un titre net, deux badges colorés
   empilés, des liens en pied. Les badges reprennent les codes
   reconnus (vert = protégé, drapeau UE = Europe) : selon Baymard,
   la sécurité se juge d'abord à l'œil et aux repères familiers. */
.auth-confiance{
    margin:22px 0 0;
    padding-top:16px;
    border-top:1px solid var(--line);
    text-align:center;
    /* conteneur : les badges règlent leur taille sur sa largeur (cqw),
       pour tenir sur UNE ligne à toutes les largeurs */
    container-type:inline-size;
}

.auth-confiance-badges{
    display:flex;
    flex-direction:row;
    flex-wrap:nowrap;
    align-items:center;
    justify-content:flex-start;
    gap:4px;
    margin:0;
    padding:0;
    list-style:none;
}

.auth-badge{
    display:inline-flex;
    align-items:center;
    flex:none;
    /* tout est en em : la pastille grandit et rétrécit avec le texte,
       qui vaut 9,5 px au plus et se réduit pour ne jamais passer à la
       ligne (≈ 2,65 % de la largeur du bloc, 6,4 px au minimum) */
    gap:.5em;
    padding:.3em .7em .3em .3em;
    border-radius:999px;
    font-size:max(6.4px, min(9.5px, 2.65cqw));
    font-weight:500;
    line-height:1.2;
    white-space:nowrap;
}

.auth-badge svg{
    flex:none;
    width:1.35em;
    height:1.35em;
}

/* Thème sombre par défaut ; le clair est data-theme="light". */
.auth-badge-europe{ background:rgba(76, 110, 230, .18); color:#D3DDFF; }
.auth-badge-securite{ background:rgba(46, 170, 96, .18); color:#C2EDD3; }
.auth-badge-securite svg{ color:#3DBB6E; }

:root[data-theme="light"] .auth-badge-europe{ background:#EEF2FC; color:#1A2E6E; }
:root[data-theme="light"] .auth-badge-securite{ background:#E9F6EE; color:#17663A; }
:root[data-theme="light"] .auth-badge-securite svg{ color:#1E8A4C; }

.auth-confiance-liens{
    display:flex;
    justify-content:center;
    gap:10px;
    margin:20px 0 0;
    font-size:11px;
    color:var(--grey-light);
}

.auth-confiance-liens a{

    color:inherit;

    text-decoration:none;

    border-bottom:1px solid transparent;

    transition:border-color .2s ease, color .2s ease;

}

.auth-confiance-liens a:hover,

.auth-confiance-liens a:focus-visible{

    color:var(--ink);

    border-color:var(--ink);

}

.hidden{

    display:none;

}

.navbar-account-link.logged-in{

    color:var(--gold);

}

/* =======================================================
   FIN

/* ===========================
   PAGE 404
=========================== */

/* Volontairement sobre : on réemploie la mise en page de
   .legal-page. Les tokens --grey et --ink suivent le thème,
   contrairement à --white/--black qui sont figés. */

.error-code{

    margin-bottom:14px;

    color:var(--grey);

    font-size:11px;

    font-weight:500;

    letter-spacing:3px;

    text-transform:uppercase;

}

.error-links{

    list-style:none;

    max-width:420px;

    margin:0;

    padding:0;

}

.error-links li{

    border-top:1px solid var(--line);

}

.error-links li:last-child{

    border-bottom:1px solid var(--line);

}

.error-links a{

    display:block;

    padding:13px 0;

    color:var(--ink);

    font-size:14.5px;

    text-decoration:none;

    transition:opacity .2s ease;

}

.error-links a:hover{

    opacity:.55;

}

/* ===========================
   CARTE VENDUE
=========================== */

/* La pièce reste visible — elle prouve l'activité de la
   boutique — mais elle ne se comporte plus comme une offre :
   plus de lien, plus de survol, photo en retrait, panier
   désactivé. Le survol est refusé à la source
   (.card:not(.card-soldout), dans GRILLE PRODUITS ET CARTE). */

.card-soldout {
    cursor: default;
}

.card-soldout .card-visuel img {
    filter: grayscale(1);
    opacity: .42;
}

.card-soldout .product-brand,
.card-soldout .product-sizes {
    opacity: .55;
}

/* Le prix d'une pièce vendue n'est plus une information
   d'achat : on le barre au lieu de le mettre en avant. */
.card-soldout .product-price {
    opacity: .55;
    text-decoration: line-through;
}

/* ===========================
   PAGE PAIEMENTS
=========================== */

/* Une page de paiement se lit avant de sortir sa carte : elle
   doit être calme, aérée, sans effet. Tout est construit sur
   les tokens du thème — aucune couleur figée, sinon la page
   se casse en clair comme le menu de filtres le faisait. */

.pay-page{

    max-width:920px;

    margin:0 auto 120px;

    padding:0 24px;

}

/* ---------- En-tête ---------- */

.pay-hero{

    padding:70px 0 46px;

    border-bottom:1px solid var(--line);

    margin-bottom:56px;

}

.pay-eyebrow{

    margin-bottom:14px;

    color:var(--grey);

    font-size:11px;

    font-weight:500;

    letter-spacing:3px;

    text-transform:uppercase;

}

.pay-hero h1{

    margin-bottom:18px;

    color:var(--ink);

    font-size:clamp(30px,4.2vw,46px);

    font-weight:500;

    line-height:1.08;

    letter-spacing:-1px;

}

.pay-intro{

    max-width:60ch;

    color:var(--grey-light);

    font-size:15.5px;

    line-height:1.75;

}

/* ---------- Blocs ---------- */

.pay-block{

    margin-bottom:64px;

}

.pay-block h2{

    margin-bottom:22px;

    color:var(--ink);

    font-size:20px;

    font-weight:500;

    letter-spacing:-.3px;

}

.pay-lead,
.pay-block > p{

    max-width:65ch;

    color:var(--grey-light);

    font-size:14.5px;

    line-height:1.8;

}

.pay-note{

    max-width:65ch;

    margin-top:20px;

    padding-left:16px;

    border-left:2px solid var(--line);

    color:var(--grey);

    font-size:13.5px;

    line-height:1.75;

}

/* ---------- Moyens de paiement ---------- */

.pay-methods{

    display:grid;

    grid-template-columns:repeat(auto-fit,minmax(230px,1fr));

    gap:1px;

    background:var(--line);

    border:1px solid var(--line);

    border-radius:12px;

    overflow:hidden;

}

/* Le fond de la grille est la ligne elle-même : chaque carte
   pose son propre fond par-dessus, et les interstices d'1px
   dessinent les séparateurs. Une seule bordure au lieu de
   quatre par carte, donc pas de doublons à la jonction. */
.pay-method{

    padding:24px 22px;

    background:var(--black);

}

.pay-method h3{

    margin-bottom:8px;

    color:var(--ink);

    font-size:14.5px;

    font-weight:500;

}

.pay-method p{

    color:var(--grey);

    font-size:13px;

    line-height:1.7;

}

.pay-method-highlight{

    background:rgba(var(--ink-rgb),.045);

}

/* ---------- Tableau des frais ---------- */

.pay-table{

    width:100%;

    margin-top:26px;

    border-collapse:collapse;

}

.pay-table th,
.pay-table td{

    padding:16px 0;

    border-top:1px solid var(--line);

    text-align:left;

    vertical-align:top;

    font-size:14px;

    line-height:1.7;

}

.pay-table tr:last-child th,
.pay-table tr:last-child td{

    border-bottom:1px solid var(--line);

}

.pay-table th{

    width:38%;

    padding-right:24px;

    color:var(--ink);

    font-weight:500;

}

.pay-table td{

    color:var(--grey-light);

}

/* ---------- Sécurité ---------- */

.pay-security{

    display:grid;

    grid-template-columns:repeat(auto-fit,minmax(260px,1fr));

    gap:28px 40px;

}

.pay-security-item h3{

    margin-bottom:9px;

    padding-top:16px;

    border-top:1px solid var(--line);

    color:var(--ink);

    font-size:14.5px;

    font-weight:500;

}

.pay-security-item p{

    color:var(--grey);

    font-size:13.5px;

    line-height:1.75;

}

/* ---------- Questions ---------- */

.pay-faq{

    margin:0;

}

.pay-faq dt{

    padding-top:22px;

    margin-bottom:9px;

    border-top:1px solid var(--line);

    color:var(--ink);

    font-size:14.5px;

    font-weight:500;

}

.pay-faq dd{

    max-width:68ch;

    margin:0 0 22px;

    color:var(--grey-light);

    font-size:14px;

    line-height:1.8;

}

.pay-faq a{

    color:var(--ink);

    text-decoration:underline;

    text-underline-offset:3px;

    text-decoration-thickness:1px;

}

/* ---------- Appel au contact ---------- */

.pay-cta{

    padding:44px 32px;

    border:1px solid var(--line);

    border-radius:14px;

    background:rgba(var(--ink-rgb),.03);

    text-align:center;

}

.pay-cta h2{

    margin-bottom:12px;

    color:var(--ink);

    font-size:19px;

    font-weight:500;

}

.pay-cta p{

    max-width:48ch;

    margin:0 auto 24px;

    color:var(--grey);

    font-size:14px;

    line-height:1.75;

}

.pay-cta-button{

    display:inline-block;

    padding:13px 28px;

    background:var(--ink);

    color:var(--accent-ink);

    border-radius:999px;

    font-size:14px;

    font-weight:500;

    text-decoration:none;

    transition:opacity .2s ease;

}

.pay-cta-button:hover{

    opacity:.82;

}

/* ---------- Écrans étroits ---------- */

@media(max-width:640px){

    .pay-page{

        margin-bottom:80px;

    }

    .pay-hero{

        padding:48px 0 34px;

        margin-bottom:42px;

    }

    .pay-block{

        margin-bottom:48px;

    }

    /* Deux colonnes deviennent illisibles : le libellé passe
       au-dessus de sa valeur. */
    .pay-table th,
    .pay-table td{

        display:block;

        width:auto;

        padding-right:0;

    }

    .pay-table th{

        padding-bottom:4px;

    }

    .pay-table td{

        padding-top:0;

    }

    .pay-cta{

        padding:34px 22px;

    }

}

/* Marque sans article sur la page courante : visible pour montrer
   l'étendue du catalogue, mais non cochable — un filtre qui ne
   renvoie rien est une impasse. */
.filter-option-empty{

    opacity:.42;

    cursor:default;

}

.filter-count{

    margin-left:auto;

    padding-left:14px;

    color:var(--grey);

    font-size:11.5px;

    font-variant-numeric:tabular-nums;

}

/* Case « vitrine seule » sur une photo de l'administration.
   Posée sur l'image, donc sur un fond dont on ignore la clarté :
   couleurs figées volontairement, elles ne dépendent pas du
   thème mais de la photo. */
.admin-photo-cover{

    position:absolute;

    left:6px;

    right:6px;

    bottom:6px;

    display:flex;

    align-items:center;

    gap:6px;

    padding:5px 8px;

    background:rgba(10, 10, 10, .72);

    border-radius:6px;

    color:#F4F3EF;

    font-size:11px;

    cursor:pointer;

    user-select:none;

}

.admin-photo-cover input{

    accent-color:#F4F3EF;

    width:13px;

    height:13px;

    margin:0;

    cursor:pointer;

}

/* ===========================
   BORDS DE PHOTO — PLUS AUCUN FONDU
=========================== */

/* RETIRÉ LE 07/09/2026, À LA DEMANDE.

   Il y avait ici un masque qui rendait transparents les derniers
   pixels des photos de fiche et des vignettes, sur les quatre
   côtés, pour qu'elles se dissolvent dans le fond de la page au
   lieu de former un rectangle à bords francs.

   Les photographies reprennent donc leurs bords nets. Ce qui
   revient avec eux, et qui était le motif d'origine du fondu :
   le fond de la photo — béton, drap — se lit maintenant comme un
   rectangle posé sur la page, d'autant plus visible en thème
   clair où l'écart de luminance est le plus grand.

   Deux autres fondus subsistent volontairement dans le fichier et
   ne sont PAS de ce type : celui du bas du hero (--fondu-bas),
   qui raccorde la bannière à la page sur un seul bord, et ceux du
   bandeau de marques et du carrousel d'avis, qui signalent qu'un
   rail continue au-delà du cadre. Aucun des deux n'encadre une
   image.

   Pour rétablir : un masque de deux dégradés croisés
   (linear-gradient to right + to bottom, transparent aux
   extrémités) avec mask-composite:intersect, 5 % sur
   .product-image et 6 % sur .product-thumbnail img. */

/* La bordure de la vignette reste éteinte au repos : elle l'était
   déjà, et le fondu n'en était que la justification écrite. Les
   états survol et sélection, eux, continuent de la faire
   apparaître — ce sont eux qui portent l'information. */
.product-thumbnail{

    border-color:transparent;

}

.product-thumbnail:hover{

    border-color:rgba(var(--ink-rgb),.25);

}

.product-thumbnail.selected{

    border-color:rgba(var(--ink-rgb),.55);

}

/* ===========================
   ÉTAT DE LA PIÈCE

   Cinq valeurs fixes (voir supabase/schema.sql, section 11).
   Pas de code couleur : un point ou un pavé ne veut rien dire
   tant qu'on n'en a pas appris la légende, alors qu'une phrase
   se comprend d'elle-même. On affiche donc le libellé suivi de
   sa définition — la même logique que Vinted sur sa fiche de
   dépôt — plutôt qu'un indicateur à mémoriser.
=========================== */

/* Carte du catalogue : juste le libellé, sobre, sous le prix. */
.condition-tag{

    margin-top:2px;

    color:var(--grey-light);

    font-size:12.5px;

}

/* Fiche produit : libellé en évidence, définition juste en
   dessous, en retrait — le même rapport que ".product-defects"
   plus haut sur cette page, pour que les deux mentions d'état
   se lisent comme une seule famille visuelle. */
.condition-label{

    display:block;

    color:var(--ink);

    font-weight:500;

}

/* ===========================
   HERO D'ACCUEIL
=========================== */

/* REPÈRES MESURÉS DANS LE FICHIER IMAGE
   ------------------------------------------------------------------
   Rien ici n'est estimé à l'oeil : les valeurs viennent d'une
   analyse des pixels de images/banniere-accueil.jpg (1844 × 853,
   rapport 2,162).

   Bannière remplacée le 02/09/2026. Contrairement au remplacement
   précédent, celle-ci ne se superpose PAS à l'ancienne : son
   rapport passe de 2,591 à 2,162, elle est proportionnellement
   plus haute. Deux valeurs en dépendent directement et ont donc
   été refaites — aspect-ratio et min-height. Tout le reste (les
   voiles, le fondu du bas, le placement du texte) a été vérifié
   sur les mesures ci-dessous et tient tel quel.

   La méthode de mesure a été validée avant d'être appliquée : elle
   redonne exactement, sur les deux images précédentes, les
   chiffres de luminance déjà écrits ici (166 184 163 152, et
   159 181 171 167). Les valeurs de l'ancienne sont rappelées
   entre parenthèses.

     · Le personnage (veste jaune) se tient toujours dans le tiers
       droit : son bord droit est à 75 % de la largeur (avant :
       72 %), et il descend jusqu'au bas du cadre. Les deux tiers
       gauches lui restent entièrement libres — la marque et le
       bouton gardent leur place.

     · Le ciel occupe tout le haut et il reste TRÈS clair : 147
       puis 165, 172, 132 de luminance moyenne par tranches de 10 %
       (avant : 166, 184, 163, 152). Un peu moins écrasant, mais du
       même ordre : le voile du haut reste nécessaire, et suffisant.

     · À partir de la moitié, le premier plan s'assombrit de
       lui-même, et PLUS FRANCHEMENT qu'avant : 68, puis 34, 27,
       23, 25, 25 (avant : 102, 53, 43, 38, 34, 36). Le texte crème
       du bas y gagne en lisibilité ; le voile du bas est donc
       conservé tel quel plutôt que renforcé.

     · Le point le plus haut du relief est à 20,6 % de la hauteur
       (avant : 19,3 % — mesure d'origine, conservée telle qu'elle
       était écrite). C'est la limite absolue du rognage par le
       haut : au-delà, on décapite le massif. Elle commande le
       min-height ci-dessous.

   Conclusion : la marque va en bas à gauche, le bouton lui répond
   à droite sur la même ligne de base, et le personnage reste seul
   dans son tiers droit. */

.hero{

    position:relative;

    width:100%;

    /* UN CADRE PANORAMIQUE, ROGNÉ PRESQUE UNIQUEMENT PAR LE BAS.
       --------------------------------------------------------------
       TROISIÈME ARBITRAGE, 07/09/2026. Les deux premiers ont tour à
       tour tout sacrifié au même endroit ; celui-ci répartit.

         · 02/09 — cadre à 3,200 pour une image à 2,162, ancré en
           bas : 67,6 % de la hauteur, et le ciel et la crête
           perdus pour garder de l'herbe.
         · 07/09 (matin) — cadre au rapport exact du fichier, rien
           de rogné : composition d'origine respectée, mais 666 px
           de haut sur un 1440, et surtout 17 % de la hauteur en
           terrain sombre sous le personnage. Le hero se lisait
           comme une grande image verticale posée là.

       CE QUI EST GARDÉ, CE QUI EST SACRIFIÉ
       --------------------------------------------------------------
       Repères relevés au pixel dans un canvas sur le fichier
       (1844 × 853, rapport 2,1618) :

         sommet du massif      20,6 %
         soleil                41,8 %
         capuche du personnage 45,8 %
         chaussures            81,0 - 83,0 %
         sol sous les pieds    83,0 - 100 %

       La bande montrée va de 7 % à 89,5 %, soit 82,5 % de la
       hauteur. Elle enlève 7 % de ciel — le sommet reste à 16,5 %
       du cadre, il lui reste 91 px de ciel au-dessus sur un 1440 —
       et 10,5 % de sol, c'est-à-dire les DEUX TIERS du terrain
       sombre qui alourdissait le bas. Le personnage, ses
       chaussures, le sac, le soleil et la vallée sont tous entiers.

       2,62 est le rapport qui donne exactement cette bande :
       2,1618 / 0,825. Il n'a pas été choisi pour lui-même — c'est
       le cadrage qui le fixe, pas l'inverse.

       RÉSULTAT : 666 → 550 px sur un 1440 (-17 %), et le terrain
       sombre passe de 17 à 8 % du cadre. C'est ce second chiffre
       qui fait l'essentiel de l'impression panoramique.

       Pour revenir à la photographie entière : aspect-ratio
       2.162 / 1 et object-position center top sur .hero-image. */
    aspect-ratio:2.62 / 1;

    min-height:0;
    max-height:none;

    /* La respiration sous le hero est portée par la section qui
       suit, pas par cette marge : c'est elle qui fixe l'écart et
       elle seule, plutôt que deux valeurs à additionner. */
    margin-bottom:0;

    overflow:hidden;

    /* La navbar est collante (position:sticky) : elle occupe donc
       une place dans le flux, en haut de la page. On remonte le
       hero d'exactement cette hauteur pour que la photo passe
       DERRIÈRE elle, et on redonne la même valeur en padding pour
       que le contenu du hero ne se glisse pas dessous.

       La hauteur est mesurée et posée par js/script.js : elle
       change avec la largeur d'écran (la rangée de catégories
       n'apparaît qu'au-dessus de 1000 px). La valeur de repli sert
       uniquement au premier rendu, avant que le script ne passe. */
    margin-top:calc(-1 * var(--hauteur-navbar, 71px));

    padding-top:var(--hauteur-navbar, 71px);

    display:flex;

    /* Hauteur du fondu par lequel la photographie se dissout dans la
       page. Reprise plus bas à trois endroits qui doivent rester
       d'accord : le masque de l'image, l'extinction du voile du bas,
       et la réserve laissée sous le texte.

       En pixels et non en pourcentage : la même valeur sert de
       padding, et un padding en pourcentage se calcule sur la
       LARGEUR du bloc, pas sur sa hauteur — 14 % auraient donné
       200 px au lieu de 87.

       Ramené de 48 à 40 px le 07/09/2026 avec le nouveau cadrage.
       Le fondu valait 7,2 % d'un cadre de 666 px ; il en vaut 7,3 %
       d'un cadre de 550 px. La proportion est donc inchangée — ce
       qui compte ici, car les chaussures du personnage sont
       maintenant à 43 px du bord bas : à 48 px elles seraient
       entrées franchement dans la dissolution. */
    --fondu-bas:40px;

    /* Forme du voile du bas. Il tient sa pleine force jusqu'à
       --voile-palier, décroît, puis s'éteint à --voile-fin.

       Ces trois valeurs doivent couvrir le bloc de texte, dont la
       hauteur est fixe alors que celle du cadre ne l'est pas : sur
       téléphone le texte occupe une part bien plus grande, d'où des
       valeurs propres au petit écran plus bas. */
    --voile-palier:34%;
    --voile-degressif:52%;
    --voile-fin:70%;

    /* Intensité du voile du bas. Volontairement faible : la
       photographie s'assombrit déjà d'elle-même. Le petit écran la
       remonte, parce que son cadre étant deux fois plus court, le
       texte s'y trouve bien plus haut — dans une zone que l'image
       n'a pas encore assombrie. */
    --voile-force:.34;
    --voile-force-palier:.30;

}

.hero-image{

    position:absolute;

    inset:0;

    width:100%;

    height:100%;

    /* cover : aucune bande vide, et l'image n'est jamais
       déformée — c'est le cadrage qui s'adapte, pas l'image. */
    object-fit:cover;

    /* 40 % EN HAUTEUR — LA VALEUR QUI PLACE LA BANDE À 7 %.
       --------------------------------------------------------------
       object-position répartit le DÉBORDEMENT, pas l'image : avec un
       cadre à 2,62 pour une image à 2,1618, il déborde de
       1 - 2,1618/2,62 = 17,49 % de la hauteur mise à l'échelle.

       Pour que la bande commence à 7 % du fichier il faut donc
       cacher 7 % en haut, soit 0,07 / 0,1749 = 40 % du débordement.

       Autrement dit : 40 % du rognage se fait en haut sur le ciel,
       60 % en bas dans l'herbe. Le bas est bien sacrifié en
       priorité, comme demandé, mais pas en totalité — sans les 7 %
       du haut le cadre resterait trop épais pour être panoramique.

       Toucher à cette valeur sans recalculer aspect-ratio déplace
       la bande entière : les deux vont ensemble. */
    object-position:center 40%;

    /* Teinte neutre du thème pendant le chargement, plutôt qu'un
       blanc franc qui flasherait en mode sombre. Elle est portée par
       l'image et non par le cadre, sinon elle resterait visible dans
       la zone de fondu sous forme d'une bande légèrement plus claire
       que la page. */
    background:rgba(var(--ink-rgb),.04);

    /* LE BORD BAS SE DISSOUT DANS LA PAGE
       --------------------------------------------------------------
       Sans ça, la photographie s'arrête net sur une ligne horizontale
       et le hero se lit comme un bloc rapporté, posé sur le site, au
       lieu d'en être le début.

       Un masque plutôt qu'un dégradé de la couleur du fond : le
       masque rend l'image transparente, donc c'est la page elle-même
       qui apparaît. Aucune couleur à écrire, et le résultat suit
       automatiquement le thème — noir en sombre, crème en clair.
       Un dégradé opaque, lui, aurait demandé une valeur par thème.

       Même technique que les photos produit et les bandeaux
       défilants, où le même bord franc avait déjà été supprimé. */
    -webkit-mask-image:linear-gradient(to bottom,
        #000 calc(100% - var(--fondu-bas)),
        transparent 100%);

    mask-image:linear-gradient(to bottom,
        #000 calc(100% - var(--fondu-bas)),
        transparent 100%);

}

/* VOILES
   ------------------------------------------------------------------
   Aucune de ces valeurs n'est choisie à l'oeil : le cadrage et les
   dégradés ont été rejoués dans un canvas pour mesurer la luminance
   réellement obtenue sous chaque texte, puis quatre réglages ont été
   comparés avant de retenir celui-ci.

   Sans voile, la navbar est illisible : posée sur le ciel, son logo
   tombe à 1,03 de contraste. Il en faut donc, mais le moins
   possible — cette photographie vaut surtout par sa lumière.

   Deux couches seulement :

     · HAUT — assoit la navbar. Volontairement fort mais très court :
       pleine force jusqu'au bas de la navbar, puis éteint peu après.

       Ses paliers sont exprimés en multiples de --hauteur-navbar et
       non en pourcentages du cadre, parce que la navbar a une
       hauteur FIXE alors que le cadre, lui, change de proportion.
       En pourcentages, un voile réglé pour le bureau (navbar = 11 %
       de la hauteur) s'arrêtait trop tôt sur téléphone (navbar =
       22 %) : le menu et le logo y retombaient à 2,4 de contraste.

     · BAS — porte la marque et le bouton. Léger, parce que le
       premier plan est déjà sombre de lui-même (37 de luminance).

   Pas de voile latéral, contrairement à la photographie précédente :
   ici le bas à gauche est naturellement sombre, et la vallée n'a
   donc pas besoin d'être assombrie pour porter le texte.

   Résultat mesuré, en tenant compte de l'opacité réelle de chaque
   texte : plus rien sous 6,7 de contraste, contre 4,03 auparavant —
   c'était le texte d'invite de la recherche qui décrochait. Le prix
   payé est mesuré lui aussi : le ciel derrière la navbar descend de
   71 à 59, celui juste en dessous de 137 à 123. La vallée de gauche
   et le personnage ne sont pas touchés.

   Les voiles sont identiques dans les deux thèmes : ils se posent
   sur la photographie, qui elle ne change pas avec le thème. */

.hero::before{

    content:"";

    position:absolute;

    inset:0;

    pointer-events:none;

    background:linear-gradient(to bottom,
        rgba(10,10,10,.80),
        rgba(10,10,10,.62) var(--hauteur-navbar, 71px),
        rgba(10,10,10,.16) calc(var(--hauteur-navbar, 71px) * 1.8),
        transparent calc(var(--hauteur-navbar, 71px) * 2.7));

}

/* LE BAS : UNE EXTINCTION, PAS UN FONDU NOIR
   ------------------------------------------------------------------
   Le voile du bas était nettement trop appuyé : à .66 d'opacité, il
   ne prolongeait plus la photographie, il la remplaçait par du noir.

   Il est très allégé ici parce que la photographie n'en a plus
   besoin : son premier plan tombe de lui-même à 57, 45, 38 de
   luminance sur les trois dernières bandes. Du texte crème y tient
   déjà autour de 9:1 sans aucun voile. Ce qui reste ne sert qu'à
   garantir le pire cas et à accompagner la disparition.

   Il ne part pas du bord : il s'éteint AVANT, sur la même hauteur
   que le fondu de l'image. Sinon il continuerait de peindre un
   rectangle sombre par-dessus la partie dissoute — très visible en
   mode clair, où l'on verrait une bande grise flotter entre la
   photographie et la page crème. */

.hero::after{

    content:"";

    position:absolute;

    inset:0;

    pointer-events:none;

    background:linear-gradient(to top,
        transparent 0,
        rgba(10,10,10,var(--voile-force)) var(--fondu-bas),
        rgba(10,10,10,var(--voile-force-palier)) var(--voile-palier),
        rgba(10,10,10,calc(var(--voile-force-palier) / 3)) var(--voile-degressif),
        transparent var(--voile-fin));

}

/* ---------- Contenu superposé ---------- */

.hero-content{

    position:relative;

    z-index:2;

    width:100%;

    /* Aligné sur le bas du cadre : la marque et le bouton partagent
       la même ligne de base, comme un ours de magazine. */
    align-self:flex-end;

    display:flex;

    align-items:flex-end;

    justify-content:space-between;

    gap:40px;

    /* La réserve du bas vaut la hauteur du fondu plus une marge : le
       texte doit rester au-dessus de la zone où la photographie se
       dissout. En mode clair, la page est crème — du texte crème posé
       dans le fondu deviendrait illisible. */
    padding:0 42px calc(var(--fondu-bas) + 30px);

}

.hero-signature{

    /* Butée de sécurité : le personnage commence à 69,7 % de la
       largeur de l'IMAGE. Le cadre ayant le même rapport qu'elle,
       ce pourcentage vaut aussi pour le cadre — on s'arrête bien
       avant, à 58 %, pour laisser du vide entre le texte et lui. */
    max-width:58%;

}

/* La marque est une signature éditoriale posée dans la
   photographie, pas un titre de landing page. D'où une taille qui
   reste proche de celle d'un gros titre de section et non d'un
   lettrage plein écran, et un plafond bas : au-delà de 76 px elle
   commencerait à concurrencer le massif. */

.hero-wordmark{

    font-family:"Anton",sans-serif;

    font-size:clamp(38px,5.2vw,76px);

    line-height:1;

    letter-spacing:.06em;

    text-transform:uppercase;

    /* Fixe dans les deux thèmes : posé sur la photographie. */
    color:#F4F3EF;

    /* Une ombre très douce, pas un contour : elle sert seulement à
       décoller les lettres si l'image devait s'éclaircir. */
    text-shadow:0 2px 18px rgba(10,10,10,.45);

}

.hero-baseline{

    margin-top:14px;

    font-size:clamp(11px,1.05vw,13.5px);

    font-weight:500;

    letter-spacing:.28em;

    text-transform:uppercase;

    color:rgba(244,243,239,.86);

    text-shadow:0 1px 12px rgba(10,10,10,.5);

}

/* Volontairement discret : bordure fine et fond translucide
   plutôt qu'un aplat plein, pour qu'il se lise sans voler
   l'attention à la photographie. Son rôle est de lever un doute,
   pas de vendre. */

.hero-cta{

    flex-shrink:0;

    display:inline-flex;

    align-items:center;

    gap:12px;

    padding:14px 26px;

    border:1px solid rgba(244,243,239,.5);

    border-radius:999px;

    background:rgba(10,10,10,.28);

    -webkit-backdrop-filter:blur(6px);
    backdrop-filter:blur(6px);

    color:#F4F3EF;

    text-decoration:none;

    font-size:12px;

    font-weight:600;

    letter-spacing:.18em;

    text-transform:uppercase;

    white-space:nowrap;

    transition:var(--transition);

}

.hero-cta:hover{

    border-color:#F4F3EF;

    background:#F4F3EF;

    color:#0A0A0A;

}

.hero-cta-arrow{

    transition:transform .25s cubic-bezier(.4,0,.2,1);

}

.hero-cta:hover .hero-cta-arrow{

    transform:translateX(4px);

}

/* ---------- La navbar posée sur le hero ---------- */

/* Uniquement sur la page d'accueil, et uniquement tant qu'on n'a
   pas dépassé le hero : la navbar devient transparente et se fond
   dans le haut de la photographie.

   Plutôt que de réécrire la couleur de chacun de ses éléments, on
   redéclare ici les variables dont ils se servent déjà. Tout ce
   qu'elle contient — recherche, compte, panier, bascule de thème —
   suit automatiquement, dans les deux thèmes : ces éléments se
   lisent sur la photographie, qui elle ne change pas avec le thème.

   POURQUOI TOUT EST EN CRÈME PLEIN ICI
   ------------------------------------------------------------------
   Ailleurs sur le site, --grey et --grey-light servent à créer une
   hiérarchie : le texte secondaire est plus pâle que le principal.
   Sur une page, ça marche — le fond est un aplat uni.

   Sur une photographie, non. Le texte de recherche à 72 % d'opacité
   tombait à 4,03 de contraste, et le ciel étant nuageux, le fond
   varie sous chaque lettre. Un texte pâle et très interlettré y
   accroche mal, même à 5:1. On rend donc l'opacité pleine à tout le
   monde et on porte la hiérarchie par la taille et la graisse, pas
   par la transparence.

   L'ombre portée ne change pas le rapport de contraste mesuré, mais
   elle détache les lettres des nuages : c'est ce que le chiffre ne
   dit pas. */

body:has(.hero) .navbar:not(.navbar-opaque){

    --ink:#F4F3EF;
    --ink-rgb:244, 243, 239;
    --grey:#F4F3EF;
    --grey-light:#F4F3EF;
    --line:rgba(244, 243, 239, .34);

    background:transparent;

    -webkit-backdrop-filter:none;
    backdrop-filter:none;

    /* C'est ce trait qui faisait lire la navbar comme une bande
       posée SUR la photo. */
    border-bottom-color:transparent;

}

/* Le texte d'invite du champ de recherche ne suit aucune variable :
   il a sa propre couleur, héritée avec une opacité réduite. C'est
   lui qui était le moins lisible de toute la barre. */

body:has(.hero) .navbar:not(.navbar-opaque) .navbar-search-input::placeholder{

    color:#F4F3EF;

    opacity:1;

}

body:has(.hero) .navbar:not(.navbar-opaque) .navbar-top{

    text-shadow:0 1px 10px rgba(10, 10, 10, .55);

}

/* Les pictogrammes sont tracés, pas peints : une ombre de texte ne
   les atteint pas, il leur faut une ombre de filtre. */

body:has(.hero) .navbar:not(.navbar-opaque) .navbar-top svg{

    filter:drop-shadow(0 1px 6px rgba(10, 10, 10, .6));

}

/* Le champ de recherche s'appuyait sur un voile clair à 5 %,
   invisible sur un ciel clair. Assombri, il redevient un contenant
   et non un simple trait. */

body:has(.hero) .navbar:not(.navbar-opaque) .navbar-search{

    background:rgba(10, 10, 10, .28);

}

/* LE MENU N'APPARAÎT QU'AU DÉFILEMENT
   ------------------------------------------------------------------
   Sur la première image de l'accueil, la barre se réduit au strict
   nécessaire : la marque, la recherche, et les trois commandes de
   droite. Le bouton de menu n'a rien à y faire — tout ce qu'il ouvre
   est encore à venir dans la page.

   Il réapparaît en même temps que le fond de la navbar, dès qu'on
   quitte le hero.

   Le repli est complet — largeur nulle ET marge négative qui annule
   l'espacement de la grille — pour que la marque ne se décale pas de
   55 px d'un coup. Elle glisse sur 0,3 s, la même durée que le fond
   qui apparaît : les deux mouvements se lisent comme un seul.

   La hauteur de la navbar ne change pas, donc la page ne bouge pas
   d'un pixel. */

body:has(.hero) .navbar:not(.navbar-opaque) .menu-btn{

    width:0;

    margin-right:-28px;

    opacity:0;

    overflow:hidden;

    pointer-events:none;

}

/* LE PANNEAU DE RÉSULTATS EST UNE EXCEPTION
   ------------------------------------------------------------------
   Tout ce qui précède force le crème parce que ça se lit SUR LA
   PHOTOGRAPHIE. Le panneau de résultats, lui, est un aplat opaque
   posé par-dessus : il se lit sur lui-même, pas sur l'image.

   Comme il est un descendant de la navbar, il héritait quand même
   du crème forcé. En mode clair son fond suit le thème et devient
   crème lui aussi : on obtenait un panneau crème rempli de texte
   crème, donc totalement illisible. On lui rend donc la palette du
   thème.

   Les valeurs sont recopiées de :root et de [data-theme="light"] —
   si la palette du site change, ces deux blocs sont à suivre. */

html:not([data-theme="light"]) body:has(.hero) .navbar:not(.navbar-opaque) .navbar-search-results{

    --grey:#9D9B99;
    --grey-light:#BAB9B6;
    --line:rgba(244, 243, 239, .12);

}

[data-theme="light"] body:has(.hero) .navbar:not(.navbar-opaque) .navbar-search-results{

    --ink:#1C1C1C;
    --ink-rgb:28, 28, 28;
    --grey:#6A6766;
    --grey-light:#4A4746;
    --line:rgba(28, 28, 28, .13);

}

/* L'ombre portée de la navbar servait à détacher le texte des
   nuages ; sur ce panneau opaque elle ne fait que salir. */

body:has(.hero) .navbar:not(.navbar-opaque) .navbar-search-results{

    text-shadow:none;

}

/* Passé le hero, la navbar reprend son apparence normale (classe
   posée par js/script.js) — sinon elle flotterait, illisible,
   au-dessus du catalogue. */

.navbar{

    transition:background .3s ease, border-color .3s ease;

}

/* ---------- Tablette ---------- */

@media(max-width:1000px){

    .hero{

        /* Le même cadrage panoramique qu'en grand écran, et pour la
           même raison : entre 700 et 1000 px le cadre reste bien
           plus large que haut, donc le rognage est vertical et la
           bande 7 - 89,5 % s'applique à l'identique. Rien à
           recalculer, object-position est hérité.

           Un rapport propre à la tablette aurait déplacé la bande
           sans qu'aucun repère de l'image ne l'exige. */
        aspect-ratio:2.62 / 1;

        min-height:0;

        max-height:none;

        margin-bottom:0;

        /* Le cadre est plus court qu'en grand écran : le fondu se
           resserre avec lui, sinon il mangerait une part trop
           grande de la photo — et surtout les chaussures, qui sont
           désormais à 8 % du bord bas. */
        --fondu-bas:44px;

    }

    .hero-content{

        padding:0 28px calc(var(--fondu-bas) + 24px);

    }

}

/* ---------- Téléphone ---------- */

@media(max-width:700px){

    /* Le cadre devient beaucoup plus étroit que l'image (2,823) :
       le rognage passe de la hauteur à la largeur, et c'est le point
       d'ancrage qui décide de ce qu'on garde.

       Contre-intuitif mais vérifié : plus le cadre est HAUT, moins on
       voit de paysage. L'image est mise à l'échelle pour couvrir la
       hauteur, donc un cadre plus haut l'agrandit et en montre une
       tranche plus étroite. D'où une hauteur mobile contenue.

       Sur un écran de 390 px, il reste 43 % de la largeur d'origine.
       Ancrer à 63 % fait voir la tranche 36-79 % de l'image : le
       personnage (69,8-71,8 %) se retrouve à 79-84 % du cadre, donc
       bien à droite du texte, et le sommet du massif reste entier. */
    .hero{

        aspect-ratio:4 / 3;

        /* Le 4/3 seul ne suffit pas : sur un écran étroit il donne
           un cadre plus court que la navbar plus les textes, qui
           débordaient alors par le haut — la marque venait se poser
           sur celle de la navbar. On garantit donc la place. */
        min-height:calc(var(--hauteur-navbar, 69px) + 250px);

        max-height:none;

        margin-bottom:0;

        /* Cadre encore plus court : le fondu se resserre d'autant.
           Il reste assez long pour que la dissolution se lise, sans
           dévorer le premier plan. */
        --fondu-bas:52px;

        /* Le bloc de texte a la même hauteur qu'ailleurs mais le
           cadre fait moitié moins : il monte donc bien plus haut en
           proportion. Avec les valeurs du bureau, la marque sortait
           par le haut du voile et retombait à 2,18 de contraste.
           Le palier remonte d'autant. */
        --voile-palier:58%;
        --voile-degressif:72%;
        --voile-fin:86%;

        /* Avec l'intensité du bureau, la marque retombait à 3,27 de
           contraste : sur ce cadre court elle se pose dans une bande
           que l'image n'a pas encore assombrie. */
        --voile-force:.54;
        --voile-force-palier:.50;

    }

    .hero-image{

        /* 63 % en largeur : c'est le réglage d'origine, et il reste
           juste — sur téléphone le cadre est bien plus HAUT que
           l'image, donc le rognage est horizontal et la hauteur
           passe entière. Ciel, crête, personnage et chaussures
           sont tous montrés ; ce sont le soleil et la vallée de
           gauche qui sortent du cadre.
           En hauteur, on passe de « bottom » à « top » : sans
           rognage vertical le réglage ne sert à rien aujourd'hui,
           mais si un écran très large et très court venait à
           inverser le rapport, la coupe se ferait dans l'herbe et
           non sur la crête. */
        object-position:63% top;

    }

    /* En pleine largeur, la marque et le bouton ne peuvent plus se
       partager une ligne : le bouton passe dessous, à gauche comme
       le reste. La butée de largeur n'a plus lieu d'être — le texte
       s'appuie sur le voile du bas, qui est franc. */
    .hero-content{

        flex-direction:column;

        align-items:flex-start;

        gap:22px;

        padding:0 20px calc(var(--fondu-bas) + 18px);

    }

    .hero-signature{

        max-width:100%;

    }

    .hero-wordmark{

        font-size:clamp(30px,11vw,52px);

    }

    .hero-baseline{

        margin-top:10px;

        font-size:var(--t-micro);

        letter-spacing:.16em;

    }

    /* Resserré : à pleine largeur d'écran, l'interlettrage large du
       bureau étirait le bouton jusqu'à frôler les deux bords, ce
       qui lui donnait le poids d'un bouton commercial. */
    .hero-cta{

        padding:12px 20px;

        gap:10px;

        font-size:11px;

        letter-spacing:.12em;

    }

}


/* =======================================================
   ESPACE CLIENT — MON ARKWER
   (compte.html, compte-commandes.html, compte-commande.html,
    compte-favoris.html, compte-profil.html,
    compte-preferences.html)

   Une section à part entière, pas un panneau greffé sur le
   site public. D'où l'en-tête allégé : ni recherche, ni
   panier, ni menu catalogue. Une fois connecté, le client
   n'est plus en train d'acheter — il consulte. Lui laisser
   la barre d'achat sous les yeux brouillerait les deux.

   Le vocabulaire visuel reste celui du site : mêmes
   variables, même Anton pour les titres, mêmes filets à un
   pixel. Rien ici n'invente une seconde identité.
======================================================= */


/* -------- En-tête de section -------- */


/* Le retour au site marchand. Volontairement discret : il
   est toujours accessible, jamais insistant. */
.compte-retour{

    display:inline-flex;
    align-items:center;
    gap:.45rem;
    font-size:.85rem;
    color:var(--grey-light);
    text-decoration:none;
    transition:color var(--transition);

}

.compte-retour:hover{ color:var(--ink); }


/* -------- Charpente de page -------- */

.compte-page{

    max-width:1180px;
    margin:0 auto;
    padding:2.6rem 1.5rem 5rem;

}

.compte-titre{

    font-family:'Anton', sans-serif;
    font-size:clamp(2rem, 5vw, 3rem);
    letter-spacing:.04em;
    text-transform:uppercase;
    line-height:1;
    margin:0;

}

.compte-bonjour{

    color:var(--grey-light);
    font-size:1.05rem;
    margin:.7rem 0 0;

}


/* L'ancienneté du compte, sous le bonjour de l'Aperçu.

   Volontairement minuscule : c'est une preuve d'appartenance,
   pas une information dont on a besoin. Elle n'apparaît que si
   la session porte réellement la date — voir
   compteIdentiteEntete, qui ne fabrique aucun repli. */
.compte-identite-ligne{

    color:var(--grey);
    font-size:.82rem;
    letter-spacing:.02em;
    margin:.85rem 0 0;

}

.compte-entete{

    padding-bottom:1.8rem;
    border-bottom:1px solid var(--line);
    margin-bottom:2rem;

}


/* -------- Coquille : sidebar persistante + contenu --------

   Une tuile latérale plutôt qu'une rangée d'onglets en haut de
   page : l'identité et la navigation restent sous les yeux quel
   que soit le défilement du contenu, sur chaque page du compte.
   C'est ce qui porte le sentiment d'espace personnel — pas
   seulement l'Aperçu, qui n'est qu'une page parmi d'autres.

   Sur petit écran, la colonne redevient une bande horizontale
   défilante (voir le responsive plus bas) : même structure,
   pas un second menu à maintenir. */

/* Le nom du compte, en tête de la colonne. Ce n'est plus une
   salutation (elle est passée dans le titre de l'Aperçu, où
   elle n'est dite qu'une fois) mais une étiquette : de quel
   compte s'agit-il. */

/* L'adresse sous le nom. Le filet de séparation lui revient
   alors — sinon il passerait ENTRE le nom et l'email, qui
   forment un même bloc d'identité. */

/* Un trait et un poids de texte suffisent à marquer la page
   courante — pas de pastille pleine ni de fond coloré, qui
   pèseraient trop pour une liste qui reste sous les yeux en
   permanence. */

/* Préférences reste une rubrique réelle, mais secondaire aux
   quatre premières : un filet au-dessus la détache légèrement
   plutôt que de l'aligner comme un cinquième onglet de même
   poids. Modificateur posé sur le lien lui-même, pas sur un
   conteneur : la nav reste une liste plate, en ligne comme en
   colonne, sans un niveau d'imbrication qui compliquerait le
   passage colonne → ligne au responsive. */

@media (max-width:860px){

    /* En bande horizontale, le filet sous l'identité doublerait
       la séparation déjà faite par les pastilles de navigation. */

    /* La colonne redevient la bande défilante déjà éprouvée
       sur le reste du site pour ce genre de liste courte. */

    /* Même logique que .checkout-button : --ink s'inverse
       correctement par thème, --white non (voir plus haut). */

    /* En colonne, le filet se pose au-dessus ; en ligne, il n'y
       a pas de « au-dessus » — la séparation redevient un trait
       vertical avant la pastille, dans la même bande défilante. */

}


/* -------- Blocs -------- */

.compte-bloc{ margin-bottom:3.2rem; }

/* EN-TÊTE DE BLOC = EN-TÊTE DE SECTION (chantier système des
   sections, 15/09/2026). Même composition que les sections du
   site : titre et action centrés sur une ligne, écart titre →
   grille de 12 à 16 px (il était de 19). Sur téléphone, un titre
   long ne se laisse plus casser en deux lignes par son action
   (« RÉCEMMENT / CONSULTÉS », flèche renvoyée à la ligne) :
   l'action passe dessous. */
.compte-bloc-tete{

    display:flex;
    flex-wrap:wrap;
    align-items:center;
    justify-content:space-between;
    column-gap:1rem;
    row-gap:8px;
    margin-bottom:clamp(12px, 1.2vw, 16px);

}

.compte-bloc-titre{

    font-family:'Anton', sans-serif;
    font-size:1.15rem;
    line-height:1.1;
    letter-spacing:.1em;
    text-transform:uppercase;
    margin:0;

}

.compte-bloc-lien{

    font-size:.82rem;
    color:var(--grey);
    text-decoration:none;
    transition:color var(--transition);

}

.compte-bloc-lien:hover{ color:var(--ink); }

/* Cible d'appui (chantier sections V1) : le « Tout voir » des
   favoris mesurait 18 px de haut. Il reste une ligne de texte,
   mais sa zone d'appui atteint 44 px ; les marges négatives
   rendent la hauteur gagnée, le bloc ne bouge pas.
   :not(.hidden) — .hidden n'est pas !important : sans ce filtre,
   display:inline-flex afficherait un lien que compte.js masque. */
.compte-bloc-tete .compte-bloc-lien:not(.hidden){
    display:inline-flex;
    align-items:center;
    min-height:44px;
    margin-block:-13px;
}

/* L'ACTION D'EN-TÊTE EST CELLE DES SECTIONS : capitales DM Sans,
   encre pleine, libellé souligné dès le repos, flèche muette.
   Elle était un texte gris de 13 px, flèche comprise, sans rien
   qui la désigne comme un lien sans survol. compte.html porte le
   balisage commun (.section-action) ; le lien que fabrique
   compte.js pour l'état « Votre première pièce vous attend » n'a
   pas de span de libellé : le soulignement est porté par le lien.
   Les autres .compte-bloc-lien (suivi de colis, codes) ne sont pas
   dans un en-tête et gardent leur forme. */
.compte-bloc-tete .compte-bloc-lien{
    gap:10px;
    font-family:"DM Sans", sans-serif;
    font-size:12px;
    font-weight:600;
    line-height:1.2;
    letter-spacing:.1em;
    text-transform:uppercase;
    white-space:nowrap;
    color:var(--ink);
}

.compte-bloc-tete .compte-bloc-lien:not(:has(.section-action-texte)){
    text-decoration:underline;
    text-decoration-thickness:1px;
    text-underline-offset:5px;
    text-decoration-color:rgba(var(--ink-rgb), .35);
}

.compte-bloc-tete .compte-bloc-lien:focus-visible{
    outline:1px solid var(--ink);
    outline-offset:2px;
}

.compte-bloc-tete .compte-bloc-lien:focus-visible .section-action-texte{ text-decoration-color:currentColor; }
.compte-bloc-tete .compte-bloc-lien:focus-visible .section-action-fleche{ transform:translateX(4px); }

@media (hover: hover) and (pointer: fine){
    .compte-bloc-tete .compte-bloc-lien:hover .section-action-texte{ text-decoration-color:currentColor; }
    .compte-bloc-tete .compte-bloc-lien:hover .section-action-fleche{ transform:translateX(4px); }
}

@media (max-width: 560px){
    .compte-bloc-tete .compte-bloc-lien{
        gap:8px;
        font-size:11px;
        letter-spacing:.05em;
    }
}


/* -------- Carte de commande -------- */

.compte-commande-carte{

    display:flex;
    gap:1.2rem;
    align-items:center;
    padding:1.1rem;
    border:1px solid var(--line);
    border-radius:var(--radius);
    text-decoration:none;
    color:inherit;
    transition:border-color var(--transition);

}

.compte-commande-carte + .compte-commande-carte{ margin-top:.8rem; }

.compte-commande-carte:hover{ border-color:rgba(var(--ink-rgb), .28); }

.compte-commande-vignette{

    flex:0 0 74px;
    width:74px;
    height:74px;
    border-radius:12px;
    overflow:hidden;
    background:var(--card);
    display:flex;
    align-items:center;
    justify-content:center;

}

.compte-commande-vignette img{

    width:100%;
    height:100%;
    object-fit:contain;

}

.compte-commande-infos{ flex:1 1 auto; min-width:0; }

.compte-commande-num{

    font-family:'Anton', sans-serif;
    font-size:.9rem;
    letter-spacing:.09em;
    margin:0 0 .25rem;

}

.compte-commande-meta{

    font-size:.82rem;
    color:var(--grey);
    margin:0;

}

.compte-commande-montant{

    font-size:.95rem;
    white-space:nowrap;

}


/* -------- Pastille de statut -------- */

.compte-statut{

    display:inline-block;
    font-size:.7rem;
    letter-spacing:.1em;
    text-transform:uppercase;
    padding:.24rem .6rem;
    border-radius:999px;
    border:1px solid var(--line);
    color:var(--grey-light);
    margin-top:.4rem;

}

.compte-statut.en-cours{

    color:var(--gold);
    border-color:rgba(var(--gold-rgb), .4);

}

.compte-statut.terminee{

    color:var(--ink);
    border-color:rgba(var(--ink-rgb), .3);

}

.compte-statut.arretee{

    color:var(--grey);
    border-color:var(--line);

}


/* -------- Chronologie de suivi -------- */

/* Chaque étape est soit franchie, soit à venir. Aucune
   position intermédiaire : une étape que la base ne déclare
   pas atteinte reste éteinte, même si elle paraît probable.
   C'est la règle de ce composant. */
.compte-timeline{

    list-style:none;
    margin:0;
    padding:0;

}

.compte-etape{

    position:relative;
    padding:0 0 1.7rem 2.1rem;

}

.compte-etape:last-child{ padding-bottom:0; }

/* Le point de l'étape. */
.compte-etape::before{

    content:'';
    position:absolute;
    left:0;
    top:.34rem;
    width:11px;
    height:11px;
    border-radius:50%;
    border:1px solid var(--line);
    background:var(--black);

}

/* Le trait qui relie une étape à la suivante. */
.compte-etape::after{

    content:'';
    position:absolute;
    left:5px;
    top:1.1rem;
    bottom:.1rem;
    width:1px;
    background:var(--line);

}

.compte-etape:last-child::after{ display:none; }

.compte-etape.franchie::before{

    background:var(--gold);
    border-color:var(--gold);

}

.compte-etape.franchie::after{ background:rgba(var(--gold-rgb), .45); }

.compte-etape-nom{

    font-size:.92rem;
    color:var(--grey);
    margin:0;

}

.compte-etape.franchie .compte-etape-nom{ color:var(--ink); }

.compte-etape.actuelle .compte-etape-nom{

    color:var(--gold);
    font-weight:600;

}

.compte-etape-date{

    font-size:.76rem;
    color:var(--grey);
    margin:.2rem 0 0;

}


/* -------- Détail d'une commande -------- */

.compte-detail{

    display:grid;
    grid-template-columns:minmax(0, 1.35fr) minmax(0, 1fr);
    gap:2.6rem;
    align-items:start;

}

.compte-encart{

    border:1px solid var(--line);
    border-radius:var(--radius);
    padding:1.4rem;

}

.compte-encart + .compte-encart{ margin-top:1.1rem; }

.compte-encart-titre{

    font-family:'Anton', sans-serif;
    font-size:.86rem;
    letter-spacing:.12em;
    text-transform:uppercase;
    color:var(--grey-light);
    margin:0 0 .9rem;

}

.compte-ligne{

    display:flex;
    justify-content:space-between;
    gap:1rem;
    font-size:.88rem;
    padding:.4rem 0;

}

.compte-ligne dt{ color:var(--grey); margin:0; }
.compte-ligne dd{ margin:0; text-align:right; }

.compte-adresse{

    font-size:.88rem;
    line-height:1.65;
    color:var(--grey-light);
    margin:0;
    font-style:normal;

}


/* -------- Formulaire de profil -------- */

.compte-champ{ margin-bottom:1.2rem; }

.compte-champ label{

    display:block;
    font-size:.78rem;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--grey);
    margin-bottom:.4rem;

}

.compte-champ input{

    width:100%;
    padding:.75rem .9rem;
    background:transparent;
    border:1px solid var(--line);
    border-radius:10px;
    color:var(--ink);
    font-family:inherit;
    font-size:.92rem;

}

.compte-champ input:focus{

    outline:none;
    border-color:rgba(var(--ink-rgb), .35);

}

/* Un champ que le client ne peut pas modifier depuis ici.
   Il reste lisible : le griser jusqu'à l'illisibilité
   punirait le lecteur d'une contrainte technique. */
.compte-champ input[readonly]{

    color:var(--grey-light);
    background:rgba(var(--ink-rgb), .03);
    cursor:default;

}

.compte-champ-note{

    font-size:.78rem;
    color:var(--grey);
    margin:.4rem 0 0;
    line-height:1.55;

}


/* -------- États vides et messages -------- */

.compte-vide{

    text-align:center;
    padding:3.4rem 1.5rem;
    border:1px dashed var(--line);
    border-radius:var(--radius);

}

.compte-vide-titre{

    font-family:'Anton', sans-serif;
    font-size:1.05rem;
    letter-spacing:.1em;
    text-transform:uppercase;
    margin:0 0 .6rem;

}

.compte-vide-texte{

    color:var(--grey);
    font-size:.9rem;
    max-width:34rem;
    margin:0 auto 1.4rem;
    line-height:1.7;

}

/* Encart signalant une fonction annoncée mais pas encore
   ouverte. Il dit ce qui manque plutôt que de faire semblant
   d'exister : un bouton qui ne fait rien coûte plus cher en
   confiance qu'une phrase honnête. */
.compte-bientot{

    border:1px solid var(--line);
    border-left:2px solid rgba(var(--gold-rgb), .5);
    border-radius:10px;
    padding:1rem 1.2rem;
    font-size:.86rem;
    color:var(--grey-light);
    line-height:1.65;

}


/* -------- Écran de connexion de la section -------- */

/* Marge basse plus courte que la haute : sur la page panier,
   ce bloc n'est pas seul — le panier suit juste en dessous, et
   doit rester visiblement rattaché à lui. */
.compte-garde{

    max-width:32rem;
    margin:5rem auto 3.4rem;
    padding:0 1.5rem;
    text-align:center;

}


/* -------- Écran d'accès non connecté --------

   Deux actions, deux traitements, un seul rang de lecture.
   « Se connecter » est plein, « S'inscrire » est contourné :
   côte à côte, même hauteur, même position — le second reste
   immédiatement identifiable sans faire concurrence au premier.

   Chacune se nomme telle quelle. La version précédente cachait
   l'inscription derrière un séparateur (« Pas encore chez
   ARKWER ? ») : c'est exactement la devinette qu'on ne veut
   pas — le visiteur doit reconnaître son cas au libellé.

   Sur la page panier, ce bloc n'est pas une impasse : le
   panier reste rendu juste en dessous, d'où la disparition de
   l'ancienne échappatoire vers cart.html, qui n'a plus d'objet
   (voir .compte-panier-invite plus bas). */

.compte-garde-hook{

    max-width:24rem;
    margin:0 auto .9rem;
    font-family:'Anton', sans-serif;
    font-size:clamp(1.5rem, 4.2vw, 2.15rem);
    line-height:1.18;
    letter-spacing:.01em;
    text-transform:uppercase;

}

.compte-garde-texte{

    max-width:26rem;
    margin-bottom:2rem;

}

.compte-garde-actions{

    display:flex;
    flex-wrap:wrap;
    justify-content:center;
    gap:.75rem;

}

/* .checkout-button fournit deja le remplissage sombre/clair
   correctement inverse par theme (voir sa definition) — ici on
   ne corrige que la forme : largeur et hauteur au contenu, pas
   pleine largeur, comme .compte-hero-bouton le fait deja pour
   le meme bouton ailleurs dans l'espace client. min-height
   garantit les 44px de cible tactile meme si le texte est court. */
.compte-garde-cta{

    display:inline-flex;
    align-items:center;
    justify-content:center;
    gap:.5rem;
    width:auto;
    height:auto;
    min-height:44px;
    padding:.85rem 1.8rem;

}

/* Secondaire mais jamais un lien perdu : un vrai bouton
   contourne, meme langage d'interaction que le CTA principal
   (meme transition, meme duree) mais sans remplissage — c'est
   ce qui le place derriere "Se connecter" sans le cacher.
   Taille de texte et interlettrage repris de .checkout-button :
   posés cote a cote, les deux doivent se lire comme une paire. */
.compte-garde-creer{

    display:inline-flex;
    align-items:center;
    justify-content:center;
    gap:.5rem;
    min-height:44px;
    padding:.85rem 1.6rem;
    background:none;
    border:1px solid var(--line);
    color:var(--ink);
    font-family:inherit;
    font-size:11px;
    font-weight:600;
    letter-spacing:1.4px;
    text-transform:uppercase;
    cursor:pointer;
    transition:border-color var(--transition), background var(--transition);

}

.compte-garde-creer:hover{

    border-color:rgba(var(--ink-rgb), .4);
    background:rgba(var(--ink-rgb), .04);

}


/* -------- Le panier, sous l'invitation --------

   Posée sur <body> par compteExigerConnexion quand personne
   n'est connecté sur compte-panier.html.

   Le panier est déjà rendu par js/cart-page.js, qui n'a jamais
   demandé de session : rien à recalculer ici. Il n'y a que la
   coquille de l'espace client à retirer autour de lui — la
   sidebar et le titre de page n'ont aucun sens sans compte,
   et le titre ferait de surcroît un second <h1> derrière celui
   du bloc d'accès. */

/* Le panier de l'espace client n'a pas de titre dans sa rangée
   (l'en-tête de page le porte) : « Tout sélectionner » y reste
   seul et doit donc aller chercher lui-même le bord droit, que
   space-between lui donnait tant qu'il avait un voisin. */
.compte-page .cart-title-row .select-all-label{ margin-left:auto; }


/* Le panier occupe désormais le haut de l'écran : il garde donc
   son titre de page. Sa marge basse se resserre pour que le
   filet du bloc de connexion vienne se poser juste dessous
   plutôt que de flotter à cinq rem de tout. */
.compte-panier-invite .compte-page{ padding-bottom:2.4rem; }


/* -------- Se connecter, en second --------

   Même bloc que sur les six autres pages du compte, mais lu
   dans un tout autre contexte : ici il ne porte plus l'écran,
   il le clôt. D'où la mise en page opposée — aligné à gauche
   dans la colonne du panier, titre à la taille d'un titre de
   section, et non centré au milieu d'une page vide.

   La différence n'est pas décorative : centré et en grand, un
   bloc de connexion posé sous un panier prend l'allure d'une
   fenêtre promotionnelle. Aligné sur le contenu, il se lit
   pour ce qu'il est — une commodité offerte, pas un péage. */

.compte-garde-secondaire{

    max-width:1180px;
    margin:0 auto;
    padding:2.4rem 1.5rem 5rem;
    text-align:left;
    border-top:1px solid var(--line);

}

.compte-garde-secondaire .compte-garde-hook{

    max-width:none;
    margin:0 0 .5rem;
    font-size:1.15rem;
    letter-spacing:.1em;

}

.compte-garde-secondaire .compte-garde-texte{

    max-width:32rem;
    margin-left:0;
    margin-right:0;
    margin-bottom:1.4rem;

}

.compte-garde-secondaire .compte-garde-actions{ justify-content:flex-start; }

/* .checkout-button souleve le bouton de 2px au survol. Sur ces
   deux actions, ce deplacement se retire quand le systeme le
   demande — le survol reste parfaitement lisible sans lui, le
   fond et la bordure changeant de toute facon. */
@media (prefers-reduced-motion: reduce){

    .compte-garde-cta,
    .compte-garde-creer{ transition:none; }

    .compte-garde-cta:hover,
    .compte-garde-cta:active{ transform:none; }

}

@media (max-width:480px){

    .compte-garde-hook{ font-size:1.4rem; }

    /* Les deux actions passent l'une sous l'autre plutôt que de
       se serrer : chacune garde une cible tactile pleine largeur. */
    .compte-garde-actions{ flex-direction:column; }

}


/* -------- Espacements de l'espace client --------

   Ces quatre règles remplacent des attributs style="" que la
   CSP du site bloque : script-src et style-src n'autorisent
   que les fichiers, jamais le HTML en ligne. Un style écrit
   dans la balise n'est pas seulement mal rangé ici — il ne
   s'applique tout simplement pas. */

/* Un encart qui suit autre chose qu'un encart (une liste,
   une grille) et a besoin du même écart. */
.compte-encart-suite{ margin-top:1.1rem; }

/* Le titre d'une page de détail, sous son lien de retour. */
.compte-titre-sous-retour{ margin-top:.9rem; }

/* Une note qui ouvre un encart : le titre au-dessus porte
   déjà l'écart, la note n'en rajoute pas. */
.compte-encart-titre + .compte-champ-note{ margin-top:0; }

/* Une note de bas de page, détachée du contenu. */
.compte-note-bas{ margin-top:2rem; }


/* -------- Responsive -------- */

@media (max-width:860px){

    .compte-detail{ grid-template-columns:1fr; gap:1.8rem; }

}

@media (max-width:640px){

    .compte-page{ padding:1.8rem 1.1rem 4rem; }

    .compte-commande-carte{

        gap:.9rem;
        padding:.9rem;

    }

    .compte-commande-vignette{

        flex-basis:58px;
        width:58px;
        height:58px;

    }

    .compte-commande-montant{

        align-self:flex-start;
        font-size:.88rem;

    }

    /* La bande de navigation déborde volontairement du cadre
       de lecture : elle signale ainsi qu'elle se fait défiler. */

}


/* -------- Accès au compte depuis le site public --------

   Un prénom seul posé dans la barre ne dit pas qu'on peut
   cliquer dessus. L'icône le dit : c'est elle qui transforme
   une étiquette en porte d'entrée. Le contour discret suffit
   à marquer la zone cliquable sans alourdir la barre. */

.navbar-account-link.logged-in{

    display:inline-flex;
    align-items:center;
    gap:.5rem;
    padding:.34rem .8rem .34rem .55rem;
    border:1px solid var(--line);
    border-radius:999px;
    max-width:11rem;
    transition:border-color var(--transition), color var(--transition);

}

.navbar-account-link.logged-in:hover{

    color:var(--ink);
    border-color:rgba(var(--ink-rgb), .32);

}

.navbar-account-icone{

    flex:0 0 auto;
    width:17px;
    height:17px;

}

/* Un nom Google peut être long : on le tronque plutôt que de
   laisser la barre s'étirer. */
.navbar-account-nom{

    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;

}


/* -------- En-tête de l'espace client --------

   L'email est une information de contrôle — « suis-je sur le
   bon compte ? » — pas un titre. Il reste lisible, en retrait,
   et disparaît quand la barre se resserre. */

/* La déconnexion n'est pas une action courante : elle est
   accessible, jamais mise en avant. */


/* -------- La commande en cours, en tête de page --------

   Deux colonnes : la pièce et son suivi côte à côte. C'est la
   seule question d'un client qui revient — « où en est ma
   commande ? » — donc elle occupe la première place et se lit
   sans défilement. */

.compte-hero{

    display:grid;
    grid-template-columns:minmax(0, 1.25fr) minmax(0, 1fr);
    gap:1.1rem;
    align-items:start;

}

.compte-hero-carte{

    display:flex;
    gap:1.5rem;
    padding:1.5rem;
    border:1px solid var(--line);
    border-radius:var(--radius);

}

.compte-hero-image{

    flex:0 0 132px;
    width:132px;
    height:150px;
    border-radius:12px;
    overflow:hidden;
    background:var(--card);
    display:flex;
    align-items:center;
    justify-content:center;

}

.compte-hero-image img{

    width:100%;
    height:100%;
    object-fit:contain;

}

.compte-hero-infos{

    flex:1 1 auto;
    min-width:0;
    display:flex;
    flex-direction:column;
    align-items:flex-start;
    gap:.32rem;

}

.compte-hero-num{

    font-family:'Anton', sans-serif;
    font-size:1rem;
    letter-spacing:.1em;
    margin:0;

}

.compte-hero-produit{

    font-size:.95rem;
    color:var(--grey-light);
    margin:0;

}

.compte-hero-montant{

    font-size:1.15rem;
    margin:.3rem 0 0;

}

/* .checkout-button est taillé pour le tunnel d'achat : pleine
   largeur, 56 px de haut. Posé ici sur un <a>, il gardait cette
   hauteur sans centrer son texte — un grand bloc vide surmonté
   d'un libellé. On le ramène aux proportions d'un bouton
   d'action : largeur du contenu, hauteur normale, texte centré. */

.compte-hero-bouton{

    display:inline-flex;
    align-items:center;
    gap:.5rem;
    width:auto;
    height:auto;
    margin-top:1.1rem;
    padding:.7rem 1.3rem;
    text-decoration:none;

}


/* -------- Commandes récentes, en deux colonnes --------

   Un résumé, pas l'historique : quatre commandes au plus,
   posées côte à côte pour tenir dans un regard. Une seule
   colonne étirée sur toute la largeur donnerait exactement
   l'impression de la page « Mes commandes ». */

.compte-liste-double{

    display:grid;
    grid-template-columns:repeat(2, minmax(0, 1fr));
    gap:.8rem;

}

/* Dans une grille, la marge d'empilement n'a plus lieu d'être. */
.compte-liste-double .compte-commande-carte + .compte-commande-carte{ margin-top:0; }


/* -------- Panier dans l'espace client --------

   Aucune règle de mise en page ici : la page reprend telle
   quelle la structure de cart.html, donc les styles .cart-*
   du tunnel d'achat s'appliquent sans retouche. Seul l'écart
   avec la barre de navigation au-dessus est à poser. */

.compte-page .cart-title-row{ margin-top:.4rem; }


/* -------- Grilles de pièces dans l'espace client --------

   Rien à redéfinir : les cartes viennent du catalogue
   (.products / .card) et héritent de sa cascade responsive,
   4 → 3 → 2 → 1 colonne selon la largeur.

   Une première version imposait ici repeat(auto-fill, 210px).
   Résultat : cinq colonnes pour quatre pièces, donc un vide
   à droite de chaque rangée. Les blocs de l'espace client
   montrent quatre pièces au plus — exactement la grille du
   site. La contrarier ne pouvait que la désaligner. */


/* -------- États vides -------- */

/* .compte-vide reste réservé aux ERREURS — « Chargement
   impossible », « Commande introuvable ». Un encadré centré y
   est juste : c'est un événement, il doit arrêter l'œil.

   Une rubrique vide n'est pas un événement. Elle utilise
   .compte-etat-ligne ci-dessus. La règle
   « .compte-vide + .compte-vide-grille » qui suivait ici
   accompagnait l'ancien état vide encadré ; plus rien ne porte
   ces classes ensemble, elle est retirée. */


/* SUR MOBILE, LES PIÈCES SUGGÉRÉES DÉFILENT

   À une colonne, les quatre suggestions d'un compte vide
   faisaient plus de deux mille pixels de haut. Elles étaient
   passées à deux colonnes — des mini-cartes de 160 px, les
   seules du site. Elles prennent désormais le rail de la
   Sélection ARKWER : une rangée qui glisse, des cartes à la
   taille du reste du site, et la hauteur d'une seule carte.
   Voir « LE RAIL », en fin de fichier. */

/* LA LIGNE D'ÉTAT D'UNE RUBRIQUE VIDE

   Elle remplace le contenu d'une rubrique, sous son titre, et
   ne remplace jamais la rubrique elle-même : « Commandes »
   reste écrit, et cette ligne répond. C'est la différence
   entre une page qui informe et une page qui se contente de
   ne rien afficher.

   Deux niveaux dans un seul paragraphe : le fait d'abord, à
   l'encre du texte courant parce que c'est une réponse et non
   une excuse ; l'explication ensuite, en retrait. Pas
   d'encadré, pas d'icône, pas de bouton — un état vide qui
   s'habille attire l'œil bien plus que ce qui compte autour.

   Le retrait à gauche l'aligne sur les cartes de commande, qui
   occupent la même place lorsqu'il y en a. */
.compte-etat-ligne{

    margin:0;
    padding:1.1rem 0 1.1rem 1.1rem;
    border-left:1px solid var(--line);
    font-size:.92rem;
    color:var(--ink);

}

.compte-etat-ligne span{

    display:block;
    margin-top:.35rem;
    font-size:.82rem;
    color:var(--grey);

}


/* LA DÉCOUVERTE EST EN DESSOUS, ET SE VOIT COMME TELLE

   Tout ce qui précède appartient au client ; cette section est
   une proposition de la maison. Un filet et une respiration
   suffisent à marquer le passage — sans quoi une grille de
   pièces posée à la suite des favoris se lit comme la suite
   des favoris.

   C'est la seule concession commerciale de l'écran, et elle
   est toujours la dernière. */
.compte-bloc-decouverte{

    margin-top:4rem;
    padding-top:2.6rem;
    border-top:1px solid var(--line);

}

/* -------- Responsive -------- */

@media (max-width:980px){

    .compte-hero{ grid-template-columns:1fr; }

}

@media (max-width:760px){

    .compte-liste-double{ grid-template-columns:1fr; }

    /* L'email en double avec le nom de la barre publique : sur
       petit écran, la place manque et il n'apporte rien de plus
       que la page « Mon profil ». */

}

@media (max-width:640px){

    .compte-hero-carte{

        gap:1rem;
        padding:1.1rem;

    }

    .compte-hero-image{

        flex-basis:96px;
        width:96px;
        height:112px;

    }

    /* La barre de l'espace client débordait ici : ses trois
       groupes (marque, mention « Mon ARKWER », actions) faisaient
       467px de contenu pour 331px utiles, d'où un défilement
       horizontal sur toute la page.

       Ce qui part n'est pas choisi pour la place gagnée mais
       parce que c'est un doublon : « ← Retour à ARKWER » pointe
       sur index.html, exactement comme la marque ARKWER posée
       trois éléments plus à gauche, qui l'annonce déjà
       (aria-label="Accueil ARKWER"). À cette largeur, c'est elle
       qui joue ce rôle — la convention est universelle.

       Sélecteur volontairement ancré sur .navbar-top-actions :
       compte-commande.html réutilise .compte-retour comme fil
       d'Ariane vers « Mes commandes », lui bien réel, qui doit
       rester visible.

       La déconnexion suit l'email retiré plus haut pour la même
       raison : elle reste à un geste, dans la navigation de
       l'espace client et sur « Mon profil ». */
    /* « .compte-sortie » partageait cette règle ; la classe a disparu
       du site et sa suppression avait laissé le sélecteur orphelin,
       ce qui annulait la règle entière. */
    .navbar-top-actions .compte-retour{ display:none; }

}

/* Sous 360px (iPhone SE et assimilés), la marque, la mention et
   le sélecteur de thème ne tiennent toujours pas ensemble. La
   mention part à son tour, pour la même raison que les deux
   précédentes : le titre de la page dit déjà où l'on est. */
@media (max-width:359px){

}


/* -------- Panier public : invitation à se connecter --------

   Un encadré discret, jamais un mur : le panier et le paiement
   fonctionnent sans compte. Se connecter n'ouvre qu'au suivi et
   au rattachement à Mon ARKWER. */

.cart-login-invite{

    display:flex;
    align-items:center;
    gap:1rem;
    margin:1.4rem 0 .4rem;
    padding:1rem 1.2rem;
    border:1px solid var(--line);
    border-radius:14px;

}

.cart-login-invite.hidden{ display:none; }

.cart-login-invite-icone{

    flex-shrink:0;
    width:22px;
    height:22px;
    color:var(--grey);

}

.cart-login-invite-texte{ flex:1; }

.cart-login-invite-titre{

    margin:0 0 .2rem;
    font-size:.95rem;
    font-weight:600;
    color:var(--ink);

}

.cart-login-invite-note{

    margin:0;
    font-size:.82rem;
    line-height:1.45;
    color:var(--grey);

}

.cart-login-invite-bouton{

    flex-shrink:0;
    padding:.6rem 1.2rem;
    border:1px solid var(--ink);
    border-radius:999px;
    background:none;
    color:var(--ink);
    font-family:inherit;
    font-size:.8rem;
    font-weight:600;
    letter-spacing:.06em;
    text-transform:uppercase;
    cursor:pointer;
    transition:background var(--transition), color var(--transition);

}

.cart-login-invite-bouton:hover{

    background:var(--ink);
    color:var(--accent-ink);

}

@media (max-width:640px){

    .cart-login-invite{

        flex-wrap:wrap;
        gap:.7rem;

    }

    .cart-login-invite-bouton{ width:100%; }

}


/* -------- Panier vide : une porte, pas un mur --------

   .cart-empty est une colonne flex alignée à gauche : sans
   align-self, la grille se réduirait à la largeur de son
   contenu au lieu d'occuper la ligne. */

.cart-empty-suggestion{

    align-self:stretch;
    width:100%;
    margin-top:2.4rem;
    padding-top:2.2rem;
    border-top:1px solid var(--line);

}

/* .cart-empty-titre n'a plus de style à lui (chantier sections
   V1) : il est posé dans un en-tête lié, avec son action, et
   prend l'échelle des titres secondaires —
   .category-header-secondaire, dans « EN-TÊTE DE RAYON ». */

/* Là encore, aucune redéfinition de la grille : les quatre
   pièces proposées occupent exactement les quatre colonnes
   du catalogue, et suivent ses paliers responsive. */


/* =======================================================
   CONSENTEMENT — BANDEAU ET PRÉFÉRENCES

   Le balisage est construit par js/consent.js, pas écrit dans
   les pages : le site n'a aucun système d'inclusion, et un
   bandeau en dur serait recopié 106 fois.

   Toutes les couleurs passent par les variables de thème : le
   bandeau doit rester lisible en clair comme en sombre.
======================================================= */

/* -------- Bandeau --------

   Ancré en bas, largeur limitée, jamais plein écran : il
   informe et propose, il ne prend pas la page en otage. Le
   z-index le place au-dessus du contenu mais SOUS la modale de
   connexion (200) et sous le grain (9999). */
.consent-bandeau{

    position:fixed;
    left:50%;
    bottom:1.2rem;
    transform:translateX(-50%);
    z-index:150;

    width:min(46rem, calc(100vw - 2.4rem));
    padding:1.3rem 1.5rem;

    background:var(--dark);
    border:1px solid var(--line);
    border-radius:12px;
    box-shadow:0 18px 50px rgba(10, 10, 10, .28);

}

.consent-bandeau-titre{

    margin:0 0 .5rem;
    font-family:'Anton', sans-serif;
    font-size:1rem;
    letter-spacing:.1em;
    text-transform:uppercase;

}

.consent-bandeau-texte{

    margin:0 0 1.1rem;
    color:var(--grey);
    font-size:.86rem;
    line-height:1.6;

}

.consent-lien{

    color:var(--ink);
    text-decoration:underline;
    text-underline-offset:2px;

}

.consent-bandeau-actions{

    display:flex;
    flex-wrap:wrap;
    gap:.6rem;

}


/* -------- Boutons --------

   « Tout accepter » et « Refuser » partagent la MÊME classe et
   donc exactement le même rendu : taille, remplissage, poids,
   contraste. C'est une exigence, pas une préférence — rendre
   le refus plus discret que l'acceptation vide le consentement
   de son sens.

   min-height:44px : cible tactile confortable. */
.consent-bouton{

    display:inline-flex;
    align-items:center;
    justify-content:center;
    min-height:44px;
    padding:.7rem 1.4rem;
    border-radius:8px;
    font-family:inherit;
    font-size:11px;
    font-weight:600;
    letter-spacing:1.4px;
    text-transform:uppercase;
    cursor:pointer;
    transition:background var(--transition), border-color var(--transition), color var(--transition);

}

.consent-bouton-principal{

    flex:1 1 10rem;
    background:var(--ink);
    border:1px solid var(--ink);
    color:var(--accent-ink);

}

.consent-bouton-principal:hover{ background:var(--accent-hover); }

.consent-bouton-secondaire{

    flex:1 1 8rem;
    background:none;
    border:1px solid var(--line);
    color:var(--ink);

}

.consent-bouton-secondaire:hover{ border-color:rgba(var(--ink-rgb), .4); }

/* Troisième rang : plus sobre parce qu'il ouvre un choix plus
   long, pas parce qu'il compte moins. */
.consent-bouton-tertiaire{

    flex:0 1 auto;
    background:none;
    border:1px solid transparent;
    color:var(--grey);
    text-decoration:underline;
    text-underline-offset:3px;

}

.consent-bouton-tertiaire:hover{ color:var(--ink); }


/* -------- Panneau de préférences -------- */

.consent-panneau-fond{

    position:fixed;
    inset:0;
    z-index:210;
    display:flex;
    align-items:center;
    justify-content:center;
    padding:1.2rem;
    background:rgba(10, 10, 10, .62);

}

.consent-panneau{

    position:relative;
    width:min(34rem, 100%);
    max-height:86vh;
    overflow-y:auto;
    padding:2rem 1.8rem 1.6rem;
    background:var(--dark);
    border:1px solid var(--line);
    border-radius:12px;

}

.consent-panneau-titre{

    margin:0 0 1.4rem;
    font-family:'Anton', sans-serif;
    font-size:1.15rem;
    letter-spacing:.1em;
    text-transform:uppercase;

}

.consent-panneau-fermer{

    position:absolute;
    top:.7rem;
    right:.8rem;
    width:34px;
    height:34px;
    background:none;
    border:none;
    color:var(--grey);
    font-size:1.4rem;
    line-height:1;
    cursor:pointer;
    transition:color var(--transition);

}

.consent-panneau-fermer:hover{ color:var(--ink); }


/* -------- Une finalité -------- */

.consent-finalite{

    padding:1rem 0;
    border-top:1px solid var(--line);

}

.consent-finalite:last-child{ border-bottom:1px solid var(--line); }

.consent-finalite-tete{

    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:1rem;
    margin-bottom:.35rem;

}

.consent-finalite-titre{

    margin:0;
    font-size:15px;
    font-weight:600;

}

/* « Toujours actifs » : un libellé, pas un interrupteur bloqué.
   Un interrupteur qu'on ne peut pas bouger laisse croire à un
   choix qui n'existe pas. */
.consent-finalite-fixe{

    flex:0 0 auto;
    color:var(--grey);
    font-size:11px;
    letter-spacing:1px;
    text-transform:uppercase;

}

.consent-finalite-note{

    margin:0;
    color:var(--grey);
    font-size:.82rem;
    line-height:1.55;

}


/* -------- Interrupteur --------

   Une vraie case à cocher, rendue invisible mais conservée :
   c'est elle qui porte le focus clavier, l'état et le libellé
   accessible. Le dessin n'est qu'une peinture par-dessus. */
/* La zone tactile fait 44px de haut alors que la piste dessinée
   n'en fait que 26 : c'est l'étiquette entière qui est cliquable,
   pas seulement le dessin. Sans ce min-height, l'interrupteur
   demanderait une visée au pouce de 26px — la hauteur du dessin
   n'a pas à dicter celle de la cible. */
.consent-bascule{

    flex:0 0 auto;
    position:relative;
    display:inline-flex;
    align-items:center;
    min-height:44px;
    cursor:pointer;

}

.consent-bascule-case{

    position:absolute;
    width:100%;
    height:100%;
    margin:0;
    opacity:0;
    cursor:pointer;

}

.consent-bascule-piste{

    display:block;
    width:44px;
    height:26px;
    border:1px solid var(--line);
    border-radius:999px;
    background:rgba(var(--ink-rgb), .07);
    transition:background var(--transition), border-color var(--transition);

}

.consent-bascule-piste::after{

    content:"";
    display:block;
    width:18px;
    height:18px;
    margin:3px;
    border-radius:50%;
    background:var(--grey);
    transition:transform var(--transition), background var(--transition);

}

.consent-bascule-case:checked + .consent-bascule-piste{

    background:var(--ink);
    border-color:var(--ink);

}

.consent-bascule-case:checked + .consent-bascule-piste::after{

    transform:translateX(18px);
    background:var(--accent-ink);

}

/* Le focus doit rester visible : c'est le seul repère d'un
   utilisateur au clavier. */
.consent-bascule-case:focus-visible + .consent-bascule-piste{

    outline:2px solid var(--ink);
    outline-offset:2px;

}


/* -------- Bas du panneau -------- */

.consent-panneau-bas{

    display:flex;
    flex-wrap:wrap;
    gap:.6rem;
    margin-top:1.4rem;

}

.consent-panneau-pied{

    margin:1rem 0 0;
    font-size:.78rem;
    text-align:center;

}

/* Empêche la page de défiler derrière le panneau ouvert. */
.consent-fige{ overflow:hidden; }


/* -------- Accès permanent, dans le pied de page --------

   Un bouton et non un lien : il n'ouvre pas une page, il ouvre
   un panneau. Il doit néanmoins se lire exactement comme ses
   voisins « Mentions légales » ou « Conditions générales », d'où
   la remise à zéro du style natif du bouton. */
.consent-lien-pied{

    padding:0;
    background:none;
    border:none;
    color:inherit;
    font-family:inherit;
    font-size:inherit;
    letter-spacing:inherit;
    text-align:left;
    cursor:pointer;

}

.consent-lien-pied:hover{ text-decoration:underline; }


@media (max-width:560px){

    .consent-bandeau{

        left:.6rem;
        right:.6rem;
        bottom:.6rem;
        width:auto;
        transform:none;
        padding:1.1rem 1.1rem 1.2rem;

    }

    /* Chaque action sur sa propre ligne, pleine largeur : à cette
       taille, trois boutons côte à côte deviennent trois cibles
       étroites — et la plus étroite serait « Refuser ». */
    .consent-bandeau-actions{ flex-direction:column; }

    .consent-bouton-principal,
    .consent-bouton-secondaire{ flex:1 1 auto; }

}


@media (prefers-reduced-motion: reduce){

    .consent-bouton,
    .consent-panneau-fermer,
    .consent-bascule-piste,
    .consent-bascule-piste::after{ transition:none; }

}


/* =======================================================
   ADMINISTRATION — BASE CLIENTS

   Reprend le langage du back-office existant (.admin-table,
   .admin-btn, .admin-search) plutôt que d'en inventer un
   second. Seul ce qui n'existait pas est défini ici.

   Aucun graphique : une fiche client sert à gérer un compte,
   pas à le contempler. Les chiffres sont donnés en clair.
======================================================= */

/* Le sélecteur de statut, taillé comme le champ de recherche
   voisin pour que la barre d'outils reste d'un seul tenant. */
.admin-select{

    padding:10px 14px;
    border:1px solid var(--line);
    border-radius:8px;
    background:transparent;
    color:var(--ink);
    font-family:inherit;
    font-size:12.5px;
    cursor:pointer;

}

.admin-vide{

    padding:1.6rem 0;
    color:var(--grey);
    font-size:.86rem;
    text-align:center;

}

/* Une action qui ne mérite pas un cadre : ouvrir une fiche,
   consigner une note. */
.admin-btn-lien{

    padding:6px 10px;
    border-color:transparent;
    color:var(--grey);
    text-decoration:underline;
    text-underline-offset:3px;

}

.admin-btn-lien:hover{ color:var(--ink); }

.admin-retour{ margin-bottom:1.4rem; }


/* -------- Pastille de statut --------

   Trois états, trois traitements distincts. Le banni est le
   seul en rouge : c'est le seul qui interdit quelque chose de
   façon définitive. Le suspendu est ambré — temporaire, à
   surveiller. L'actif reste neutre : c'est la normale, elle
   n'a pas à attirer l'œil. */
.admin-statut{

    display:inline-block;
    padding:3px 10px;
    border:1px solid var(--line);
    border-radius:999px;
    font-size:11px;
    font-weight:600;
    letter-spacing:.04em;

}

.admin-statut-active{ color:var(--grey); }

.admin-statut-suspended{

    border-color:rgba(var(--ink-rgb), .4);
    color:var(--ink);

}

.admin-statut-banned{

    border-color:rgba(194, 65, 65, .45);
    color:#C24141;

}


/* -------- Fiche client -------- */

.admin-fiche-bloc{

    margin-bottom:2rem;
    padding-bottom:1.6rem;
    border-bottom:1px solid var(--line);

}

.admin-fiche-bloc:last-child{ border-bottom:none; }

.admin-fiche-bloc h3{

    margin:0 0 1rem;
    font-family:'Anton', sans-serif;
    font-size:.95rem;
    letter-spacing:.1em;
    text-transform:uppercase;

}

/* Libellé / valeur en deux colonnes : la première fixe, pour
   que les valeurs s'alignent et se lisent en descendant. */
.admin-fiche-liste{

    display:grid;
    grid-template-columns:11rem 1fr;
    gap:.55rem 1.2rem;
    margin:0;
    font-size:.88rem;

}

.admin-fiche-liste dt{ color:var(--grey); }

.admin-fiche-liste dd{ margin:0; }

.admin-fiche-liste code{

    padding:2px 6px;
    border-radius:4px;
    background:rgba(var(--ink-rgb), .06);
    font-size:.8rem;

}

.admin-fiche-note{

    margin:.8rem 0 1.2rem;
    color:var(--grey);
    font-size:.78rem;
    line-height:1.5;

}


/* -------- Chiffres d'activité --------

   Des nombres posés à plat, sans courbe ni jauge. À six
   valeurs, un graphique n'apprendrait rien de plus et
   demanderait d'être déchiffré. */
.admin-fiche-chiffres{

    display:grid;
    grid-template-columns:repeat(auto-fit, minmax(9rem, 1fr));
    gap:1rem;

}

.admin-chiffre{

    display:flex;
    flex-direction:column;
    gap:.25rem;
    padding:.9rem 1rem;
    border:1px solid var(--line);
    border-radius:8px;

}

.admin-chiffre-valeur{

    font-family:'Anton', sans-serif;
    font-size:1.2rem;
    letter-spacing:.02em;

}

.admin-chiffre-libelle{

    color:var(--grey);
    font-size:.74rem;
    letter-spacing:.06em;
    text-transform:uppercase;

}


/* -------- Modération -------- */

.admin-mod-actions{

    display:flex;
    flex-wrap:wrap;
    gap:.6rem;
    margin-bottom:.4rem;

}

/* L'historique se lit comme un journal : une ligne par
   décision, la plus récente en haut, avec qui l'a prise. */
.admin-historique{

    margin:0;
    padding:0;
    list-style:none;

}

.admin-historique li{

    display:flex;
    flex-wrap:wrap;
    align-items:baseline;
    gap:.5rem .9rem;
    padding:.7rem 0;
    border-top:1px solid var(--line);
    font-size:.84rem;

}

.admin-historique-date{

    flex:0 0 9.5rem;
    color:var(--grey);
    font-size:.78rem;

}

.admin-historique-action{

    font-weight:600;
    letter-spacing:.04em;
    text-transform:uppercase;
    font-size:.74rem;

}

.admin-historique-motif{ color:var(--ink); }

.admin-historique-par{

    margin-left:auto;
    color:var(--grey);
    font-size:.76rem;

}


@media (max-width:760px){

    .admin-fiche-liste{ grid-template-columns:1fr; gap:.15rem; }

    .admin-fiche-liste dt{ margin-top:.6rem; }

    .admin-historique-date{ flex:0 0 100%; }

    .admin-historique-par{ margin-left:0; }

    .admin-select{ width:100%; }

}


/* =======================================================
   ADMINISTRATION — DASHBOARD ANALYTICS

   Hiérarchie tenue partout : les CHIFFRES d'abord, puis
   l'ÉVOLUTION, puis le DÉTAIL. Le regard doit pouvoir
   s'arrêter à la première ligne et déjà savoir où on en est.

   Aucune couleur décorative, aucune jauge, aucun dégradé : ce
   sont des nombres, ils se lisent. Le seul écart de traitement
   marque la valeur qui compte le plus dans chaque vue.
======================================================= */

/* Sous-onglets : plus légers que les onglets principaux, pour
   qu'on voie tout de suite qu'ils naviguent DANS Analytics et
   non entre les grandes sections du back-office. */
.admin-sous-onglets{

    display:flex;
    flex-wrap:wrap;
    gap:.4rem;
    margin-bottom:1.6rem;
    padding-bottom:.9rem;
    border-bottom:1px solid var(--line);

}

.admin-sous-onglet{

    padding:7px 14px;
    border:1px solid transparent;
    border-radius:999px;
    background:none;
    color:var(--grey);
    font-family:inherit;
    font-size:12.5px;
    font-weight:600;
    cursor:pointer;
    transition:color var(--transition), background var(--transition);

}

.admin-sous-onglet:hover{ color:var(--ink); }

.admin-sous-onglet.active{

    background:rgba(var(--ink-rgb), .07);
    color:var(--ink);

}


/* -------- Cartes de chiffres --------

   Grille souple : à sept ou onze cartes, une largeur fixe
   laisserait un trou en fin de ligne. minmax les répartit. */
.admin-kpis{

    display:grid;
    grid-template-columns:repeat(auto-fit, minmax(11rem, 1fr));
    gap:.9rem;
    margin-bottom:1.4rem;

}

.admin-kpi{

    display:flex;
    flex-direction:column;
    gap:.3rem;
    padding:1rem 1.1rem;
    border:1px solid var(--line);
    border-radius:10px;

}

/* Une seule carte accentuée par vue : celle qui répond à la
   question qu'on est venu poser. Accentuer davantage
   reviendrait à n'accentuer rien. */
.admin-kpi-fort{ border-color:rgba(var(--ink-rgb), .34); }

.admin-kpi-libelle{

    color:var(--grey);
    font-size:.72rem;
    letter-spacing:.08em;
    text-transform:uppercase;

}

.admin-kpi-valeur{

    font-family:'Anton', sans-serif;
    font-size:1.45rem;
    letter-spacing:.01em;
    line-height:1.15;

}

.admin-kpi-note{

    color:var(--grey);
    font-size:.74rem;
    line-height:1.4;

}

/* L'aveu d'une lacune ne doit jamais ressembler à un chiffre :
   ni gros, ni en Anton, ni aligné comme une valeur. */
.admin-insuffisant{

    display:inline-block;
    color:var(--grey);
    font-family:inherit;
    font-size:.8rem;
    font-style:italic;

}


/* -------- Graphiques -------- */

.admin-graphes{

    display:grid;
    grid-template-columns:repeat(auto-fit, minmax(18rem, 1fr));
    gap:1.4rem;
    margin-top:1.8rem;

}

.admin-graphe{

    padding:1.1rem 1.2rem 1rem;
    border:1px solid var(--line);
    border-radius:10px;

}

.admin-graphe h4{

    display:flex;
    align-items:baseline;
    justify-content:space-between;
    gap:1rem;
    margin:0 0 .9rem;
    font-size:.8rem;
    font-weight:600;
    letter-spacing:.04em;

}

.admin-graphe-max{

    color:var(--grey);
    font-size:.72rem;
    font-weight:400;

}

/* preserveAspectRatio="none" étire le viewBox : les barres
   suivent la largeur disponible sans qu'on ait à recalculer
   quoi que ce soit en JavaScript. La hauteur est fixée ici. */
.admin-graphe-svg{

    display:block;
    width:100%;
    height:120px;

}

.admin-graphe-svg rect{

    fill:var(--ink);
    opacity:.72;
    transition:opacity var(--transition);

}

.admin-graphe-svg rect:hover{ opacity:1; }


/* -------- Tri des colonnes --------

   Un vrai bouton : le tri se déclenche au clavier comme à la
   souris, et l'en-tête reste annoncé comme un en-tête. */
.admin-tri{

    padding:0;
    background:none;
    border:none;
    color:inherit;
    font:inherit;
    letter-spacing:inherit;
    text-transform:inherit;
    cursor:pointer;

}

.admin-tri:hover{ text-decoration:underline; }

.admin-tri.actif{ color:var(--ink); font-weight:700; }

.admin-sous-titre{

    margin:2rem 0 .6rem;
    font-family:'Anton', sans-serif;
    font-size:.9rem;
    letter-spacing:.1em;
    text-transform:uppercase;

}


@media (prefers-reduced-motion: reduce){

    .admin-sous-onglet,
    .admin-graphe-svg rect{ transition:none; }

}


/* -------- Espace client : enregistrer son nom affiché --------

   Le bouton et son retour vivent sur la même ligne, sous le
   champ : la confirmation doit apparaître là où l'œil vient de
   cliquer, pas en haut de page. */
.compte-champ-action{

    display:flex;
    flex-wrap:wrap;
    align-items:center;
    gap:.8rem;
    margin-top:.6rem;

}

.compte-champ-etat{

    color:var(--grey);
    font-size:.8rem;

}

.compte-champ-etat-erreur{ color:#C24141; }


/* =======================================================
   ADMINISTRATION — PROMOTIONS

   Aucun composant nouveau là où l'un existe déjà : la liste
   réutilise .admin-table, la fiche .admin-drawer, les
   boutons .admin-btn, les pastilles .admin-statut. Seul ce
   qui manquait vraiment est défini ici — un formulaire
   sectionné, un sélecteur de type, et les couleurs des cinq
   états d'un code.
======================================================= */


/* -------- Sections du formulaire --------

   Un code promotionnel a une vingtaine de réglages. Posés à
   la suite, ils forment une feuille de calcul ; regroupés en
   six questions successives — quel type, quel code, sur quoi,
   à quelles conditions, combien de fois, actif ou non — ils
   redeviennent lisibles.

   <fieldset> plutôt qu'une <div> : le regroupement est réel,
   et un lecteur d'écran annonce alors la légende avant chaque
   champ du bloc. */
.admin-bloc{

    border:none;
    border-top:1px solid var(--line);
    margin:0;
    padding:1.6rem 0 0;

}

.admin-bloc:first-of-type{ border-top:none; padding-top:0; }

.admin-bloc + .admin-bloc{ margin-top:1.6rem; }

.admin-bloc-titre{

    font-family:'Anton', sans-serif;
    font-size:.82rem;
    letter-spacing:.12em;
    text-transform:uppercase;
    color:var(--grey-light);
    padding:0;
    margin-bottom:1rem;

}

/* Les champs qui apparaissent selon les choix du dessus.
   L'écart est posé ici et non sur le bloc parent : un champ
   masqué ne doit pas laisser sa marge derrière lui. */
.admin-bloc-champ{ margin-top:1rem; }


/* -------- Sélecteur de type --------

   Trois options exclusives, montrées ensemble : le choix se
   fait d'un coup d'œil, sans dérouler une liste. Même
   traitement que .size-button sur les fiches produit, dont
   c'est exactement le rôle. */
.admin-choix{

    display:flex;
    flex-wrap:wrap;
    gap:.5rem;

}

.admin-choix-option{

    padding:9px 16px;
    border:1px solid var(--line);
    border-radius:8px;
    background:transparent;
    color:var(--grey);
    font-family:inherit;
    font-size:12.5px;
    cursor:pointer;
    transition:border-color var(--transition), color var(--transition);

}

.admin-choix-option:hover{ color:var(--ink); }

/* --ink s'inverse correctement par thème, --white non :
   c'est le même choix que .checkout-button. */
.admin-choix-option.active{

    background:var(--ink);
    border-color:var(--ink);
    color:var(--accent-ink);

}


/* -------- Liste des promotions -------- */

/* Une action de ligne, plus discrète que le bouton d'une
   barre d'outils : la table en compte autant que de lignes. */
.admin-btn-mini{

    padding:5px 11px;
    font-size:11.5px;

}

/* La précision sous une valeur : nom interne d'un code, type
   de cible, période. Jamais l'information principale. */
.admin-sous{

    color:var(--grey);
    font-size:11.5px;

}


/* -------- Les cinq états d'un code --------

   Aucun n'est stocké : ils se déduisent de la date du jour et
   du compteur d'utilisations (promo_etat en base). Le code
   actif est le seul mis en avant — les quatre autres décrivent
   une inactivité, et une inactivité n'a pas à attirer l'œil.

   « Épuisée » est ambré comme la suspension d'un compte : dans
   les deux cas quelque chose demande une décision. « Expirée »
   et « Désactivée » restent neutres : c'est une fin normale. */
.admin-statut-promo-active{

    border-color:rgba(var(--gold-rgb), .45);
    color:var(--gold);

}

.admin-statut-promo-programmee{ color:var(--grey); }

.admin-statut-promo-expiree{ color:var(--grey); }

.admin-statut-promo-inactive{ color:var(--grey); }

.admin-statut-promo-epuisee{

    border-color:rgba(var(--ink-rgb), .4);
    color:var(--ink);

}


/* -------- Ciblage d'une promotion --------

   Cinq listes indépendantes dans un tiroir étroit. Le risque
   n'est pas le manque de place, c'est l'illisibilité : sans
   séparation nette, les sélections d'un bloc se lisent comme
   celles du voisin.

   D'où un filet à gauche par groupe — le même trait à un
   pixel que le reste du back-office, jamais une carte. */

.admin-cibles{

    display:flex;
    flex-direction:column;
    gap:1.4rem;

}

.admin-cible{

    padding-left:.9rem;
    border-left:1px solid var(--line);

}

.admin-cible-titre{

    font-size:.78rem;
    font-weight:600;
    letter-spacing:.06em;
    text-transform:uppercase;
    color:var(--grey);
    margin:0 0 .6rem;

}

/* La règle de combinaison, dite une fois en haut du bloc. */
.admin-cible-regle{ margin-bottom:1.4rem; }


/* -------- Les sélections --------

   Le « ou » entre deux puces n'est pas décoratif : le moteur
   combine TOUTES les cibles par OU, types confondus. Un signe
   « + » aurait laissé croire à un croisement, et une campagne
   aurait remisé bien plus de pièces que prévu. */

.admin-puces{

    display:flex;
    flex-wrap:wrap;
    align-items:center;
    gap:.4rem;

}

.admin-puces:not(:empty){ margin-bottom:.7rem; }

.admin-puce{

    display:inline-flex;
    align-items:center;
    gap:.5rem;
    max-width:100%;
    padding:5px 6px 5px 11px;
    border:1px solid var(--line);
    border-radius:999px;
    font-size:12px;
    /* Un nom de pièce long ne doit pas élargir le tiroir. */
    overflow-wrap:anywhere;

}

.admin-puce-ou{

    font-size:var(--t-micro);
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--grey);

}

.admin-puce-x{

    flex:0 0 auto;
    width:18px;
    height:18px;
    display:flex;
    align-items:center;
    justify-content:center;
    padding:0;
    border:none;
    border-radius:50%;
    background:transparent;
    color:var(--grey);
    font-family:inherit;
    font-size:14px;
    line-height:1;
    cursor:pointer;
    transition:background var(--transition), color var(--transition);

}

.admin-puce-x:hover{

    background:rgba(var(--ink-rgb), .09);
    color:var(--ink);

}


/* -------- Le sélecteur --------

   Il ne s'ouvre qu'à la demande, et un seul à la fois : deux
   listes de résultats côte à côte dans un tiroir étroit
   deviennent illisibles. */

.admin-picker{

    margin-top:.7rem;
    border:1px solid var(--line);
    border-radius:8px;
    overflow:hidden;

}

.admin-picker-champ{

    width:100%;
    padding:9px 12px;
    border:none;
    border-bottom:1px solid var(--line);
    background:transparent;
    color:var(--ink);
    font-family:inherit;
    font-size:12.5px;

}

.admin-picker-champ:focus{ outline:none; }

/* Une hauteur bornée, sinon soixante-trois pièces poussent le
   pied du tiroir hors de l'écran. */
.admin-picker-liste{

    max-height:14rem;
    overflow-y:auto;

}

.admin-picker-item{

    display:flex;
    align-items:baseline;
    justify-content:space-between;
    gap:1rem;
    width:100%;
    padding:8px 12px;
    border:none;
    border-bottom:1px solid var(--line-soft, rgba(var(--ink-rgb), .07));
    background:transparent;
    color:var(--ink);
    font-family:inherit;
    font-size:12.5px;
    text-align:left;
    cursor:pointer;
    transition:background var(--transition);

}

.admin-picker-item:last-child{ border-bottom:none; }

.admin-picker-item:hover{ background:rgba(var(--ink-rgb), .05); }

.admin-picker-vide{

    padding:12px;
    margin:0;
    color:var(--grey);
    font-size:12px;

}


/* =======================================================
   LE CODE PROMOTIONNEL

   Deux composants, et rien de plus : le champ dans le
   récapitulatif, et la carte d'un code attribué dans
   l'espace client.

   Aucun encadré coloré, aucun badge, aucune animation. Un
   panier doit rassurer ; une interface qui clignote fait
   exactement l'inverse au moment où le client s'apprête à
   payer. Le montant TOTAL reste l'information dominante —
   la réduction se lit, mais ne prend jamais le dessus.
======================================================= */


/* -------- Le champ, dans le récapitulatif -------- */

.promo-bloc{

    margin:1.1rem 0 0;

}

/* :not(.hidden) est INDISPENSABLE ici.

   .hidden{display:none} est declare bien plus haut dans ce
   fichier. A specificite egale, c est la derniere regle qui
   gagne : un simple display:flex pose ici annulerait donc le
   masquage, et le champ restait affiche SOUS le code applique.

   La classe etait bien posee, l element restait visible — le
   genre de defaut qu une verification du DOM ne voit pas, et
   qu une capture d ecran montre tout de suite. */
.promo-saisie:not(.hidden){

    display:flex;
    gap:.5rem;

}

.promo-saisie input{

    flex:1 1 auto;
    /* Sans min-width:0, un input en flex refuse de descendre
       sous sa largeur par défaut et pousse le bouton hors du
       récapitulatif sur mobile. */
    min-width:0;
    padding:11px 13px;
    border:1px solid var(--line);
    border-radius:8px;
    background:transparent;
    color:var(--ink);
    font-family:inherit;
    font-size:13px;
    /* Les codes s'écrivent en capitales : les afficher ainsi
       évite au client de se demander si sa saisie compte. */
    text-transform:uppercase;

}

.promo-saisie input::placeholder{

    color:var(--grey);
    text-transform:none;

}

.promo-saisie input:focus{

    outline:none;
    border-color:rgba(var(--ink-rgb), .4);

}

.promo-appliquer{

    flex:0 0 auto;
    /* 44px de haut : la cible tactile minimale recommandée.
       Un bouton plus fin se rate au pouce, et l'échec se
       produit au pire moment du parcours. */
    min-height:44px;
    padding:11px 18px;
    border:1px solid var(--line);
    border-radius:8px;
    background:transparent;
    color:var(--ink);
    font-family:inherit;
    font-size:12.5px;
    letter-spacing:.04em;
    cursor:pointer;
    transition:border-color var(--transition), color var(--transition);

}

.promo-appliquer:hover{ border-color:rgba(var(--ink-rgb), .4); }

.promo-appliquer:disabled{ opacity:.5; cursor:default; }


/* -------- Le code appliqué --------

   Discret et définitif : le code, ce qu'il rapporte, et de
   quoi le retirer. Un filet d'un pixel, comme partout
   ailleurs sur le site. */

/* Meme raison que .promo-saisie ci-dessus. */
.promo-actif:not(.hidden){

    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:.8rem;
    padding:.7rem .9rem;
    border:1px solid rgba(var(--gold-rgb), .4);
    border-radius:8px;

}

.promo-actif-texte{

    display:flex;
    flex-direction:column;
    gap:.15rem;
    min-width:0;

}

.promo-actif-code{

    font-family:'Anton', sans-serif;
    font-size:.85rem;
    letter-spacing:.08em;
    color:var(--gold);
    overflow-wrap:anywhere;

}

.promo-actif-gain{

    font-size:11.5px;
    color:var(--grey);

}

.promo-retirer{

    flex:0 0 auto;
    min-height:32px;
    padding:0 .5rem;
    border:none;
    background:none;
    color:var(--grey);
    font-family:inherit;
    font-size:11.5px;
    text-decoration:underline;
    text-underline-offset:3px;
    cursor:pointer;
    transition:color var(--transition);

}

.promo-retirer:hover{ color:var(--ink); }


/* Le refus, dit en une phrase. Jamais un encadré rouge :
   un code qui ne s'applique pas n'est pas une faute du
   client. */
.promo-erreur{

    margin:.6rem 0 0;
    font-size:12px;
    color:#C24141;

}


/* -------- La ligne de réduction du récapitulatif --------

   Même graisse que les autres lignes : elle informe, elle ne
   se vante pas. La couleur suffit à la distinguer d'un frais. */
.promo-ligne{ color:var(--gold); }


/* -------- Une carte de code, dans l'espace client --------

   Ce que le client vient chercher est LE CODE : il est donc
   la ligne la plus lisible de la carte. La valeur le
   surmonte, les conditions le suivent en retrait.

   Un code passé n'est pas caché — savoir qu'on a utilisé
   une offre fait partie de son historique — mais il
   s'estompe. */

.compte-code{

    padding:1.1rem 1.2rem;
    border:1px solid var(--line);
    border-radius:var(--radius);

}

.compte-code + .compte-code{ margin-top:.8rem; }

.compte-code-passe{ opacity:.55; }

.compte-code-tete{

    display:flex;
    align-items:baseline;
    justify-content:space-between;
    gap:1rem;
    margin-bottom:.2rem;

}

.compte-code-valeur{

    font-family:'Anton', sans-serif;
    font-size:1.05rem;
    letter-spacing:.03em;
    text-transform:uppercase;
    margin:0;

}

.compte-code-nom{

    font-size:.82rem;
    color:var(--grey);
    margin:0 0 .6rem;

}

/* Le code lui-même : sélectionnable, et espacé pour qu'on
   ne confonde pas un 0 et un O en le recopiant à la main. */
.compte-code-code{

    font-family:'Anton', sans-serif;
    font-size:1.25rem;
    letter-spacing:.16em;
    color:var(--gold);
    margin:.5rem 0 .4rem;
    user-select:all;
    overflow-wrap:anywhere;

}

.compte-code-conditions{

    font-size:.8rem;
    color:var(--grey);
    margin:0;

}

.compte-code-actions{

    display:flex;
    align-items:center;
    gap:1.1rem;
    margin-top:.9rem;

}

.compte-code-copier{

    min-height:36px;
    padding:8px 14px;
    border:1px solid var(--line);
    border-radius:8px;
    background:transparent;
    color:var(--ink);
    font-family:inherit;
    font-size:12px;
    cursor:pointer;
    transition:border-color var(--transition), color var(--transition);

}

.compte-code-copier:hover{ border-color:rgba(var(--ink-rgb), .4); }

/* Le retour après copie. Un changement de couleur et de
   texte, pas d'animation : la confirmation doit se lire, pas
   se regarder. */
.compte-code-copie{

    border-color:rgba(var(--gold-rgb), .5);
    color:var(--gold);

}


/* =======================================================
   AFFILIATION — PAGE PUBLIQUE

   Une page de conviction, pas un tableau de bord. Elle
   emprunte au reste du site ses variables, son Anton et ses
   filets à un pixel ; elle n'invente ni palette ni forme.

   Aucune image : la typographie ARKWER porte seule, et
   fabriquer un visuel pour l'occasion aurait ajouté un
   fichier à maintenir sans rien dire de plus.
======================================================= */

.affil-page{

    max-width:900px;
    margin:0 auto;
    padding:3.5rem 1.5rem 6rem;

}


/* -------- L'accroche --------

   Quatre lignes, une idée par ligne. Le retour à la ligne est
   porté par des <span> en display:block plutôt que par la
   largeur du bloc : la coupure doit tomber au même endroit à
   toutes les tailles, parce que c'est elle qui donne le
   rythme. */

.affil-eyebrow{

    font-family:'Anton', sans-serif;
    font-size:.72rem;
    letter-spacing:.16em;
    text-transform:uppercase;
    color:var(--gold);
    margin:0 0 1.6rem;

}

.affil-titre{

    font-family:'Anton', sans-serif;
    font-weight:400;
    font-size:clamp(1.9rem, 6vw, 3.4rem);
    line-height:1.04;
    letter-spacing:.02em;
    text-transform:uppercase;
    margin:0 0 2rem;

}

.affil-titre span{ display:block; }

/* La quatrième ligne est la promesse. Elle seule change de
   couleur — trois lignes dorées n'auraient plus de hiérarchie. */
.affil-titre-fort{ color:var(--gold); }

.affil-chapo{

    font-size:1.05rem;
    color:var(--grey-light);
    max-width:46ch;
    margin:0 0 2.4rem;

}

.affil-actions{

    display:flex;
    flex-direction:column;
    align-items:flex-start;
    gap:1rem;

}

.affil-cta{

    /* Le bouton du site, à sa largeur naturelle : étiré sur
       900px il ressemblerait à une bannière publicitaire. */
    width:auto;
    padding-left:2.2rem;
    padding-right:2.2rem;

}

.affil-etat{

    font-size:.9rem;
    color:var(--gold);
    margin:0;
    max-width:52ch;

}

.affil-etat-erreur{ color:#C24141; }


/* -------- Le lien --------

   Encadré d'un filet doré : c'est le seul élément de la page
   que l'affilié vient chercher deux fois. */

.affil-lien-bloc{

    margin:3.5rem 0 0;
    padding:1.6rem;
    border:1px solid rgba(var(--gold-rgb), .4);
    border-radius:var(--radius);

}

.affil-lien-titre{

    font-family:'Anton', sans-serif;
    font-size:.8rem;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--grey-light);
    margin:0 0 .9rem;

}

.affil-lien{

    display:flex;
    flex-wrap:wrap;
    align-items:center;
    gap:.8rem;

}

.affil-lien-adresse{

    font-family:'Anton', sans-serif;
    font-size:clamp(1.05rem, 3.6vw, 1.5rem);
    letter-spacing:.06em;
    color:var(--gold);
    /* Sélectionnable d'un geste : certains préfèrent copier à
       la main plutôt que de faire confiance à un bouton. */
    user-select:all;
    overflow-wrap:anywhere;
    min-width:0;

}

.affil-copier{

    flex:0 0 auto;
    min-height:40px;
    padding:9px 16px;
    border:1px solid var(--line);
    border-radius:8px;
    background:transparent;
    color:var(--ink);
    font-family:inherit;
    font-size:12.5px;
    cursor:pointer;
    transition:border-color var(--transition), color var(--transition);

}

.affil-copier:hover{ border-color:rgba(var(--ink-rgb), .4); }

.affil-copie{

    border-color:rgba(var(--gold-rgb), .5);
    color:var(--gold);

}

.affil-lien-note{

    font-size:.85rem;
    color:var(--grey);
    margin:1rem 0 0;
    max-width:52ch;

}


/* -------- Les chiffres --------

   Deux nombres, réels, venus de la base. Aucun n'est affiché
   tant qu'il n'est pas revenu du serveur : un zéro provisoire
   se lit comme un échec. */

.affil-chiffres{

    display:flex;
    flex-wrap:wrap;
    gap:2.4rem;
    margin-top:1.6rem;

}

.affil-chiffres:empty{ display:none; }

.affil-chiffre{

    display:flex;
    flex-direction:column;
    gap:.2rem;

}

.affil-chiffre-valeur{

    font-family:'Anton', sans-serif;
    font-size:1.6rem;
    line-height:1;
    font-variant-numeric:tabular-nums;

}

.affil-chiffre-libelle{

    font-size:.78rem;
    letter-spacing:.04em;
    color:var(--grey);

}


/* -------- Les sections -------- */

.affil-section{

    margin-top:3.5rem;
    padding-top:2.4rem;
    border-top:1px solid var(--line);

}

.affil-h2{

    font-family:'Anton', sans-serif;
    font-size:1.15rem;
    letter-spacing:.1em;
    text-transform:uppercase;
    margin:0 0 1.4rem;

}

.affil-texte{

    max-width:60ch;
    margin:0 0 1rem;

}

.affil-texte-gris{ color:var(--grey); font-size:.92rem; }


/* -------- Les trois étapes --------

   Numérotées parce que c'en est réellement une séquence :
   sans la première, la deuxième n'a pas lieu. Le numéro dit
   donc quelque chose de vrai, il ne décore pas. */

.affil-etapes{

    list-style:none;
    counter-reset:etape;
    margin:0;
    padding:0;
    display:grid;
    grid-template-columns:repeat(auto-fit, minmax(220px, 1fr));
    gap:2rem;

}

.affil-etapes li{

    counter-increment:etape;
    padding-top:2.4rem;
    position:relative;

}

.affil-etapes li::before{

    content:counter(etape, decimal-leading-zero);
    position:absolute;
    top:0;
    left:0;
    font-family:'Anton', sans-serif;
    font-size:.8rem;
    letter-spacing:.1em;
    color:var(--gold);

}

.affil-etape-titre{

    font-family:'Anton', sans-serif;
    font-size:.98rem;
    letter-spacing:.06em;
    text-transform:uppercase;
    margin:0 0 .5rem;

}

.affil-etape-texte{

    font-size:.92rem;
    color:var(--grey-light);
    margin:0;

}


/* -------- Les règles -------- */

.affil-regles{

    list-style:none;
    margin:0 0 1.4rem;
    padding:0;
    max-width:62ch;

}

.affil-regles li{

    position:relative;
    padding:0 0 .9rem 1.3rem;
    font-size:.94rem;
    color:var(--grey-light);

}

.affil-regles li::before{

    content:'';
    position:absolute;
    left:0;
    top:.62em;
    width:5px;
    height:1px;
    background:var(--gold);

}


/* =======================================================
   L'ARRIVÉE PAR UN LIEN AFFILIÉ (r.html)

   Une page qu'on ne doit pas voir. Elle existe le temps d'un
   aller-retour au serveur, et se contente de ne pas être
   vide pendant ces quelques dixièmes de seconde.
======================================================= */

.redirection-affilie{

    min-height:100vh;
    display:flex;
    align-items:center;
    justify-content:center;
    background:var(--black);

}

.redirection-bloc{

    text-align:center;
    padding:2rem;

}

.redirection-marque{

    font-family:'Anton', sans-serif;
    font-size:1.6rem;
    letter-spacing:.3em;
    text-transform:uppercase;
    margin:0 0 1rem;

}

.redirection-note{

    color:var(--grey);
    font-size:.9rem;
    margin:0;

}

.redirection-secours{

    display:inline-block;
    margin-top:1.6rem;
    color:var(--gold);
    font-size:.9rem;

}


/* -------- Le lien d'un affilié, dans l'administration --------

   La seule règle propre à cet onglet. Tout le reste — fiche,
   tableau, pastilles, chiffres, boutons — réutilise les
   classes de la fiche client et de l'onglet Promotions. */

.affil-admin-lien{

    font-family:'Anton', sans-serif;
    font-size:1.05rem;
    letter-spacing:.06em;
    color:var(--gold);
    margin:0 0 1rem;
    /* Un lien long ne doit pas élargir la fiche. */
    overflow-wrap:anywhere;
    user-select:all;

}


/* =======================================================
   ESPACE AFFILIÉ (compte-affiliation.html)

   Une seule question compte quand on ouvre cette page :
   combien puis-je retirer. Le solde est donc la plus grande
   chose à l'écran, et tout le reste l'explique.

   Rien de bancaire, rien de gamifié. Les mêmes filets à un
   pixel et le même Anton que le reste de Mon ARKWER.
======================================================= */

.affil-solde{

    padding-bottom:1.6rem;
    border-bottom:1px solid var(--line);
    margin-bottom:1.4rem;

}

.affil-solde-libelle{

    font-family:'Anton', sans-serif;
    font-size:.8rem;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--grey-light);
    margin:0 0 .5rem;

}

/* Le chiffre dominant de la page. clamp pour qu'il reste
   entier sur un écran de 360px sans être écrasé sur grand
   écran. */
.affil-solde-montant{

    font-family:'Anton', sans-serif;
    font-size:clamp(2.2rem, 9vw, 3.4rem);
    line-height:1;
    letter-spacing:.02em;
    color:var(--gold);
    margin:0;
    font-variant-numeric:tabular-nums;

}

.affil-solde-points{

    font-size:.82rem;
    color:var(--grey);
    margin:.5rem 0 0;

}

.affil-retrait{ margin-bottom:1rem; }

.affil-retrait .checkout-button{ width:auto; padding-left:2rem; padding-right:2rem; }

/* Un bouton désactivé doit se voir comme tel : sans cela le
   client clique, ne comprend pas, et recommence. */
.affil-retrait .checkout-button:disabled{

    opacity:.45;
    cursor:default;

}


/* -------- Les trois états d'un gain --------

   Toujours les trois, même à zéro : savoir qu'on n'a rien en
   préparation est une information, pas un vide. */

.affil-etapes-etat{

    display:grid;
    grid-template-columns:repeat(auto-fit, minmax(200px, 1fr));
    gap:1.4rem;

}

.affil-etape-etat{

    padding-left:.9rem;
    border-left:1px solid var(--line);

}

.affil-etape-etat-titre{

    font-size:.78rem;
    letter-spacing:.05em;
    text-transform:uppercase;
    color:var(--grey);
    margin:0 0 .4rem;

}

.affil-etape-etat-montant{

    font-family:'Anton', sans-serif;
    font-size:1.4rem;
    line-height:1;
    margin:0 0 .35rem;
    font-variant-numeric:tabular-nums;

}

.affil-etape-etat-note{

    font-size:.76rem;
    color:var(--grey);
    margin:0;

}


/* -------- Une vente, un retrait --------

   Trois colonnes qui se replient en pile sur mobile. Le
   montant est en chiffres tabulaires pour que la colonne
   s'aligne d'une ligne à l'autre. */

.affil-vente{

    display:flex;
    flex-wrap:wrap;
    align-items:center;
    gap:.7rem 1.2rem;
    padding:.9rem 0;
    border-bottom:1px solid var(--line-soft, rgba(var(--ink-rgb), .07));

}

.affil-vente:last-child{ border-bottom:none; }

.affil-vente-ref{

    font-family:'Anton', sans-serif;
    font-size:.85rem;
    letter-spacing:.08em;
    color:var(--grey-light);
    /* Largeur fixe : les références s'alignent en colonne. */
    flex:0 0 auto;
    min-width:5.5rem;

}

.affil-vente-montant{

    font-size:.95rem;
    font-variant-numeric:tabular-nums;
    flex:1 1 auto;

}

.affil-vente-note{

    flex:1 1 100%;
    font-size:.8rem;
    color:var(--grey);

}

/* =======================================================
   HAUT DE PAGE MARCHAND (accueil)

   LOT 1 DE LA REFONTE, 07/09/2026.

   Ce que cette section remplace :

     · le hero plein écran et ses 550 px d'image avant le
       premier produit ;
     · les quatre grandes tuiles La sélection / Offres / Mode /
       Détails, qui répétaient la navigation en occupant un
       écran ;
     · la marque écrite en police système avec 5 px
       d'interlettrage, approximation du vrai logo.

   Ce qu'elle installe, dans cet ordre et sans rien d'autre
   entre les deux :

     HEADER → NAVIGATION → BARRE PROMO → SÉLECTION → FILTRES

   LES SÉPARATIONS SONT DES FILETS D'UN PIXEL ET DE L'ESPACE,
   jamais des encadrés. Le site en comptait déjà trop ; ajouter
   des bordures pour séparer aurait rendu la page plus confuse,
   pas moins. Chaque zone se distingue par son fond, sa hauteur
   et son filet de base — rien de plus.

   Les règles qui suivent sont toutes préfixées ou portées par
   un conteneur propre à ce haut de page. La carte, elle, n'est
   plus redéfinie ici : depuis le chantier cartes (12/09/2026)
   la sélection prend la carte commune — voir GRILLE PRODUITS
   ET CARTE.
======================================================= */

/* --- LE LOGO ---------------------------------------------

   Deux fichiers, un par thème, découpés dans le même dessin :
   même largeur, même hauteur, aucun saut au changement de
   thème. C'est la raison pour laquelle le PNG blanc fourni
   n'est pas utilisé tel quel — sa chasse diffère (rapport 4,31
   contre 3,50), le logo aurait changé de largeur en basculant.

   La hauteur est fixée, la largeur suit : le logo identifie la
   marque, il ne domine pas la barre. */

.brand {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    line-height: 0;
}

.brand-logo {
    display: block;
    width: auto;
    height: 21px;
}

/* Le thème décide lequel des deux s'affiche. Les deux images
   sont dans le DOM et préchargées : basculer de thème
   n'entraîne aucune requête, donc aucun clignotement. */
/* SOMBRE PAR DÉFAUT, SANS ATTRIBUT. js/theme.js ne pose
   data-theme="light" que pour le mode clair ; le mode sombre est
   l'absence d'attribut. La règle précédente attendait
   data-theme="dark", qui n'est jamais posé : en sombre, le logo
   noir s'affichait sur fond noir (relevé le 14/09/2026). */
.brand-logo-sombre { display: none; }

:root[data-theme="light"] .brand-logo-sombre { display: block; }
:root[data-theme="light"] .brand-logo-clair  { display: none; }

/* --- LA BARRE ACHETEUR ------------------------------------

   CHANTIER NAVIGATION V1, 14/09/2026. Cinq entrées, toutes
   tournées vers l'achat : CATALOGUE · OFFRES · POPULAIRES ·
   À DÉCOUVRIR · CHOISISSEZ. Vendre, Gagner et ARKWER n'y sont
   plus : ce sont d'autres intentions, elles vivent dans le menu
   global.

   Bloc partagé sur toutes les pages à en-tête complet
   (ARKWER ADMIN/MAINTENANCE/partiels/barre-acheteur.html).
   Ordinateur et tablette ; masquée sur téléphone, où le menu
   prend le relais.

   Une seule ligne, séparée de la barre du dessus par un filet et
   non par une couleur : c'est un seul en-tête. */

/* Hauteur de l'en-tête collant, pour ce qui se cale dessous :
   colonne d'achat de la fiche, résumés du panier et de la
   commande, ancres. Valeurs relevées dans le navigateur, filet
   compris : 71 px (barre de 70 px), 69 px sous 700 px (barre de
   68 px), 116 px avec la barre acheteur, hors téléphone. */
:root {
    --hauteur-header: 71px;
}

@media (max-width: 700px) {
    :root {
        --hauteur-header: 69px;
    }
}

@media (min-width: 761px) {
    :root:has(.navbar > .mainnav) {
        --hauteur-header: 116px;
    }
}

html {
    scroll-padding-top: calc(var(--hauteur-header) + 16px);
}

.mainnav {
    border-top: 1px solid var(--line);
    padding: 0 clamp(16px, 4vw, 48px);
}

.mainnav-liste {
    display: flex;
    align-items: stretch;
    gap: clamp(4px, 1.4vw, 22px);
    list-style: none;
    margin: 0;
    padding: 0;
    max-width: 1560px;
}

.mainnav-item {
    position: relative;
    display: flex;
}

.mainnav-lien {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 13px clamp(6px, 1vw, 12px);
    background: none;
    border: 0;
    color: var(--ink);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    position: relative;
}

/* Le soulignement se dessine sur le filet bas de l'en-tête : il
   marque la rubrique survolée, ou la page où l'on est, sans
   ajouter d'épaisseur. */
.mainnav-lien::after {
    content: "";
    position: absolute;
    left: clamp(6px, 1vw, 12px);
    right: clamp(6px, 1vw, 12px);
    bottom: 0;
    height: 2px;
    background: var(--ink);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .22s cubic-bezier(.22, 1, .36, 1);
}

.mainnav-lien:hover::after,
.mainnav-lien:focus-visible::after,
.mainnav-lien[aria-current="page"]::after {
    transform: scaleX(1);
}

@media (prefers-reduced-motion: reduce) {
    .mainnav-lien::after {
        transition: none;
    }
}

/* --- LA BARRE PROMOTIONNELLE ------------------------------

   Une bande pleine, courte, en inversion du fond de page :
   c'est la seule surface pleine du haut de page, elle se
   remarque donc sans avoir besoin d'être grande ni colorée.
   Rien ne clignote et rien ne défile. */

.promo-bar {
    background: var(--ink);
    color: var(--black);
    padding: 11px clamp(16px, 4vw, 48px);
    text-align: center;
}

.promo-bar-texte {
    /* La couleur est posee ICI et pas seulement heritee de
       .promo-bar : une regle de page donne deja une couleur aux
       <p>, et elle l emportait sur l heritage — la bande est
       sortie du premier rendu en 1,0:1 de contraste, texte
       invisible sur son propre fond. */
    color: var(--black);

    margin: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 4px 9px;
    font-size: 13px;
    line-height: 1.35;
}

.promo-bar-texte strong {
    font-family: "Anton", sans-serif;
    font-size: 15px;
    font-weight: 400;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.promo-bar-texte span {
    letter-spacing: .05em;
    opacity: .82;
}


/* =========================================================
   LES SURFACES DE L'ACCUEIL — CLAIR ET SOMBRE

   CHANTIER CORRECTION DE L'ACCUEIL, 17/09/2026.

   UNE SEULE GRAMMAIRE, DEUX JEUX DE VALEURS. Les règles de section
   ne lisent que des jetons de RÔLE ; chaque thème leur donne ses
   valeurs. Il n'y a donc pas deux feuilles parallèles à tenir
   d'accord.

     rôle              clair      sombre
     page              #FFFFFF    #1C1C1C
     surface           #F3F3F3    #262626
     carte sur page    #F3F3F3    #262626
     carte sur surface #FFFFFF    #313131
     contrôle          #FFFFFF    #313131

   CLAIR : blanc = environnement, gris = zone de contenu, blanc =
   ce qui est posé sur le gris ; texte #0A0A0A.

   SOMBRE : PAS UN MIROIR DU CLAIR. La hiérarchie monte toujours
   d'un cran vers la lumière — page, surface, carte — ce qui est la
   lecture naturelle d'un thème sombre (les éléments proches sont
   plus clairs). Écarts de 10 et 11 niveaux : assez pour être vus,
   pas assez pour dessiner des blocs. Texte #F4F3EF inchangé.
   Le #0A0A0A d'origine, trop lourd, ne sert plus de fond à
   l'accueil.

   PORTÉE : le <body class="accueil"> de index.html, et lui seul.
   Le catalogue, la fiche, le panier et le compte gardent leurs
   surfaces actuelles. Les cartes ne sont pas redessinées : elles
   lisent déjà --carte-surface, on ne redéfinit que la variable.
   ========================================================= */

/* CETTE PALETTE N'EST PLUS PROPRE À L'ACCUEIL.
   ------------------------------------------------------------------
   Deux blocs la posaient ici, sur [data-theme="light"] .accueil et
   sur :root:not([data-theme="light"]) .accueil, et le commentaire
   ci-dessus disait sa portée : « le <body class="accueil"> de
   index.html, et lui seul ».

   Elle est désormais déclarée dans :root et dans
   [data-theme="light"], donc valable pour les 110 pages. Les deux
   blocs qui étaient ici n'auraient fait que réécrire les mêmes
   valeurs un peu plus loin dans la cascade : deux sources de vérité
   pour une seule palette, et la garantie qu'un jour l'une des deux
   serait oubliée. Ils sont retirés.

   Ce qui reste ci-dessous est ce qui est vraiment propre à
   l'accueil : quelles ZONES de la page portent quel cran de
   surface. Cela, aucune autre page ne le partage. */

/* LA SÉLECTION ARKWER, sur la page : cartes d'un cran détachées. */
.accueil .selection-arkwer {
    --carte-surface: var(--acc-carte-page);
}

/* Son filet d'ouverture ne sépare plus rien : les changements de
   surface font ce travail. */
.accueil .selection-arkwer .category-header {
    border-top: 0;
}

/* LES FILTRES ET LE CATALOGUE, sur la surface. La zone est déjà
   pleine largeur : un fond suffit. */
.accueil .catalog-filter-scope {
    --carte-surface: var(--acc-carte-surface);
    padding: clamp(26px, 3vw, 44px) 0 clamp(22px, 2.6vw, 38px);
    background: var(--acc-surface);
}

/* Pilules sur fond de contrôle — hors état actif, pour ne rien
   écraser du style d'un filtre sélectionné. */
.accueil .catalog-filter-scope .filter-pill:not(.active) > .filter-pill-toggle:not(.active) {
    background: var(--acc-controle);
}

/* POUR VOUS, sur la surface. Section centrée : l'ombre portée étend
   le fond d'un bord à l'autre, le clip-path le coupe net en haut et
   en bas. Le contenu ne bouge pas, l'ombre n'entre pas dans le
   défilement horizontal. */
.accueil #reco-accueil {
    --carte-surface: var(--acc-carte-surface);
    padding-top: clamp(26px, 3vw, 44px);
    padding-bottom: clamp(26px, 3vw, 44px);
    background: var(--acc-surface);
    box-shadow: 0 0 0 100vmax var(--acc-surface);
    clip-path: inset(0 -100vmax);
}


/* --- LE CATALOGUE EN QUATRE LIGNES --------------------------

   La grille reçoit tout le catalogue, les filtres portent donc sur
   l'ensemble des pièces ; seules les quatre premières lignes de
   cartes VISIBLES sont montrées. Les filtres écartent une carte par
   style="display: none" sans la retirer du DOM : « of :not(...) »
   ne compte que les autres, les quatre lignes restent pleines quel
   que soit le filtre. Colonnes : 5 au-delà de 1 199 px, 3 jusqu'à
   1 199, 2 jusqu'à 768 — soit 20, 12 et 8 pièces. */

/* LA BARRE DE FILTRES SUIT LES GOUTTIÈRES DES SECTIONS.
   Défaut antérieur : les paliers 25 / 18 px de
   « .catalog-filter-scope > .filter-bar » sont écrits AVANT la
   règle de base à 40 px, qui les écrase à spécificité égale. Cette
   règle vit après la base, et ne concerne que l'accueil (seule page
   à .catalog-filter-scope). */
@media (max-width: 1000px) {
    .catalog-filter-scope > .filter-bar {
        padding-left: 25px;
        padding-right: 25px;
    }
}

@media (max-width: 700px) {
    .catalog-filter-scope > .filter-bar {
        padding-left: 18px;
        padding-right: 18px;
    }
}

/* La section reprend la géométrie des sections ; sa marge haute
   négative reproduit « .filter-bar + .products » : les montants de
   la grille viennent buter sur le filet de la barre. */
.accueil-catalogue-section {
    max-width: 1700px;
    margin: -40px auto 0;
    padding: 0 40px;
}

.accueil-catalogue-section > .accueil-catalogue {
    border-top: 0;
}

.accueil-catalogue > .card:nth-child(n + 21 of .card:not([style*="none"])) {
    display: none;
}

@media (max-width: 1199px) {
    .accueil-catalogue > .card:nth-child(n + 13 of .card:not([style*="none"])) {
        display: none;
    }
}

@media (max-width: 768px) {
    .accueil-catalogue > .card:nth-child(n + 9 of .card:not([style*="none"])) {
        display: none;
    }
}

/* « VOIR PLUS » : un lien compact, aligné à droite sous la grille,
   à toutes les largeurs. */
.accueil-catalogue-section > .accueil-voir-plus {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    margin: 6px 0 0;
    padding: 0;
    border: 0;
}

@media (max-width: 1000px) {
    .accueil-catalogue-section {
        padding: 0 25px;
    }
}

@media (max-width: 700px) {
    .accueil-catalogue-section {
        padding: 0 18px;
    }
}

/* --- L'OFFRE, DANS LE PANIER -------------------------------

   Posée AU-DESSUS du champ de code, et seulement si le membre
   a un bon disponible. Elle ne remplace pas le champ : elle
   évite d'avoir à retrouver son code ailleurs. */

.panier-offre:not(.hidden) {
    display: block;
    margin: 1.1rem 0 0;
    padding: .9rem 1rem;
    border: 1px solid rgba(var(--gold-rgb), .4);
    border-radius: 8px;
}

.panier-offre-titre {
    margin: 0;
    font-family: "Anton", sans-serif;
    font-size: .95rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ink);
}

.panier-offre-detail {
    margin: .2rem 0 .7rem;
    font-size: 12px;
    color: var(--grey);
}

.panier-offre-liste {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.panier-offre-bouton {
    flex: 1 1 auto;
    min-height: 44px;
    padding: 11px 16px;
    border: 1px solid var(--ink);
    border-radius: 8px;
    background: var(--ink);
    color: var(--accent-ink);
    font-family: inherit;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    cursor: pointer;
    transition: background var(--transition);
}

@media (hover: hover) and (pointer: fine) {
    .panier-offre-bouton:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
}


/* --- MES OFFRES, DANS MON ARKWER ---------------------------

   Une offre n'est pas un coupon : c'est un avantage personnel.
   La carte dit d'abord ce qu'elle rapporte, puis à quoi elle
   sert, puis le code — qui reste l'élément à copier, donc le
   plus lisible après le bénéfice.

   Une offre utilisée ne disparaît pas : elle s'estompe et le
   dit. Savoir qu'on a déjà profité d'un avantage fait partie
   de son historique. */

.compte-offres-groupe {
    margin: 0 0 1.6rem;
}

.compte-offres-groupe-titre {
    margin: 0 0 .35rem;
    font-family: "Anton", sans-serif;
    font-size: 1.15rem;
    line-height: 1.1;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--ink);
}

.compte-offres-groupe-texte {
    margin: 0 0 1.1rem;
    font-size: .85rem;
    color: var(--grey);
}

.compte-offre {
    padding: 1.2rem 1.3rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--carte-surface);
}

.compte-offre + .compte-offre { margin-top: .8rem; }

.compte-offre-utilisee { opacity: .55; }

.compte-offre-tete {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
}

.compte-offre-valeur {
    margin: 0;
    font-family: "Anton", sans-serif;
    font-size: 1.35rem;
    line-height: 1.05;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ink);
}

.compte-offre-nom {
    margin: .15rem 0 0;
    font-size: .85rem;
    color: var(--grey);
}

.compte-offre-code {
    margin: 1rem 0 .2rem;
    font-family: "Anton", sans-serif;
    font-size: 1.15rem;
    letter-spacing: .14em;
    color: var(--gold);
    user-select: all;
    overflow-wrap: anywhere;
    cursor: copy;
}

.compte-offre-plafond {
    margin: 0;
    font-size: .8rem;
    color: var(--grey);
}

.compte-offre-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .8rem;
    margin-top: 1rem;
}

.compte-offre-copier {
    min-height: 44px;
    padding: 11px 18px;
    border: 1px solid var(--ink);
    border-radius: 8px;
    background: var(--ink);
    color: var(--accent-ink);
    font-family: inherit;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    cursor: pointer;
    transition: background var(--transition);
}

.compte-offre-copier.compte-code-copie {
    background: none;
    color: var(--ink);
}

.compte-offre-utiliser {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--ink);
    text-decoration: underline;
    text-decoration-color: rgba(var(--ink-rgb), .35);
    text-underline-offset: 5px;
}

.compte-offre-etat {
    flex: 0 0 auto;
    font-size: var(--t-micro);
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--grey);
}


/* L'ACCÈS AUX OFFRES DEPUIS L'APERÇU

   Une ligne, pas un bandeau. Le client n'a rien à décider
   ici : on lui dit qu'il a quelque chose, et où le trouver.
   Un encart promotionnel à cet endroit lui vendrait ce qu'il
   possède déjà.

   Le filet d'or est la seule marque d'attention : il suffit à
   la distinguer sans faire concurrence à la commande en cours,
   qui reste la première chose de la page. */

/* :not(.hidden) : même raison que pour l'action du bandeau.
   Sans lui, l'accès s'afficherait aussi aux comptes qui n'ont
   aucune offre — en promettant un avantage qui n'existe pas. */
.compte-offres-acces:not(.hidden) {
    display: flex;
    align-items: baseline;
    gap: .7rem;
    min-height: 44px;
    padding: 13px 16px;
    margin: 0 0 clamp(20px, 2vw, 28px);
    border: 1px solid var(--line);
    border-left: 2px solid var(--gold);
    border-radius: var(--radius);
    background: var(--carte-surface);
    text-decoration: none;
}

.compte-offres-acces-titre {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--ink);
}

.compte-offres-acces-detail {
    flex: 1 1 auto;
    font-size: .8rem;
    color: var(--grey);
}

.compte-offres-acces-fleche {
    flex: 0 0 auto;
    color: var(--ink);
}

/* --- LA SÉLECTION ARKWER ----------------------------------

   CHANTIER CARTES, 12 ET 13/09/2026.

   ELLE N'A PAS DE CARTE À ELLE. Ses pièces sortent de
   productCardHtml et prennent la carte commune (« GRILLE
   PRODUITS ET CARTE »). Ce qui est écrit ici ne touche que la
   SECTION : son filet d'ouverture, sa rangée unique, son rail
   sur téléphone. Ses colonnes sont celles de toutes les grilles.

   LA MÊME GRILLE SERT AU RAIL « VOUS AIMEREZ AUSSI » DES FICHES
   (.pdp .pdp-rail). Il avait sa propre version — six colonnes
   de 213 px, cellules de 10 px, marque réduite, cartes de 150 px
   sur téléphone : les seules cartes du site qui paraissaient
   sorties d'un autre système. Il suit désormais la grille
   commune, exactement comme la Sélection. */

.selection-arkwer {
    padding-top: clamp(22px, 2.6vw, 36px);
    padding-bottom: 0;
    margin-bottom: clamp(24px, 2.6vw, 36px);
}

/* Le filet qui ouvre la section appartient à son en-tête, donc à
   la colonne de lecture : il part du même bord que le titre et
   la grille, et s'arrête au même bord. Le titre est posé entre ce
   filet et celui de la grille — il ne flotte plus dans un espace
   à part. */
.selection-arkwer .category-header {
    padding-top: clamp(14px, 1.4vw, 18px);
    border-top: 1px solid var(--line);
}

/* UNE RANGÉE, JAMAIS UNE RANGÉE ENTAMÉE.
   La Sélection et le rail des fiches n'ont plus de colonnes à eux :
   ils prennent celles de toutes les grilles (5 / 3 / 2, voir « LA
   GRILLE PAR LARGEUR »). Ils font une seule chose en plus : masquer
   les pièces au-delà de la première rangée. Sous 761 px, le rail
   les remontre toutes. */
.selection-arkwer .products > .card:nth-child(n + 6),
.pdp .pdp-rail > .card:nth-child(n + 6) {
    display: none;
}

@media (max-width: 1199px) {
    .selection-arkwer .products > .card:nth-child(n + 4),
    .pdp .pdp-rail > .card:nth-child(n + 4) {
        display: none;
    }
}

@media (max-width: 768px) {
    .selection-arkwer .products > .card:nth-child(n + 3),
    .pdp .pdp-rail > .card:nth-child(n + 3) {
        display: none;
    }
}

/* --- LES FILTRES, SOUS LA SÉLECTION -----------------------

   Le bloc n'a pas changé d'un caractère : il a changé de place
   dans le document, et le conteneur .catalog-filter-scope l'a
   suivi avec le catalogue, sans quoi les filtres auraient perdu
   les rayons qu'ils pilotent (js/script.js les retrouve par
   bar.closest('.catalog-filter-scope')).

   On lui donne seulement de l'air au-dessus, pour qu'il ne colle
   pas au filet de la sélection. */

#vetements-catalog {
    padding-top: clamp(18px, 2.4vw, 30px);
}

/* --- TÉLÉPHONE --------------------------------------------

   LA SÉLECTION DEVIENT UN RAIL QUI DÉFILE. C'est le seul
   défilement horizontal volontaire de la page : trois cartes de
   110 px empilées sur 375 px ne montrent plus une pièce, et
   deux rangées ont été explicitement écartées.

   La navigation, elle, défile aussi mais sans jamais dépasser
   la fenêtre : c'est la liste qui glisse, pas la page. */

@media (max-width: 760px) {

    /* Téléphone : pas de seconde barre sous l'en-tête ; les cinq
       entrées acheteur restent dans le menu, univers ACHETER. */
    .mainnav {
        display: none;
    }

    /* Une regle ancienne fixe .brand img a 34 px sur petit
       ecran — elle datait dun logo image precedent et sa
       specificite (0,1,1) battait .brand-logo. A 34 px dans un
       en-tete de 110 px, la marque devenait lelement dominant.
       On la ramene a lechelle de la barre. */
    .brand .brand-logo {
        height: 19px;
    }

    .promo-bar {
        padding: 10px clamp(12px, 4vw, 20px);
    }

    .promo-bar-texte {
        font-size: 12px;
    }

    .promo-bar-texte strong {
        font-size: 14px;
    }

    /* LE RAIL.
       Mêmes cartes, mêmes filets : seule la grille devient une
       rangée qui glisse, parce que cinq colonnes de 70 px ne
       montrent plus un vêtement. Une seule règle pour les trois
       endroits qui en ont un : la Sélection, le rail des fiches,
       et les suggestions de l'espace client (qui passaient à
       deux colonnes de mini-cartes).

       66vw : la pièce reste grande, et le bord de la suivante
       suffit à dire qu'on peut faire défiler. Le rail reste dans
       la colonne de lecture, entre les mêmes bords que le reste
       de la page. */
    .selection-arkwer .products,
    .pdp .pdp-rail,
    .compte-bloc-decouverte .products,
    #compte-favoris-apercu {
        display: flex;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scroll-snap-type: x proximity;
        scrollbar-width: none;
    }

    .selection-arkwer .products::-webkit-scrollbar,
    .pdp .pdp-rail::-webkit-scrollbar,
    .compte-bloc-decouverte .products::-webkit-scrollbar,
    #compte-favoris-apercu::-webkit-scrollbar {
        display: none;
    }

    /* Les paliers larges masquent les pièces au-delà des
       colonnes ; le rail les remontre toutes, à spécificité
       égale. */
    .selection-arkwer .products > .card:nth-child(n + 3),
    .pdp .pdp-rail > .card:nth-child(n + 3) {
        display: flex;
    }

    .selection-arkwer .products > .card,
    .pdp .pdp-rail > .card,
    .compte-bloc-decouverte .products > .card,
    #compte-favoris-apercu > .card {
        flex: 0 0 66vw;
        max-width: 300px;
        scroll-snap-align: start;
    }

}


/* =========================================================
   BACK-OFFICE — L'ACCUEIL, PLACEMENT DES ANNONCES

   Cet écran montre la page d'accueil telle qu'elle est servie :
   les cartes sont les vraies cartes du site (.card, fabriquées
   par carteProduitElement), posées dans la vraie grille
   (.products). Rien n'est redessiné ici — on ajoute seulement
   ce qu'exige la manipulation : un rang lisible, deux actions,
   et les trois états du glisser-déposer.

   Une carte de catalogue est un lien vers une fiche et porte un
   bouton panier. Dans le back-office, ni l'un ni l'autre n'a de
   sens : le lien est neutralisé en JavaScript (clic capté), le
   bouton panier est retiré de l'affichage — le laisser visible
   proposerait une action qui n'existe pas ici.
========================================================= */

.admin-accueil-bloc {
    margin: 0 0 34px;
}

.admin-accueil-bloc-tete {
    margin: 0 0 12px;
}

.admin-accueil-bloc-tete h3 {
    margin: 0 0 4px;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
}

/* CINQ COLONNES, COMME LA PAGE. L'écran promet de montrer
   l'accueil tel qu'il est servi : une grille qui se remplirait
   toute seule donnerait sept cartes par ligne et quatre lignes
   qui ne correspondraient à rien de ce que voit le visiteur.
   Les colonnes ne se réduisent qu'en dessous des largeurs où la
   page elle-même se réduit. */
.admin-accueil-grille {
    grid-template-columns: repeat(5, minmax(0, 1fr));
}

.admin-accueil-carte {
    position: relative;
    cursor: grab;
}

.admin-accueil-carte:active {
    cursor: grabbing;
}

/* Le lien reste dans le marquage — c'est la carte du site — mais
   il ne doit pas se comporter en lien ici. */
.admin-accueil-carte .card-lien {
    pointer-events: none;
}

.admin-accueil-carte .card-panier {
    display: none;
}

/* LE RANG. C'est le seul repère qui relie les deux grilles : la
   pièce n° 3 de la Sélection est la n° 3 de l'aperçu. */
.admin-accueil-rang {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 6px;
    border-radius: 11px;
    background: var(--ink);
    color: var(--black);
    font-family: "DM Sans", sans-serif;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
}

/* LES DEUX ACTIONS. Au survol pour la souris, à la sélection pour
   le doigt : sans le second chemin, l'écran serait inutilisable
   sur une tablette. */
.admin-accueil-actions {
    position: absolute;
    right: 8px;
    bottom: 8px;
    z-index: 2;
    display: flex;
    gap: 6px;
    opacity: 0;
    transition: opacity .15s ease;
}

.admin-accueil-carte:hover .admin-accueil-actions,
.admin-accueil-carte:focus-within .admin-accueil-actions,
.admin-accueil-carte.est-choisie .admin-accueil-actions {
    opacity: 1;
}

.admin-accueil-carte.est-choisie {
    outline: 2px solid var(--ink);
    outline-offset: -2px;
}

.admin-accueil-carte.est-portee {
    opacity: .45;
}

.admin-accueil-carte.est-cible {
    outline: 2px dashed var(--ink);
    outline-offset: -2px;
}

/* LA BARRE D'ÉTAT. Collante : sur vingt cartes, le bouton
   d'enregistrement ne doit pas être à trois écrans de la carte
   que l'on vient de déplacer. */
.admin-accueil-barre {
    position: sticky;
    top: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin: 0 0 22px;
    padding: 12px 16px;
    border: 1px solid var(--line);
    background: var(--black);
}

.admin-accueil-attente-texte {
    font-size: 13px;
    font-weight: 600;
}

.admin-accueil-barre-actions {
    display: flex;
    gap: 8px;
}

/* Le repère du catalogue : « ✓ SUR LA HOME » se lit d'un coup
   d'œil dans une colonne de trente lignes. */
.admin-accueil-repere {
    white-space: nowrap;
}

/* L'écran de choix montre un tableau, pas un formulaire : il lui
   faut la largeur des colonnes de l'onglet Annonces. */
.admin-drawer-large {
    width: min(1180px, 100%);
}

/* Les mêmes paliers que la page : trois colonnes sous 1 200 px,
   deux sous 769 px. */
@media (max-width: 1199px) {

    .admin-accueil-grille {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

}

@media (max-width: 768px) {

    .admin-accueil-grille {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* Au doigt, les actions restent affichées : il n'y a pas de
       survol pour les révéler. */
    .admin-accueil-actions {
        opacity: 1;
    }

}


/* =========================================================
   LE MOUVEMENT — UN SYSTÈME, PAS DES EFFETS

   CHANTIER MOTION, 30/09/2026.

   CE QUI N'ALLAIT PAS, RELEVÉ AVANT D'ÉCRIRE UNE LIGNE
   — l'apparition au défilement valait 6 px en 0,28 s, et le
     commentaire l'assumait : « elle doit se remarquer le moins
     possible ». Elle ne se remarquait pas du tout ;
   — aucune cascade : 5 déclarations de délai dans toute la
     feuille, donc une grille de vingt pièces surgissait d'un
     bloc, comme un tableau qui s'affiche ;
   — une seule vitesse : 47 transitions sur 169 à .2s. Un survol
     de lien et l'ouverture d'un panneau allaient au même
     rythme, donc rien n'avait de poids ;
   — la courbe dominante, cubic-bezier(.4, 0, .2, 1), est celle
     de Material 2014. C'est la signature du « vieillot ».

   CE QUE CE BLOC POSE
   Trois durées, trois courbes, et trois gestes : l'entrée en
   scène, le survol d'une pièce, l'enchaînement entre deux
   pages. Les 169 transitions existantes ne sont PAS réécrites —
   elles continuent de fonctionner, et basculeront sur les
   jetons au fil des chantiers.

   Écrit en fin de feuille, donc après les règles qu'il
   remplace : c'est voulu, et c'est la seule façon de reprendre
   la main sans toucher aux blocs d'origine.
========================================================= */

:root {

    /* LES TROIS DURÉES. Une réaction n'a pas le même poids qu'une
       entrée en scène : c'est cette hiérarchie qui manquait. */
    --m-vif:   150ms;   /* on répond au doigt : survol, pression   */
    --m-net:   280ms;   /* on change d'état : panneau, bascule     */
    --m-ample: 560ms;   /* on entre en scène : apparition, arrivée */

    /* LES TROIS COURBES. Toutes démarrent vite et finissent
       lentement — c'est ce qui donne la sensation de matière. */
    --m-sortie:  cubic-bezier(.16, 1, .3, 1);      /* franche, moderne */
    --m-doux:    cubic-bezier(.33, 1, .68, 1);     /* posée            */
    --m-ressort: cubic-bezier(.34, 1.42, .64, 1);  /* léger dépassement */
}


/* ---- 1. L'ENTRÉE EN SCÈNE ------------------------------

   Le déplacement passe de 6 à 20 px et la durée de .28 à .56 s :
   assez pour qu'on voie arriver le contenu, trop court pour
   qu'on l'attende. Le retard est posé par js/script.js, une
   carte après l'autre, et plafonné — une grille se déroule, elle
   ne se fait pas désirer.                                     */

.reveal {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity var(--m-ample) var(--m-sortie),
                transform var(--m-ample) var(--m-sortie);
    transition-delay: var(--m-retard, 0ms);
}

.reveal.in-view {
    opacity: 1;
    transform: none;
}

/* LES PIÈCES NE SONT PLUS CONCERNÉES — RETIRÉ LE 01/10/2026.

   Elles arrivaient en cascade, d'un peu plus bas et d'un peu
   plus petit. C'était joli et c'était faux : une apparition
   commence par CACHER ce qu'elle va montrer, et le dernier rang
   d'une grille attendait jusqu'à un demi-seconde. En défilant un
   peu vite, on voyait des cadres blancs à la place des pièces.

   Sur un catalogue, la pièce est le contenu. Elle ne se dévoile
   pas : elle est là. Ces lignes restent en garde — si une règle
   future remettait .reveal sur une carte, elle n'aurait aucun
   effet, et c'est voulu. */
.products > .card.reveal,
.products > .card.reveal.in-view {
    opacity: 1;
    transform: none;
    transition: none;
}


/* ---- 2. LE SURVOL D'UNE PIÈCE --------------------------

   Avant : la photo grandissait de 3,5 % en 220 ms, et c'est
   tout. Maintenant elle respire davantage, plus longuement, et
   une lumière passe dessus — le geste qu'on retrouve sur la
   bande d'offre, pour que le site parle une seule langue.

   Aucune dimension ne change : pas de reflow, pas de décalage
   de la grille. Souris fine uniquement, et jamais en mouvement
   réduit.                                                    */

.card-visuel {
    transition: transform var(--m-ample) var(--m-sortie);
}

.card-visuel::after {
    content: "";
    position: absolute;
    top: -30%;
    bottom: -30%;
    left: -40%;
    width: 28%;
    z-index: 1;
    opacity: 0;
    pointer-events: none;
    transform: skewX(-16deg) translateX(0);
    background: linear-gradient(90deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, .10) 50%,
        rgba(255, 255, 255, 0) 100%);
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {

    .card:not(.card-soldout):hover .card-visuel {
        transform: scale(1.06);
    }

    .card:not(.card-soldout):hover .card-visuel::after {
        animation: m-lumiere 720ms var(--m-doux);
    }

}

@keyframes m-lumiere {
    from { opacity: 0; transform: skewX(-16deg) translateX(0); }
    22%  { opacity: 1; }
    to   { opacity: 0; transform: skewX(-16deg) translateX(560%); }
}


/* ---- 3. L'ENCHAÎNEMENT ENTRE DEUX PAGES ----------------

   Le site est multipage et statique : chaque clic repeignait la
   fenêtre d'un coup. Les transitions de vue natives suppriment
   ce clignotement, et laissent la photo d'une pièce se
   prolonger jusqu'à sa fiche — c'est js/script.js qui donne aux
   deux images le même nom, le temps du saut.

   Aucune dépendance, aucun script de transition : les
   navigateurs qui ne savent pas faire naviguent comme avant.
   La déclaration vit dans une requête de média, donc un
   visiteur qui demande moins d'animation n'en a aucune.      */

@media (prefers-reduced-motion: no-preference) {

    @view-transition { navigation: auto; }

}

::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: var(--m-net);
    animation-timing-function: var(--m-doux);
}

/* La photo en vol : plus longue que le fondu de la page, pour
   qu'on la suive des yeux d'un écran à l'autre. */
::view-transition-group(piece-en-vol) {
    animation-duration: 520ms;
    animation-timing-function: var(--m-sortie);
}

::view-transition-old(piece-en-vol),
::view-transition-new(piece-en-vol) {
    animation-duration: 520ms;
    animation-timing-function: var(--m-sortie);
}


/* ---- CE QUE VOIT UN VISITEUR QUI EN DEMANDE MOINS ------
   Rien ne bouge : le contenu est posé, la photo ne grandit pas,
   les pages ne s'enchaînent pas. Écrit en dernier, donc au-dessus
   de tout ce qui précède.                                     */

@media (prefers-reduced-motion: reduce) {

    .reveal,
    .products > .card.reveal {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .card-visuel { transition: none; }
    .card-visuel::after { animation: none; opacity: 0; }

    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) {
        animation: none !important;
    }

}


/* =========================================================
   FILTRER — REPRISE DE L'ESTHÉTIQUE, 30/09/2026

   TROIS DÉFAUTS RELEVÉS, PAS SUPPOSÉS (1440 px, thème clair) :

   1. UN TROU AU MILIEU DE LA BARRE. Les écarts mesuraient
      32, 8, 8, 8, 8 px : le tri était rejeté à 32 px des
      filtres, les filtres serrés à 8 les uns contre les autres.
      L'œil ne lit pas « un tri puis cinq filtres », il lit une
      barre cassée en deux.

      L'ancienne intention était bonne — distinguer le tri, qui
      ORDONNE, des filtres, qui RETIRENT. Mais on ne distingue
      pas par un trou : on distingue par le traitement. Le tri
      reçoit donc un fond d'encre légère, et l'écart redevient
      celui de tout le monde.

   2. DES CONTRÔLES DE 38 px. Sous la cible tactile de 44 px
      que le reste du site respecte, et visuellement écrasés :
      une capsule plus haute que large de peu paraît tassée.

   3. UN RYTHME TROP SERRÉ. 8 px entre deux capsules de 130 px
      de large, c'est une haie. 10 px et un peu d'air dans les
      capsules laissent la barre respirer.

   Rien d'autre ne bouge : mêmes couleurs, même forme, même
   comportement. On ne rajoute aucun effet.
========================================================= */

.pf-declencheur,
.pf-tri {
    min-height: 44px;
    padding: 0 18px 0 20px;
    transition: background-color var(--m-vif) var(--m-doux),
                border-color var(--m-vif) var(--m-doux),
                color var(--m-vif) var(--m-doux),
                transform var(--m-vif) var(--m-doux);
}

/* Le rythme, régulier d'un bout à l'autre. */
.pf-groupe { gap: 10px; }

/* PLUS DE TROU. Le tri garde une respiration — la moitié d'une
   capsule, pas une capsule entière — et se signale surtout par
   son fond. */
.pf-bloc-tri { margin-right: 10px; }

/* LE TRI SE DISTINGUE PAR SON POIDS, PAS PAR SA DISTANCE.
   Fond d'encre très légère, contour d'un ton au-dessus : on voit
   d'un coup d'œil que ce contrôle n'est pas de la même famille,
   sans casser l'alignement. */
.pf-tri {
    background: var(--pf-doux);
    border-color: var(--pf-bord-fort);
}

.pf-tri:hover { background: rgba(var(--pf-encre-rgb), .1); }

/* L'intitulé « TRIER » recule d'un ton, la valeur choisie reste
   pleine : c'est elle qui porte l'information. */
.pf-tri-intitule { color: var(--pf-sourd); }

/* Une capsule qu'on survole se soulève d'un cheveu. Un pixel,
   pas plus — la barre ne doit pas gigoter au passage du
   curseur. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
    .pf-declencheur:hover,
    .pf-tri:hover { transform: translateY(-1px); }
}

.pf-declencheur:active,
.pf-tri:active { transform: translateY(0); }


/* ---------------------------------------------------------
   LES SEPT AUTRES PAGES PARLENT LA MÊME LANGUE

   Catalogue, rayons, recherche et « À découvrir » portent
   encore l'ancienne barre. Elle fonctionne — on n'y touche
   pas — mais elle ne ressemblait à rien de ce que l'accueil
   montre : boutons rectangulaires à coins de 6 px, texte
   grisé, contrôles de 40 px, aucun fond.

   Passer d'une page à l'autre donnait l'impression de changer
   de site. On aligne donc l'APPARENCE — capsule, hauteur,
   contour, casse — sans rien changer au marquage ni au
   comportement. Le jour où la barre V3 sera déployée partout,
   ces lignes n'auront plus d'objet et sauteront d'un bloc.
--------------------------------------------------------- */

.filter-pill-toggle {
    min-height: 44px;
    padding: 0 18px;
    border-radius: 999px;
    border-color: rgba(var(--ink-rgb), .16);
    background: var(--acc-controle, var(--card));
    color: var(--ink);
    font-weight: 600;
    letter-spacing: .09em;
    text-transform: uppercase;
    white-space: nowrap;
    transition: background-color var(--m-vif) var(--m-doux),
                border-color var(--m-vif) var(--m-doux),
                color var(--m-vif) var(--m-doux),
                transform var(--m-vif) var(--m-doux);
}

/* Le tri porte le même poids que sur l'accueil : fond d'encre
   légère, contour d'un ton au-dessus. */
.filter-pill[data-filter="sort"] > .filter-pill-toggle {
    background: rgba(var(--ink-rgb), .06);
    border-color: rgba(var(--ink-rgb), .34);
}

.filter-pill:hover > .filter-pill-toggle,
.filter-pill.open > .filter-pill-toggle {
    border-color: rgba(var(--ink-rgb), .34);
    color: var(--ink);
}

.filter-pill.active > .filter-pill-toggle {
    border-color: var(--ink);
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
    .filter-pill:hover > .filter-pill-toggle { transform: translateY(-1px); }
}

.filter-pill > .filter-pill-toggle:active { transform: translateY(0); }


/* ---------------------------------------------------------
   LE RÉARRANGEMENT DES PIÈCES

   Chaque carte nommée devient son propre groupe pendant la
   bascule : celles qui restent glissent vers leur nouveau rang,
   celles qui sortent s'effacent sur place, celles qui entrent
   montent. C'est le déplacement réel, rendu visible — aucun
   effet n'est ajouté par-dessus.

   Écrit APRÈS les règles de root et de la photo en vol, donc
   les valeurs propres à celles-ci restent les leurs.
--------------------------------------------------------- */

::view-transition-group(*) {
    animation-duration: 340ms;
    animation-timing-function: var(--m-sortie);
}

::view-transition-group(root) {
    animation-duration: var(--m-net);
    animation-timing-function: var(--m-doux);
}

::view-transition-group(piece-en-vol) {
    animation-duration: 520ms;
    animation-timing-function: var(--m-sortie);
}

/* Une pièce qui entre ou qui sort ne fait que paraître : c'est
   le mouvement des voisines qui raconte le filtrage, pas un
   effet sur elle. */
::view-transition-old(*):only-child,
::view-transition-new(*):only-child {
    animation-duration: 200ms;
}


/* ---------------------------------------------------------
   LA SECONDE PHOTO

   Posée sous la couverture, dans le même cadre et au même
   cadrage. Au survol, c'est la COUVERTURE qui s'efface : la
   seconde ne bouge pas, ne grandit pas de son côté, et les deux
   restent parfaitement superposées.

   Souris fine uniquement. Au doigt, un appui ouvre la fiche —
   on n'y verrait qu'un clignotement avant de changer de page.
--------------------------------------------------------- */

.card-verso {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: 50% 100%;
    opacity: 0;
    pointer-events: none;
    filter: drop-shadow(var(--photo-shadow-card));
    transition: opacity var(--m-net) var(--m-doux);

    /* LA MÊME ÉCHELLE QUE LA COUVERTURE. Celle-ci porte un
       scale(1.07) posé sur sa base — sans lui, le verso
       apparaîtrait plus petit, et la pièce semblerait reculer au
       moment précis où on la regarde. */
    transform: scale(1.07);
    transform-origin: 50% 100%;
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {

    .card:not(.card-soldout):hover .card-verso { opacity: 1; }

    /* La couverture s'efface par-dessus. Un peu plus vite que
       l'arrivée du verso : sans ce décalage, les deux photos se
       mélangent au milieu du passage. */
    /* NEUTRALISÉE LE 01/10/2026 — ET C'ÉTAIT LE DÉFAUT.

       Cette règle effaçait la photo de couverture au survol pour
       laisser voir la seconde. Mais la seconde a été désactivée
       la veille (les miniatures de la photo 2 n'existent pas) :
       il ne restait donc plus RIEN à montrer, et passer la souris
       sur une pièce la faisait disparaître.

       Désactiver une moitié d'un effet sans désactiver l'autre,
       c'est exactement comme ça qu'on casse une page. La règle
       est gardée, inerte, à rétablir le jour où les miniatures
       seront générées — et ce jour-là, les deux moitiés
       reviendront ensemble.

    .card:not(.card-soldout):hover .card-visuel > img:not(.card-verso) {
        opacity: 0;
        transition: opacity var(--m-vif) var(--m-doux);
    }
    */

    .card-visuel > img:not(.card-verso) {
        transition: opacity var(--m-net) var(--m-doux);
    }

}


/* ---------------------------------------------------------
   LES SQUELETTES

   Un cadre de carte, trois lignes de texte, et une lueur qui
   passe lentement. Rien de plus : un squelette qui s'agite
   attire l'œil sur l'attente au lieu de la faire oublier.

   Ils occupent exactement la place des cartes à venir, donc la
   page ne saute pas quand les pièces arrivent.
--------------------------------------------------------- */

.card-squelette {
    pointer-events: none;
}

.card-squelette > .card-visuel,
.card-squelette .squelette-ligne {
    position: relative;
    overflow: hidden;
    background: rgba(var(--ink-rgb), .05);
}

.card-squelette .squelette-ligne {
    height: 10px;
    margin: 0 0 9px;
    border-radius: 3px;
}

.card-squelette .squelette-marque { width: 62%; }
.card-squelette .squelette-taille { width: 34%; height: 8px; }
.card-squelette .squelette-prix   { width: 24%; margin-bottom: 0; }

.card-squelette > .card-visuel::before,
.card-squelette .squelette-ligne::before {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg,
        rgba(var(--ink-rgb), 0) 0%,
        rgba(var(--ink-rgb), .07) 50%,
        rgba(var(--ink-rgb), 0) 100%);
    animation: m-attente 1.6s var(--m-doux) infinite;
}

@keyframes m-attente {
    to { transform: translateX(100%); }
}

/* En mouvement réduit, le cadre reste — il tient la place — mais
   la lueur ne passe pas. */
@media (prefers-reduced-motion: reduce) {
    .card-squelette > .card-visuel::before,
    .card-squelette .squelette-ligne::before { animation: none; opacity: 0; }
}


/* ---------------------------------------------------------
   LES PANNEAUX DE FILTRE, SUR LA COURBE À RESSORT

   Les trois ouvertures — panneau déroulant, tiroir latéral,
   feuille du bas — glissaient sur cubic-bezier(.2, 0, 0, 1) en
   140 à 220 ms : correct, et sans caractère. Elles arrivent
   maintenant avec un dépassement d'un cheveu, celui d'un
   objet qui se pose.

   Le déplacement de départ est légèrement augmenté : un
   ressort sur 4 px ne se voit pas, il se devine.
--------------------------------------------------------- */

.pf-panneau {
    animation: pf-apparaitre var(--m-net) var(--m-ressort) both;
}

@keyframes pf-apparaitre {
    from { opacity: 0; transform: translateY(-8px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

.pf-feuille {
    animation: pf-tiroir 320ms var(--m-ressort) both;
}

@keyframes pf-tiroir { from { transform: translateX(32px); opacity: 0; } }

@keyframes pf-feuille { from { transform: translateY(32px); opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
    .pf-panneau,
    .pf-feuille { animation: none; }
}


/* ---------------------------------------------------------
   LA PRESSION

   Un contrôle qu'on enfonce recule. C'est la plus petite
   attention du lot, et celle qu'on remarque le plus quand elle
   manque : sans elle, un bouton ne répond au doigt qu'une fois
   l'action terminée.

   Portée volontairement étroite : les boutons qui gèrent déjà
   leur propre réaction — l'appel à l'action du bandeau, qui a
   son ombre portée — ne sont pas touchés.
--------------------------------------------------------- */

.card-panier,
.pf-option,
.pf-tri-option,
.pf-effacer,
.pf-tout-effacer,
.pf-puce {
    transition: transform var(--m-vif) var(--m-doux),
                background-color var(--m-vif) var(--m-doux),
                border-color var(--m-vif) var(--m-doux),
                color var(--m-vif) var(--m-doux);
}

@media (prefers-reduced-motion: no-preference) {

    .card-panier:not(:disabled):active,
    .pf-option:active,
    .pf-tri-option:active,
    .pf-effacer:active,
    .pf-tout-effacer:active,
    .pf-puce:active {
        transform: scale(.94);
    }

}


/* ---------------------------------------------------------
   LES TITRES DE SECTION, À L'ARRIVÉE

   Le titre ne monte pas : il se DÉCOUVRE, par le bas, comme
   une ligne qu'on dévoile. C'est le geste de l'édition
   imprimée, et il va mieux à une maison de mode qu'un fondu.

   Le masque est posé sur un conteneur, jamais sur le texte
   lui-même : une propriété clip-path sur un titre coupe aussi
   ses accents et ses jambages.
--------------------------------------------------------- */

.category-header.reveal > * {
    display: block;
    clip-path: inset(0 0 105% 0);
    transform: translateY(.35em);
    transition: clip-path var(--m-ample) var(--m-sortie),
                transform var(--m-ample) var(--m-sortie);
    transition-delay: var(--m-retard, 0ms);
}

.category-header.reveal.in-view > * {
    clip-path: inset(0 0 -20% 0);
    transform: none;
}

/* Le titre porte déjà son propre masque : le fondu générique de
   .reveal ferait double emploi et l'aplatirait. */
.category-header.reveal {
    opacity: 1;
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    .category-header.reveal > *,
    .category-header.reveal.in-view > * {
        clip-path: none;
        transform: none;
        transition: none;
    }
}


/* =======================================================
   LE BACK-OFFICE AU POUCE — IPHONE 15 PRO ET EN DESSOUS
   Chantier du 02/10/2026.

   Relevé AVANT, à 393 × 852, sur les neuf onglets :

     · la barre d'onglets réclamait 1019 px pour 357 offerts,
       en nowrap et sans défilement. C'était LE seul élément
       qui débordait : toutes les pages mesuraient 1037 px de
       large, et c'était elle à chaque fois ;
     · les tableaux : 562 à 898 px naturels pour 355 offerts,
       soit 1,6 à 2,5 fois trop larges ;
     · les cibles tactiles : 27 à 40 px (69 sur 70 dans
       « Annonces ») ;
     · les champs : tous sous 16 px, ce qui fait zoomer iOS
       tout seul à chaque mise au point.

   Rien ici ne change le back-office sur ordinateur, et rien
   ne sort de #admin-shell — vendre.html partage .admin-page,
   .admin-shell et .admin-tabs, et ne doit pas bouger. La
   seule exception est volontaire : .admin-tabs devient
   défilante partout, ce qui ne se voit pas sur une barre qui
   tenait déjà.
======================================================= */

@media (max-width: 760px) {

    /* ---- 1. LA BARRE D'ONGLETS ------------------------
       Elle défile de côté au lieu de pousser la page. Le
       débordement négatif puis le rembourrage la font glisser
       bord à bord : sans ça, le premier et le dernier onglet
       restent collés sous le rail et on croit la barre finie. */
    /* VOLONTAIREMENT NON CADRÉ. vendre.html porte aussi une
       .admin-tabs ; la rendre défilante ne change rien à une
       barre qui tient déjà dans l'écran, et la sauve si elle
       grandit un jour. C'est le seul endroit de ce chantier
       qui sort de .page-admin. */
    .admin-tabs,
    .admin-sous-onglets {
        flex-wrap: nowrap;
        overflow-x: auto;
        overflow-y: hidden;
        scroll-snap-type: x proximity;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        /* Ces quatre valeurs doivent valoir EXACTEMENT le
           rembourrage de .admin-page ci-dessous (16 px). À 18 px
           la barre dépassait de 2 px de chaque côté et la page
           entière gagnait un défilement horizontal — mesuré :
           scrollWidth 398 pour 393 de vue. */
        margin-left: -16px;
        margin-right: -16px;
        padding-left: 16px;
        padding-right: 16px;
    }

    .admin-tabs::-webkit-scrollbar,
    .admin-sous-onglets::-webkit-scrollbar { display: none; }

    .admin-tabs { margin-bottom: 20px; }

    .admin-tab,
    .admin-sous-onglet {
        flex: 0 0 auto;
        scroll-snap-align: start;
        min-height: 44px;
        padding: 10px 15px;
        white-space: nowrap;
    }


    /* ---- 2. LES TABLEAUX DEVIENNENT DES FICHES --------

       Chaque ligne se replie en une fiche : le nom de la
       colonne à gauche, la valeur à droite. Le nom vient de
       l'attribut data-col, que js/admin-mobile.js recopie
       depuis l'en-tête — aucune fonction de rendu n'a été
       touchée, et un tableau ajouté plus tard marche seul.

       On garde volontairement TOUTES les colonnes : c'est
       votre outil, et cacher une donnée pour faire joli vous
       obligerait à ressortir l'ordinateur. */

    #admin-shell .admin-table-wrap {
        overflow-x: visible;
        border: 0;
        border-radius: 0;
    }

    #admin-shell .admin-table,
    #admin-shell .admin-table tbody,
    #admin-shell .admin-table tr,
    #admin-shell .admin-table td {
        display: block;
        width: auto;
    }

    /* L'en-tête quitte l'écran mais reste dans le document :
       c'est lui qui nomme les cellules, et les lecteurs
       d'écran s'en servent. */
    #admin-shell .admin-table thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    #admin-shell .admin-table tr {
        border: 1px solid var(--line);
        border-radius: 14px;
        padding: 4px 14px;
        margin-bottom: 10px;
    }

    #admin-shell .admin-table td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 16px;
        padding: 9px 0;
        border-bottom: 1px solid var(--line);
        text-align: right;
        min-height: 40px;
        /* Un e-mail ou une référence sans espace ne doit pas
           pousser la fiche hors de l'écran : mesuré à 447 px de
           large pour 393 avant cette ligne. On coupe le mot
           plutôt que la page. */
        overflow-wrap: anywhere;
        min-width: 0;
    }

    #admin-shell .admin-table tr td:last-child { border-bottom: 0; }

    /* Le nom de la colonne, à gauche. On lui donne une largeur
       plancher pour que les valeurs s'alignent d'une fiche à
       l'autre, et c'est la VALEUR qui passe à la ligne quand
       elle est longue, jamais l'étiquette. */
    #admin-shell .admin-table td[data-col]:not([data-col=""])::before {
        content: attr(data-col);
        flex: 0 0 auto;
        min-width: 7.5em;
        color: var(--grey);
        font-size: 11px;
        font-weight: 600;
        letter-spacing: 1px;
        text-transform: uppercase;
        text-align: left;
    }

    /* La colonne d'actions n'a pas de titre : elle prend toute
       la largeur, en bas de la fiche, et ses boutons s'étirent
       pour devenir des cibles franches. */
    #admin-shell .admin-table td[data-actions] {
        justify-content: stretch;
        padding-top: 12px;
        padding-bottom: 4px;
        text-align: left;
    }

    #admin-shell .admin-table td[data-actions] > * {
        flex: 1 1 auto;
        justify-content: center;
    }

    /* La photo d'une annonce : à gauche, à taille lisible. */
    #admin-shell .admin-table td > img {
        width: 56px;
        height: 72px;
        object-fit: cover;
        border-radius: 8px;
    }


    /* ---- 3. LES CIBLES TACTILES -----------------------
       44 px est le minimum d'Apple, et ce n'est pas une
       coquetterie : en dessous, on touche le voisin. Relevé
       avant : 27 à 40 px presque partout. */
    #admin-shell .admin-btn,
    #admin-shell .admin-tab,
    #admin-shell .admin-sous-onglet,
    #admin-shell .admin-select,
    #admin-shell .admin-search,
    #admin-shell .admin-table button,
    #admin-shell .admin-table a,
    #admin-shell .admin-panel-actions button,
    #admin-shell .admin-panel-actions a,
    #admin-shell .admin-drawer button {
        min-height: 44px;
    }

    #admin-shell .admin-panel-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 10px;
        width: 100%;
    }

    #admin-shell .admin-panel-actions > * { flex: 1 1 160px; }


    /* ---- 4. LES CHAMPS : 16 px, PAS MOINS -------------
       En dessous de 16 px, iOS zoome la page à la mise au
       point et ne la dézoome jamais. Ce n'est pas réglable
       autrement : c'est la taille du texte qui décide. */
    #admin-shell input,
    #admin-shell select,
    #admin-shell textarea {
        font-size: 16px;
    }


    /* ---- 5. LA PLACE -----------------------------------
       Un écran de 393 px n'a pas de marge à gaspiller. */
    /* .admin-page est partagée avec vendre.html : on cadre. */
    .page-admin .admin-page {
        padding-left: 16px;
        padding-right: 16px;
    }

    #admin-shell .admin-panel-head {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }

    #admin-shell .admin-bloc {
        padding-left: 14px;
        padding-right: 14px;
    }

}


/* ---- 6. POSÉ SUR L'ÉCRAN D'ACCUEIL ---------------------

   data-app est posé par js/app-admin.js quand on tourne dans
   l'application plein écran. Là, et seulement là, il n'y a
   plus de barre d'adresse pour protéger du haut de l'écran :
   le contenu passerait sous l'heure et la batterie, et le bas
   sous la barre d'accueil. env(safe-area-inset-*) vaut zéro
   partout ailleurs ; on garde la règle sous data-app pour que
   l'intention reste lisible. */

html[data-app] body {
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
}

html[data-app] .admin-page {
    padding-left: max(16px, env(safe-area-inset-left));
    padding-right: max(16px, env(safe-area-inset-right));
}

/* En application, la sélection longue d'un libellé ne sert à
   rien et déclenche la loupe d'iOS au moindre appui maintenu.
   Les champs et les valeurs restent sélectionnables : c'est
   là qu'on copie une référence ou un numéro de suivi. */
html[data-app] #admin-shell .admin-tab,
html[data-app] #admin-shell .admin-sous-onglet,
html[data-app] #admin-shell .admin-btn {
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}


/* ---- 7. L'EN-TÊTE DU BACK-OFFICE SUR TÉLÉPHONE --------

   Mesuré : la page entière réclamait 447 px pour 393 de vue, et
   c'est l'EN-TÊTE qui débordait — pas les panneaux, qui tiennent
   à 393. Sur la capture, l'adresse du compte sortait de l'écran
   par la droite. La descente dans l'arbre l'avait d'abord
   manquée : j'en avais écarté les éléments en position fixe pour
   éliminer le grain décoratif, et la navbar est partie avec.

   Il y avait cinq choses sur une ligne : le logo, l'étiquette
   « Administration », la bascule clair/sombre, l'adresse du
   compte connecté et « Se déconnecter ». Sur 393 px, deux de ces
   cinq ne gagnent pas leur place :

     — l'étiquette « Administration » : posée sur l'écran
       d'accueil, l'application s'appelle déjà ADMIN et porte sa
       propre icône. Elle redit ce que l'utilisateur sait ;
     — l'adresse du compte : on administre sa propre boutique
       depuis son propre téléphone. Elle reste sur ordinateur,
       où la place existe.

   « Se déconnecter » reste : c'est la seule des cinq à faire
   quelque chose qu'on ne peut pas faire autrement.

   TOUT est cadré sur .page-admin, posée sur le <body> de
   admin.html et de lui seul. .admin-navbar-tag,
   .admin-current-user et .admin-page sont partagés avec
   vendre.html, et .navbar-top est sur cent neuf pages : sans ce
   cadrage, on retoucherait tout le site pour un écran. */

@media (max-width: 760px) {

    .page-admin .admin-navbar-tag,
    .page-admin .admin-current-user { display: none; }

    /* min-width: 0 aux deux niveaux : sans lui, un enfant flex
       refuse de descendre sous la taille de son contenu et
       repousse la page, même avec du texte tronqué. */
    .page-admin .navbar-top { min-width: 0; gap: 10px; }

    .page-admin .navbar-top-actions {
        min-width: 0;
        gap: 8px;
        flex-shrink: 1;
    }

    /* SE DÉCONNECTER, RÉTABLI SUR TÉLÉPHONE.

       .navbar-account-link est en display:none par défaut et
       n'apparaît qu'au-dessus de 1000 px : sur le site public
       c'est juste, le compte vit dans le menu mobile. Mais
       admin.html n'a PAS de menu mobile, et #admin-signout est
       le seul moyen de sortir d'une session d'administration.
       Résultat mesuré avant ce chantier : sur un téléphone, on
       ne pouvait pas se déconnecter du back-office.

       :not(.hidden) est indispensable. .hidden ne porte que
       0,1,0 de spécificité ; ce sélecteur en porte 0,4,1 et
       rallumerait le bouton AVANT même la connexion. C'est
       exactement le piège du display qui annule un masquage. */
    .page-admin .navbar-top-actions .navbar-account-link:not(.hidden) {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
        padding: 0 4px;
        white-space: nowrap;
    }

}


/* =======================================================
   ANALYTICS — LE TABLEAU DE BORD
   Chantier du 02/10/2026.

   Avant : onze cartes de chiffres toutes de la même taille,
   et trois graphiques en barres étirés à la largeur du
   conteneur, sans grille ni repère. On voyait une forme, pas
   une quantité, et rien ne disait par où commencer.

   Maintenant, trois étages :

     1. la TÊTE — le chiffre d'affaires net en grand, avec son
        évolution contre la même période d'avant, et quatre
        chiffres de contexte à côté ;
     2. les GRAPHIQUES — grille, échelle, dates, et deux formes
        distinctes : l'aire pour ce qui coule, les barres pour
        ce qui se compte ;
     3. le DÉTAIL — tout le reste, entier, en retrait.

   Monochrome, comme le reste du site : la couleur n'apporte
   rien quand il n'y a qu'une série par graphique, et elle
   trahirait la charte. La hiérarchie se fait à la taille et au
   contraste.
======================================================= */

/* ---- 1. LA TÊTE ---- */

.ana-tete {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
    padding: 22px;
    margin-bottom: 26px;
    border: 1px solid var(--line);
    border-radius: 16px;
}

@media (min-width: 900px) {
    .ana-tete {
        grid-template-columns: minmax(260px, 1fr) minmax(0, 1.6fr);
        align-items: center;
        gap: 32px;
        padding: 28px 30px;
    }
}

.ana-tete-principal {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.ana-tete-libelle {
    color: var(--grey);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 1.4px;
    text-transform: uppercase;
}

/* Le seul endroit de l'écran qui a le droit d'être gros. */
.ana-tete-valeur {
    font-family: "Anton", "DM Sans", sans-serif;
    font-size: clamp(34px, 7vw, 52px);
    line-height: 1.02;
    letter-spacing: -0.5px;
    font-variant-numeric: tabular-nums;
}

.ana-tete-note {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    color: var(--grey);
    font-size: 12px;
}

.ana-tete-cote {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px 18px;
    min-width: 0;
}

@media (min-width: 620px) {
    .ana-tete-cote { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.ana-mini {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.ana-mini-libelle {
    color: var(--grey);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 1.2px;
    text-transform: uppercase;
}

.ana-mini-valeur {
    font-size: 19px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    /* Un montant long ne doit pas pousser la colonne voisine. */
    overflow-wrap: anywhere;
}

/* L'évolution. Pas de vert ni de rouge : une hausse de
   remboursements n'est pas une bonne nouvelle, et une couleur
   l'affirmerait. La flèche dit le sens, le lecteur juge. */
.ana-evo {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.4px;
    color: var(--grey);
    white-space: nowrap;
}

.ana-evo-hausse,
.ana-evo-baisse { color: var(--ink); }

.ana-evo-egal { color: var(--grey); }


/* ---- 2. LES GRAPHIQUES ---- */

.ana-graphes {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
    margin-bottom: 30px;
}

@media (min-width: 1000px) {
    .ana-graphes { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.ana-graphe {
    margin: 0;
    padding: 16px 18px 12px;
    border: 1px solid var(--line);
    border-radius: 14px;
    min-width: 0;
}

.ana-graphe-tete {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}

.ana-graphe-titre {
    color: var(--grey);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 1.2px;
    text-transform: uppercase;
}

.ana-graphe-total {
    font-size: 15px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.ana-graphe-plan { position: relative; }

/* height:auto avec un viewBox fixe : le dessin garde ses
   proportions. C'est tout l'objet du changement — l'ancienne
   version l'étirait et l'épaisseur des traits mentait. */
.ana-graphe-svg {
    display: block;
    width: 100%;
    height: auto;
    color: var(--ink);
    overflow: visible;
}

/* Le repère haut de l'échelle, posé en HTML : dans le SVG il
   grandirait avec le dessin. */
.ana-graphe-plafond {
    position: absolute;
    top: -2px;
    right: 0;
    padding: 1px 5px;
    /* Pas de fond : l'étiquette se pose AU-DESSUS de la grille
       haute, sur une zone vide. Un fond demanderait un jeton de
       couleur de page, et il n'en existe pas qui suive les deux
       thèmes — en inventer un ici serait une dette. */
    color: var(--grey);
    font-size: 10px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
}

.ana-grille {
    stroke: currentColor;
    stroke-width: 1;
    opacity: 0.14;
}

.ana-aire {
    fill: currentColor;
    opacity: 0.1;
}

.ana-ligne {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.75;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.ana-barre {
    fill: currentColor;
    opacity: 0.55;
    transition: opacity 120ms ease;
}

.ana-barre:hover { opacity: 1; }

/* Les zones d'info : invisibles, mais elles portent l'infobulle
   — viser un trait d'un pixel au doigt est impossible. */
.ana-cible { fill: transparent; }

.ana-graphe-axe {
    display: flex;
    justify-content: space-between;
    margin-top: 6px;
    color: var(--grey);
    font-size: 10px;
    font-variant-numeric: tabular-nums;
}


/* ---- 3. LE DÉTAIL ---- */

.ana-section-titre {
    margin: 0 0 14px;
    color: var(--grey);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 1.4px;
    text-transform: uppercase;
}


/* ---- SUR TÉLÉPHONE ---- */

@media (max-width: 760px) {

    .ana-tete {
        padding: 18px 16px;
        margin-bottom: 20px;
    }

    .ana-graphe { padding: 14px 14px 10px; }

    /* Trente jours dans 360 px : les barres tomberaient sous le
       pixel. On donne au graphique une hauteur plus généreuse
       plutôt que de réduire le nombre de points — on ne cache
       pas de données pour faire joli. */
    .ana-graphe-svg { min-height: 120px; }

}


/* =======================================================
   ESPACEMENTS DU BACK-OFFICE
   Chantier du 02/10/2026.

   Quinze marges étaient écrites en attribut style="…" dans
   admin.html et js/admin.js. La politique de sécurité du site
   interdit les styles en ligne : le navigateur les refusait
   une par une, en silence pour l'utilisateur et en dix lignes
   rouges dans la console. Les blocs concernés se touchaient.

   Mêmes valeurs, portées par des classes. Le modèle objet
   (element.style.setProperty) reste autorisé, lui — ce n'est
   que l'ATTRIBUT qui est interdit.
======================================================= */

.admin-ecart-xs { margin-top: .6rem; }
.admin-ecart-s  { margin-top: .7rem; }
.admin-ecart-m  { margin-top: .8rem; }
.admin-ecart    { margin-top: 1rem; }
.admin-ecart-l  { margin-top: 1.5rem; }


/* =======================================================
   PAGE D'INSTALLATION DE L'APERÇU — apercu.html

   Trois lignes, parce qu'une liste numérotée n'existait
   nulle part dans le back-office. Tout le reste de la page
   réemploie .admin-gate et ses compagnes.
======================================================= */

.apercu-etapes {
    margin: 0 0 4px;
    padding-left: 1.3em;
    text-align: left;
}

.apercu-etapes li {
    margin-bottom: 6px;
}


/* =========================================================
   LA BANDE D'OFFRE — LE GAIN

   Remplace la composition précédente, dont les quarante-trois
   règles ont été retirées une fois celle-ci en place : chaque
   sélecteur avait d'abord été essayé sur les quarante-cinq
   pages du site, et aucun ne touchait plus rien.

   LA BANDE EST SOMBRE DANS LES DEUX THÈMES. Ce n'est pas un
   oubli : c'est une vitrine, pas une surface de lecture, et
   le jeton d'argent n'a de matière que sur du noir. Elle se
   comporte comme une image à l'intérieur de la page.
   ========================================================= */

.ob2 {
    position: relative;
    overflow: hidden;
    isolation: isolate;

    /* ELLE TOUCHE LES DEUX BORDS, comme au laboratoire. La
       version précédente la rentrait dans un rail avec des
       coins arrondis : c'était la géométrie de l'ancienne
       carte, pas celle qui a été validée. Une bande qui va
       d'un bord à l'autre se lit comme un bandeau ; la même
       posée sur un rail redevient une boîte au milieu de la
       page. */
    margin: clamp(26px, 4vw, 48px) 0;
    width: 100%;
    /* le gris des cartes d'annonces juste au-dessus (24/10/2026) */
    background: var(--carte-surface);
    cursor: pointer;

    /* LE FILET S'ALLUME AU GAIN : la variable est poussée par
       le scénario, la règle ne fait que la lire.

       EN OMBRE INTÉRIEURE, ET NON EN BORDURE. Une bordure
       rétrécit la boîte intérieure, où la toile est posée :
       la scène se dimensionnait sur 183 px et dessinait sur
       181, soit un pour cent d'étirement vertical. */
    border-top: 1px solid rgba(244, 243, 239, var(--ob2-cadre, .12));
    border-bottom: 1px solid rgba(244, 243, 239, var(--ob2-cadre, .12));

    /* Le glissé horizontal fait tourner le jeton ; le vertical
       reste au navigateur, sinon on empêcherait de faire
       défiler la page avec le doigt posé sur la bande. */
    touch-action: pan-y;
}

/* PAS DE LARGEUR NI DE HAUTEUR : une toile est un élément
   remplacé, et un positionnement sur-contraint ne l'étire
   pas — sa taille intrinsèque l'emporte, donc celle de son
   tampon de rendu. Avec width et height à 100 %, elle se
   repliait sur la boîte intérieure et comprimait la scène
   d'un pour cent en hauteur. */
.ob2-toile {
    position: absolute; inset: 0; z-index: 0;
    pointer-events: none;

    /* LA TAILLE D'AFFICHAGE EST CELLE DE LA BANDE, pas celle du
       tampon.

       Un canevas n'a pas de taille CSS tant qu'on ne lui en donne
       pas : il prend celle de son tampon de dessin. Or le moteur
       l'appelle avec setSize(l, h, false) — le « false » interdit
       de toucher au style — et fixe un tampon de l × densité.
       À densité 1 les deux coïncident, et c'est à densité 1 que
       tous mes bancs tournaient. À densité 2 ou 3, c'est-à-dire
       sur tout téléphone récent, le canevas affichait 780×482
       dans une bande de 390×241 : seul le quart haut-gauche
       restait visible, la pièce était dessinée hors champ, et
       elle avait simplement DISPARU de la bande.

       Mesuré à densité 2 et 3 : 780×482 au lieu de 390×241.
       Vu sur une capture : plus de pièce du tout.

       « inset: 0 » ne suffit pas pour un élément remplacé : il
       garde sa taille intrinsèque. Il faut dire la largeur et la
       hauteur. */
    width: 100%; height: 100%;
}

.ob2-voile {
    position: absolute; inset: 0; z-index: 1;
    pointer-events: none; opacity: 0;
    background: radial-gradient(60% 150% at 22% 50%,
        rgba(255, 255, 255, .22) 0%,
        rgba(255, 255, 255, .05) 45%,
        rgba(255, 255, 255, 0) 72%);
}

.ob2-corps {
    position: relative; z-index: 2;

    /* LE CORPS LAISSE PASSER LE POINTEUR.

       Le bouton étiré est un frère de ce bloc, et ce bloc forme
       un contexte d'empilement : aucun z-index donné à un
       enfant ne peut le faire passer au-dessus d'un frère du
       parent. Le « i » recevait donc les clics du bouton étiré
       et ouvrait l'inscription au lieu du détail.

       La hiérarchie se joue donc à la réception, pas à
       l'empilement : le corps est transparent au pointeur, ses
       éléments interactifs le reprennent, et le reste des clics
       tombe sur le bouton étiré en dessous. */
    pointer-events: none;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: clamp(24px, 3vw, 56px);
    padding: clamp(26px, 2.6vw, 38px) clamp(20px, 4vw, 56px);
}

/* LE BLOC DE TEXTE ÉPOUSE SON CONTENU. En case de grille 1fr
   il s'étirait jusqu'au bouton : tous ses enfants sont des
   blocs, donc leur bord droit était celui de la colonne, pas
   celui du texte. La scène mesurait alors quarante pixels de
   vide là où il y en a six cents. */
.ob2-texte { width: fit-content; max-width: 100%; }

/* L'INTERLIGNE EST CELUI DU LABORATOIRE.
   Le site pose 1,4 sur <body> ; la bande garde « normal »,
   sans quoi chacune de ses trois lignes sort un pixel plus
   haute et la bande entière avec. */
.ob2-sur-titre, .ob2-resume, .ob2-google { line-height: normal; }

.ob2-sur-titre {
    margin: 0 0 10px;
    font-size: var(--t-micro); font-weight: 600;
    letter-spacing: .26em; text-transform: uppercase;
    color: var(--grey);
}

/* LE « i » SE RANGE DANS LA LIGNE DE TEXTE.

   Son diamètre est la hauteur des capitales, et tout est en
   em : l'intitulé est en pixels fixes ici, mais la règle tient
   si le corps change. Une boîte en ligne s'assoit sur la ligne
   de base par son BAS, pas par son milieu — d'où le décalage,
   mesuré et non deviné. */
.ob2-info {
    pointer-events: auto;

    /* UN BOUTON NE PREND PAS LA POLICE DE SON PARENT : il
       garde celle du navigateur. Sa taille étant en em, le
       signe sortait trois pixels trop grand et poussait
       toute la ligne du sur-titre. */
    font: inherit;

    display: inline-flex; align-items: center; justify-content: center;
    width: 1.02em; height: 1.02em;
    margin-left: .34em;
    vertical-align: baseline;
    position: relative; top: .33em;
    padding: 0; border: 0; background: none;
    color: var(--grey); cursor: pointer;
    border-radius: 50%;
    transition: color .18s ease;

    /* ET IL PASSE DEVANT. Le montant et le bouton étiré sont
       positionnés eux aussi : sans cet ordre, le « i » cessait
       d'être atteignable. */
    z-index: 4;
}

/* LA CIBLE RESTE GRANDE SANS DÉFORMER LA LIGNE. Le dessin fait
   onze pixels ; la main n'en vise pas onze. */
.ob2-info::after {
    content: ""; position: absolute;
    left: 50%; top: 50%;
    width: 24px; height: 24px;
    transform: translate(-50%, -50%);
}
.ob2-info svg { width: 100%; height: 100%; display: block; overflow: visible; }

@media (hover: hover) { .ob2-info:hover { color: var(--white); } }
.ob2-info:focus-visible {
    color: var(--white);
    outline: none;
    box-shadow: 0 0 0 2px #0B0B0C, 0 0 0 4px var(--white);
}

.ob2-montant-ligne {
    position: relative;
    margin: 0;
    isolation: isolate;

    /* PAS DE PLOMB AUTOUR DU MONTANT. Au laboratoire c'est
       un bloc ; ici il vit dans un paragraphe, donc un bloc
       EN LIGNE, qui hérite de l'interligne du parent — deux
       pixels au-dessus, autant en dessous. Le montant porte
       son propre interligne, le paragraphe n'en impose
       aucun. */
    line-height: 0;
}

/* LA BOÎTE DU CHIFFRE.

   Largeur réservée, posée par le scénario d'après la plus
   large des dix figures. La réserve se prend à GAUCHE : le
   chiffre reste collé à sa monnaie, et c'est le blanc devant
   lui qui se résorbe à mesure qu'il grandit. L'inverse
   laissait un trou entre « 200 » et « € » une fois le compte
   fini. */
.ob2-chiffre {
    display: inline-block;
    text-align: right;
    margin-right: .14em;
    font-variant-numeric: tabular-nums;
    will-change: transform;
}

.ob2-montant {
    display: inline-block;
    font-family: "Anton", sans-serif; font-synthesis: none; font-weight: 400;
    font-size: clamp(34px, 4.2vw, 62px); line-height: .9; letter-spacing: .005em;
    text-transform: uppercase; color: #FFF;
    font-variant-numeric: tabular-nums;
    will-change: transform;
}

/* LE REFLET QUI TRAVERSE LES LETTRES.

   Pas une couche posée dessus : un reflet DANS le métal des
   lettres. Un blanc plein ne peut pas briller — il faut que la
   matière soit un peu en dessous du blanc pour que l'éclat se
   voie. C'est pour ça que les machines écrivent leurs montants
   en métal et jamais en blanc plat.

   LE DÉGRADÉ DOIT TOUJOURS COUVRIR LES GLYPHES : il fait trois
   fois leur largeur et ne se répète pas, donc entre 0 et 100 %
   il couvre, au-delà il sort — et comme la couleur est
   transparente, le montant disparaîtrait. */
.ob2-montant.ob2-gagne {
    background-image: linear-gradient(100deg,
        #cfcec9 0%, #e8e7e3 30%, #ffffff 46%,
        #ffffff 54%, #e8e7e3 70%, #cfcec9 100%);
    background-size: 300% 100%;
    background-position: var(--ob2-eclair, 100%) 0;
    background-repeat: no-repeat;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

/* LES RAYONS DU GAIN.

   La signature des machines : la combinaison gagnante fait
   jaillir des rayons. Un dégradé conique répété donne les
   lames, un masque radial en éteint le bord — sans ce masque
   on obtient une roue de vélo, pas une lueur. Ils sont
   DERRIÈRE le nombre. */
.ob2-rayons {
    position: absolute; z-index: -2;
    left: 50%; top: 50%;
    width: clamp(240px, 26vw, 400px); aspect-ratio: 1;
    transform: translate(-50%, -50%) scale(.3);
    opacity: 0; pointer-events: none;
    background: repeating-conic-gradient(from 0deg,
        rgba(255, 255, 255, .3) 0deg 3.4deg,
        rgba(255, 255, 255, 0) 3.4deg 11deg);
    -webkit-mask-image: radial-gradient(closest-side,
        rgba(0, 0, 0, .25) 0%, rgba(0, 0, 0, .95) 34%,
        rgba(0, 0, 0, .45) 62%, transparent 78%);
    mask-image: radial-gradient(closest-side,
        rgba(0, 0, 0, .25) 0%, rgba(0, 0, 0, .95) 34%,
        rgba(0, 0, 0, .45) 62%, transparent 78%);
}

/* LE HALO. Une lueur, pas un trait : une barre horizontale en
   travers d'un nombre est une rature, quelle qu'ait été
   l'intention. */
.ob2-halo {
    position: absolute; z-index: -1;
    left: 50%; top: 50%;
    width: 150%; height: 420%;
    transform: translate(-50%, -50%) scale(.6);
    opacity: 0; pointer-events: none;
    background: radial-gradient(closest-side,
        rgba(255, 255, 255, .5) 0%,
        rgba(255, 245, 225, .26) 38%,
        rgba(255, 240, 215, .08) 62%,
        rgba(255, 255, 255, 0) 100%);
}

.ob2-resume {
    margin: 12px 0 0;
    font-size: 12px; color: var(--grey);
}

.ob2-place {
    pointer-events: auto;
    position: relative; z-index: 4;
    display: flex; flex-direction: column; gap: 10px;
}

/* LE SOCLE DONNE SA PROFONDEUR AU BOUTON. Sans perspective,
   une rotation en X et en Y n'est qu'un cisaillement : le
   bouton se déforme au lieu de s'incliner. */
.ob2-socle { perspective: 620px; }

/* LE REFLET SPÉCULAIRE SUIT LE POINTEUR, et c'est lui qui
   donne la matière. Sur une surface claire, un blanc ne se
   voit pas — mesuré, quatre pour cent d'écart au plus. C'est
   donc un creux sombre bordé de deux éclaircies, comme une
   arête de métal poli. */
.ob2-reflet {
    position: absolute; inset: -40%;
    z-index: 1; pointer-events: none; opacity: .9;
    background: radial-gradient(38% 60% at var(--rx, 70%) var(--ry, 0%),
        rgba(255, 255, 255, .95) 0%,
        rgba(255, 255, 255, .35) 38%,
        rgba(255, 255, 255, 0) 70%);
    transition: background-position .18s ease-out;
}

/* LE DISPLAY À PART, GARDÉ PAR :not(.hidden). js/offres.js éteint ce
   bouton par .hidden (data-offre-cta-visiteur) ; un display posé sur
   .ob2-bouton seul, écrit plus bas que .hidden, le rallumait. Le reste
   de la règle garde sa spécificité d'origine pour ne déranger aucune
   surcharge (thème clair, petits écrans). */
.ob2-bouton:not(.hidden) { display: inline-flex; }

.ob2-bouton {
    position: relative;
    align-items: center; justify-content: center;
    min-height: 56px; padding: 0 38px;
    border: 0; border-radius: 3px;
    background: linear-gradient(180deg, #FFFFFF 0%, #F2F1ED 46%, #DEDCD6 100%);
    color: #0A0A0A;
    font-family: inherit; font-size: 12px; font-weight: 700;
    letter-spacing: .16em; text-transform: uppercase; white-space: nowrap;
    text-decoration: none; cursor: pointer; overflow: hidden;
    --ob2-lueur: -60%;

    /* L'épaisseur : une arête claire en haut, une sombre en bas,
       et l'ombre portée qui la détache du fond. */
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .9),
        inset 0 -1px 0 rgba(10, 10, 10, .22),
        0 10px 22px -8px rgba(0, 0, 0, .75),
        0 2px 5px -2px rgba(0, 0, 0, .6);

    /* L'appui se sent avant tout calcul : en CSS, donc au
       clavier et au doigt aussi. Une version branchée sur
       mousedown ne répondait qu'à la souris.

       L'inclinaison passe par la même propriété : une seule
       transition, et l'appui l'emporte parce qu'il est plus
       court. */
    transform-style: preserve-3d;
    transition: transform .18s ease-out;
}
.ob2-bouton:active { transition-duration: .09s; }
.ob2-bouton:active { transform: scale(.97); }

/* L'anneau de focus en ombre portée : un contour ne suit pas le
   rayon des angles. */
.ob2-bouton:focus-visible {
    outline: none;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .9),
        inset 0 -1px 0 rgba(10, 10, 10, .22),
        0 0 0 2px #0B0B0C,
        0 0 0 4px var(--white);
}

.ob2-bouton-mot {
    position: relative; z-index: 2; display: block;
    user-select: none; -webkit-user-select: none;
}

/* LA FLÈCHE ne s'ajoute pas à la largeur : sa place est
   réservée par une marge négative qui se résorbe. Sans ça le
   bouton s'élargirait au survol et pousserait tout le reste. */
.ob2-fleche {
    position: relative; z-index: 2;
    width: 15px; height: 15px; flex: 0 0 auto;
    margin-left: 0; margin-right: -15px;
    opacity: 0; transform: translateX(-6px);
    transition: opacity .15s ease-out, transform .15s ease-out, margin .15s ease-out;
}
@media (hover: hover) {
    .ob2-bouton:hover .ob2-fleche {
        opacity: 1; transform: translateX(0);
        margin-left: 9px; margin-right: 0;
    }
}
.ob2-bouton:focus-visible .ob2-fleche {
    opacity: 1; transform: translateX(0);
    margin-left: 9px; margin-right: 0;
}

/* LE BALAYAGE, UNE FOIS, APRÈS LE GAIN. Un clignotement sur une
   bande vue à chaque visite devient un harcèlement ; un reflet
   qui traverse une seule fois dit la même chose sans revenir. */
.ob2-bouton::after {
    content: ""; position: absolute; z-index: 1;
    top: -30%; bottom: -30%; left: 0; width: 46%;
    pointer-events: none;
    background: linear-gradient(104deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, .9) 50%,
        rgba(255, 255, 255, 0) 100%);
    transform: translateX(var(--ob2-lueur, -60%)) skewX(-14deg);
}

.ob2-google {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    font-size: 11px; letter-spacing: .02em; color: var(--grey);
    white-space: nowrap;
}
.ob2-google-g { width: 13px; height: 13px; flex: 0 0 auto; }

/* LE BOUTON ÉTIRÉ : toute la bande ouvre l'inscription. Au-
   dessus du texte pour que le clic porte partout, en dessous
   du « i » et de l'action pour qu'ils gardent le leur. */
.ob2-tout {
    position: absolute; inset: 0; z-index: 1;
    display: block; padding: 0; margin: 0;
    border: 0; background: none;
    cursor: pointer;
}

.ob2-detail {
    pointer-events: auto;
    position: relative; z-index: 4;
    margin: 0;
    padding: 0 clamp(20px, 4vw, 56px) clamp(20px, 2.4vw, 30px);
    font-size: 12.5px; line-height: 1.6; color: var(--grey);
    max-width: 62ch;
}

/* =========================================================
   LA BANDE EN THÈME CLAIR

   Tout ce qui, en sombre, consiste à AJOUTER de la lumière
   doit ici en RETIRER : sur un fond clair, un voile blanc ne
   se voit pas plus qu'un voile noir sur du noir. Mesuré dans
   les deux sens.
   ========================================================= */

:root[data-theme="light"] .ob2 {
    background: var(--carte-surface);
    border-top-color: rgba(28, 28, 28, var(--ob2-cadre, .14));
    border-bottom-color: rgba(28, 28, 28, var(--ob2-cadre, .14));
}

:root[data-theme="light"] .ob2-montant { color: var(--ink); }

/* LA MENTION GOOGLE FONCE EN THÈME CLAIR.

   Écrite en --grey elle sortait à 106 de clarté, pour une
   pièce à 135 : là où la ligne passe devant elle, les deux
   se confondaient. C'est la mention qui se range, pas la
   pièce — celle-ci n'a que sa brillance.

   Elle reste une mention de service : on la fonce, on ne
   la passe pas en noir plein, ce qui la mettrait au même
   rang que le montant. */
:root[data-theme="light"] .ob2-google { color: #35322E; }

/* LE REFLET DU MONTANT : une matière sombre que traverse un
   éclat plus clair. En sombre c'était l'inverse — une matière
   presque blanche et un éclat blanc. */
:root[data-theme="light"] .ob2-montant.ob2-gagne {
    background-image: linear-gradient(100deg,
        #0A0A0A 0%, #2A2A2A 30%, #6E6E6E 46%,
        #6E6E6E 54%, #2A2A2A 70%, #0A0A0A 100%);
}

/* LES RAYONS DEVIENNENT DE L'OMBRE. */
:root[data-theme="light"] .ob2-rayons {
    background: repeating-conic-gradient(from 0deg,
        rgba(20, 20, 20, .26) 0deg 3.4deg,
        rgba(20, 20, 20, 0) 3.4deg 11deg);
}

:root[data-theme="light"] .ob2-halo {
    background: radial-gradient(closest-side,
        rgba(20, 20, 20, .34) 0%,
        rgba(28, 24, 18, .18) 38%,
        rgba(28, 24, 18, .06) 62%,
        rgba(20, 20, 20, 0) 100%);
}

/* LE VOILE AUSSI. Sur #EFEEE9, ajouter du blanc déplace la
   couleur de six niveaux sur 255 — autant dire rien. C'est
   donc un assombrissement bref, et il se lit comme un poids. */
:root[data-theme="light"] .ob2-voile {
    background: radial-gradient(60% 150% at 22% 50%,
        rgba(20, 20, 20, .18) 0%,
        rgba(20, 20, 20, .05) 45%,
        rgba(20, 20, 20, 0) 72%);
}

/* LE BOUTON RESTE À CONTRE-COURANT : c'est le point de
   contraste maximal de la bande, et ce rôle ne dépend pas du
   thème. */
:root[data-theme="light"] .ob2-bouton {
    background: linear-gradient(180deg, #2B2B2B 0%, #171717 46%, #0A0A0A 100%);
    color: var(--white);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .14),
        inset 0 -1px 0 rgba(0, 0, 0, .5),
        0 10px 22px -8px rgba(0, 0, 0, .34),
        0 2px 5px -2px rgba(0, 0, 0, .26);
}
:root[data-theme="light"] .ob2-bouton:focus-visible {
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .14),
        inset 0 -1px 0 rgba(0, 0, 0, .5),
        0 0 0 2px #EFEEE9,
        0 0 0 4px var(--ink);
}

/* Sur un bouton SOMBRE, le reflet redevient une bande claire :
   c'est le creux sombre qui, lui, ne se verrait plus. */
:root[data-theme="light"] .ob2-reflet {
    background: radial-gradient(38% 60% at var(--rx, 70%) var(--ry, 0%),
        rgba(255, 255, 255, .34) 0%,
        rgba(255, 255, 255, .12) 38%,
        rgba(255, 255, 255, 0) 70%);
}
:root[data-theme="light"] .ob2-bouton::after {
    background: linear-gradient(104deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, .28) 50%,
        rgba(255, 255, 255, 0) 100%);
}

@media (max-width: 900px) {
    .ob2-corps { grid-template-columns: minmax(0, 1fr); }
    .ob2-bouton { width: 100%; }
}

/* QUI NE VEUT PAS DE MOUVEMENT N'EN A PAS. Le scénario ne joue
   alors rien du tout ; ces règles garantissent que même une
   couche laissée en route reste invisible. */
@media (prefers-reduced-motion: reduce) {
    .ob2-rayons, .ob2-halo, .ob2-voile { display: none; }
    .ob2-bouton::after { display: none; }
    .ob2-fleche { transition: none; }
}

/* =======================================================
   MESSAGERIE INTERNE

   Trois surfaces, une seule grammaire : le bouton de la fiche
   produit, la boîte de réception du client, le panneau
   d'administration.

   AUCUN FOND, AUCUNE OMBRE, AUCUN RAYON DÉCORATIF. Les bulles de
   conversation sont la seule exception — là, le fond EST
   l'information : c'est lui qui dit qui parle. Partout ailleurs,
   un filet d'un pixel suffit, comme dans le reste du site.
======================================================= */

/* --- LE BOUTON DE LA FICHE PRODUIT ---------------------- */

.pdp-contact {
    margin-top: 18px;
    padding-top: 18px;
    border-top: 1px solid rgba(var(--ink-rgb), .14);
}

/* IL ÉTAIT TROP DISCRET POUR CE QU'IL FAIT.
   ------------------------------------------------------------
   C'était un mot souligné, 34 px de haut, posé sous une carte :
   l'intention d'origine était de ne pas disputer le regard à
   « Ajouter au panier ». Sauf que l'appel du bloc Authenticité, à
   deux centimètres de là, est encadré et fait 44 px. La seule
   action réellement cliquable de la carte vendeur était donc la
   plus faible des deux. Mesuré sur cp58.

   Il prend la même forme que .pdp-lien-action : même hauteur, même
   cadre, mêmes capitales. Les deux appels de la colonne droite se
   lisent enfin comme la même espèce de chose. Il reste en contour,
   donc toujours en retrait du bouton d'achat, qui est plein. */
.pdp-contact-ouvrir {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 0 18px;
    background: none;
    border: 1px solid var(--pdp-trait);
    border-radius: var(--r-controle);
    color: var(--ink);
    font-family: inherit;
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    text-align: left;
    cursor: pointer;
    transition: border-color .2s ease, background .2s ease;
}

.pdp-contact-ouvrir:hover {
    background: rgba(var(--ink-rgb), .06);
    border-color: var(--ink);
}

.pdp-contact-ouvrir:focus-visible {
    outline: 1px solid var(--ink);
    outline-offset: 2px;
}

/* Sous 560 px, comme l'appel authenticité : une cible calée sur son
   texte devient difficile à viser au pouce. */
@media (max-width: 560px) {

    .pdp-contact-ouvrir {
        display: flex;
        justify-content: center;
        width: 100%;
    }

}

.pdp-contact-fleche {
    transition: transform .22s cubic-bezier(.22, 1, .36, 1);
}

.pdp-contact-ouvrir:hover .pdp-contact-fleche {
    transform: translateX(4px);
}

.pdp-contact-form {
    display: flex;
    flex-direction: column;
    gap: 9px;
    margin-top: 14px;
}

.pdp-contact-label,
.compte-messages-form .compte-champ-label {
    font-size: var(--t-micro);
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--grey);
}

/* Un champ de saisie partagé par les trois surfaces : même
   bordure, même rayon discret, même police que les champs de
   commande. */
.pdp-contact-texte,
.compte-messages-texte,
.admin-textarea {
    width: 100%;
    padding: 11px 13px;
    background: none;
    border: 1px solid rgba(var(--ink-rgb), .22);
    border-radius: var(--r-controle);
    color: var(--ink);
    font-family: inherit;
    font-size: var(--t-texte);
    line-height: 1.55;
    resize: vertical;
    box-sizing: border-box;
}

.pdp-contact-texte:focus,
.compte-messages-texte:focus,
.admin-textarea:focus {
    outline: none;
    border-color: var(--ink);
}

.pdp-contact-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 9px;
}

.pdp-contact-envoyer,
.compte-messages-envoyer {
    padding: 11px 20px;
    background: var(--ink);
    border: 1px solid var(--ink);
    border-radius: var(--r-pilule);
    color: var(--black);
    font-family: inherit;
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    cursor: pointer;
}

.pdp-contact-envoyer:disabled,
.compte-messages-envoyer:disabled {
    opacity: .5;
    cursor: progress;
}

.pdp-contact-annuler {
    padding: 11px 18px;
    background: none;
    border: 1px solid rgba(var(--ink-rgb), .26);
    border-radius: var(--r-pilule);
    color: var(--ink);
    font-family: inherit;
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    cursor: pointer;
}

/* La ligne d'état. Trois tons, et le succès n'est pas vert :
   le site n'a pas de couleur d'accent, en inventer une pour un
   message de confirmation jurerait. */
.pdp-contact-note,
.compte-messages-note {
    margin: 10px 0 0;
    font-size: var(--t-etiquette);
    line-height: 1.5;
    color: var(--grey);
}

.pdp-contact-note[data-type="succes"],
.compte-messages-note[data-type="succes"] {
    color: var(--ink);
    font-weight: 500;
}

.pdp-contact-note[data-type="erreur"],
.compte-messages-note[data-type="erreur"] {
    color: #b4463c;
}

/* --- LA BOÎTE DE RÉCEPTION DU CLIENT -------------------- */

.compte-messages-liste {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.compte-message-ligne {
    display: flex;
    flex-direction: column;
    gap: 4px;
    width: 100%;
    padding: 15px 17px;
    background: none;
    border: 1px solid rgba(var(--ink-rgb), .16);
    border-radius: 10px;
    color: var(--ink);
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color .18s ease;
}

.compte-message-ligne:hover {
    border-color: rgba(var(--ink-rgb), .34);
}

/* Un fil non lu se signale par son cadre, pas par un fond :
   une liste où une ligne sur deux est colorée devient illisible
   dès qu'il y a trois réponses en attente. */
.compte-message-ligne-non-lu {
    border-color: var(--ink);
}

.compte-message-haut {
    display: flex;
    align-items: center;
    gap: 10px;
}

.compte-message-sujet {
    font-size: 14.5px;
    font-weight: 600;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.compte-message-pastille {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    background: var(--ink);
    border-radius: 999px;
    color: var(--black);
    font-size: 11px;
    font-weight: 600;
    flex-shrink: 0;
}

.compte-message-extrait {
    font-size: 13px;
    line-height: 1.45;
    color: var(--grey);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.compte-message-bas {
    font-size: 11.5px;
    letter-spacing: .04em;
    color: var(--grey);
}

.compte-messages-retour {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 14px;
    padding: 6px 0;
    background: none;
    border: 0;
    color: var(--grey);
    font-family: inherit;
    font-size: 12.5px;
    cursor: pointer;
}

.compte-messages-retour:hover {
    color: var(--ink);
}

.compte-messages-fil-titre {
    margin: 0 0 14px;
    font-family: "Anton", sans-serif;
    font-size: clamp(17px, 2vw, 22px);
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ink);
}

/* Le fil défile dans sa propre fenêtre : sans plafond, une
   conversation de vingt messages repousserait le champ de
   réponse hors de l'écran. */
.compte-messages-corps,
.admin-fil {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-height: 52vh;
    overflow-y: auto;
    padding: 4px 2px;
}

/* --- LES BULLES ----------------------------------------

   Ici le fond porte l'information : à gauche et sans fond, ce
   que dit ARKWER ; à droite et teinté, ce que dit le client. La
   bulle est bornée à 80 % pour que l'asymétrie reste lisible. */

.compte-message-bulle,
.admin-message {
    max-width: 80%;
    padding: 11px 14px;
    border-radius: 12px;
    border: 1px solid rgba(var(--ink-rgb), .16);
}

.compte-message-bulle-client,
.admin-message-client {
    align-self: flex-end;
    background: rgba(var(--ink-rgb), .06);
}

.compte-message-bulle-arkwer,
.admin-message-arkwer {
    align-self: flex-start;
    background: none;
}

/* Côté administration, les rôles s'inversent : c'est ARKWER qui
   est « nous », donc à droite. */
.admin-message-arkwer {
    align-self: flex-end;
    background: rgba(var(--ink-rgb), .06);
}

.admin-message-client {
    align-self: flex-start;
    background: none;
}

.compte-message-auteur,
.admin-message-entete {
    margin: 0 0 4px;
    font-size: var(--t-micro);
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--grey);
}

.compte-message-texte,
.admin-message-texte {
    margin: 0;
    font-size: 14px;
    line-height: 1.6;
    color: var(--ink);
    /* Les retours à la ligne du client sont respectés, et un mot
       sans espace ne déborde pas de la bulle. */
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.compte-message-date {
    margin: 6px 0 0;
    font-size: 11px;
    color: var(--grey);
}

.compte-messages-form {
    display: flex;
    flex-direction: column;
    gap: 9px;
    margin-top: 16px;
}

.compte-messages-form .compte-messages-envoyer {
    align-self: flex-start;
}

/* --- LE PANNEAU D'ADMINISTRATION ------------------------ */

.admin-fil {
    margin-top: 1rem;
    border: 1px solid rgba(var(--ink-rgb), .14);
    border-radius: 10px;
    padding: 14px;
}

/* Une conversation qui attend une réponse se signale par un
   filet à gauche, pas par un fond : le tableau garde ses
   rayures de lecture. */
.admin-ligne-attente td:first-child {
    box-shadow: inset 3px 0 0 var(--ink);
}

.admin-textarea {
    margin-top: .6rem;
}

@media (max-width: 760px) {

    .compte-message-bulle,
    .admin-message {
        max-width: 92%;
    }

    .compte-messages-corps,
    .admin-fil {
        max-height: none;
    }

    .pdp-contact-actions {
        flex-direction: column;
    }

    .pdp-contact-envoyer,
    .pdp-contact-annuler {
        width: 100%;
    }

}



/* =========================================================
   LA VIGNETTE QUI REJOINT LE PANIER

   Posée en position fixe le temps du vol, puis retirée du
   document par js/cart.js. Elle ne reçoit aucun clic et sort du
   champ des lecteurs d'écran : l'ajout est déjà annoncé par le
   libellé du bouton et par le compteur.

   Elle passe SOUS l'en-tête (z-index 5000) : en arrivant, elle
   glisse derrière lui plutôt que de s'arrêter net sur l'icône.
   ========================================================= */

.vol-panier {
    position: fixed;
    z-index: 4999;
    pointer-events: none;
    border-radius: 10px;
    overflow: hidden;
    will-change: transform, opacity;
}

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

/* Sans photo exploitable : une pastille pleine, pas un carré vide. */
.vol-panier-pastille {
    border-radius: 50%;
    background: var(--ink);
}

/* UN MESSAGE N'A PAS D'IMAGE. Il vole sous une petite note : un
   rectangle à l'encre du site, avec deux lignes de texte suggérées.
   Un rond aurait fait doublon avec la pièce qui part au panier ;
   les deux animations doivent rester distinguables. */
.vol-note {
    border-radius: 4px;
    background: var(--ink);
    background-image:
        linear-gradient(var(--black), var(--black)),
        linear-gradient(var(--black), var(--black));
    background-size: 54% 7%, 36% 7%;
    background-position: 22% 38%, 22% 56%;
    background-repeat: no-repeat;
}

/* L'icône accuse réception. Une seule pulsation, brève : c'est un
   accusé de réception, pas une fête. */
@keyframes cart-icon-pulse {
    0%   { transform: scale(1); }
    38%  { transform: scale(1.22); }
    100% { transform: scale(1); }
}

.cart-icon-pulse {
    animation: cart-icon-pulse .5s cubic-bezier(.34, 1.4, .64, 1);
}

@media (prefers-reduced-motion: reduce) {

    .cart-icon-pulse {
        animation: none;
    }

}


/* =========================================================
   CONTRAT DES ICÔNES DE TRAIT

   LE PROBLÈME, MESURÉ. Sur une seule fiche produit, 30 icônes
   visibles : neuf tailles rendues différentes, et une épaisseur
   de trait À L'ÉCRAN allant de 0,58 à 1,66 px — un écart de 2,9×.
   Deux icônes de même taille (19 px) différaient de 58 %. C'est
   ce qui les faisait paraître issues de jeux différents.

   La cause n'est pas le dessin : toutes les familles de la barre
   sont en viewBox 24×24. C'est que chacune portait son propre
   stroke-width écrit en dur (1,5 · 1,6 · 1,7 · 1,8 · 1,9 · 2,2),
   et que l'épaisseur perçue ne dépend pas de ce nombre seul :

       épaisseur à l'écran = stroke-width × taille rendue / viewBox

   Une icône de 13 px et une de 21 px avec le même stroke-width
   n'ont donc PAS le même trait à l'œil. C'est exactement l'erreur
   qui était faite partout.

   LA RÈGLE. Une seule cible : 1,5 px à l'écran, quelle que soit la
   taille. Le stroke-width se calcule, il ne se choisit pas :

       stroke-width = 1,5 × viewBox / taille rendue

   POURQUOI ICI ET PAS DANS LES 2806 SVG. Un attribut de
   présentation a une priorité INFÉRIEURE à n'importe quelle règle
   CSS : ces lignes l'emportent sans qu'aucun fichier HTML soit
   touché. Une famille dont la taille changerait n'a qu'une valeur
   à recalculer, au même endroit.
   ========================================================= */

/* 26 px rendus, viewBox 24 → 1,5 × 24/26 = 1,38 */
.home-btn svg { stroke-width: 1.38; }

/* 21 px rendus, viewBox 24 → 1,5 × 24/21 = 1,71 */
.cart-icon svg,
.messages-icon svg,
.navbar-profil svg,
.cart-login-invite svg { stroke-width: 1.71; }

/* 19 px rendus, viewBox 24 → 1,89 */
.card-panier svg { stroke-width: 1.89; }

/* 16 px rendus, viewBox 24 → 1,5 × 24/16 = 2,25 */
.pdp-confiance-picto { stroke-width: 2.25; }

/* 18 px rendus, viewBox 24 → 2,00. Le chevron du meme bouton est
   en viewBox 20 : groupe ici il sortait a 1,80, il a sa regle. */
.menu-univers-bouton svg:not(.menu-univers-chevron) { stroke-width: 2; }

/* 18 px rendus, viewBox 20 → 1,5 × 20/18 = 1,67 */
.menu-univers-chevron { stroke-width: 1.67; }

/* 19 px rendus, viewBox 24 → 1,89 (reseaux du pied de page) */
.footer-rich-socials svg { stroke-width: 1.89; }

/* 15 px rendus, viewBox 24 → 2,40 */
.navbar-search svg { stroke-width: 2.4; }

/* 14 px rendus, viewBox 24 → 2,57 */
.sidebar-marque svg { stroke-width: 2.57; }

/* 14 px rendus mais viewBox 16, pas 24 → 1,5 × 16/14 = 1,71.
   Releve : groupee avec les viewBox 24, elle sortait a 2,25. */
.pdp-lien-action-fleche { stroke-width: 1.71; }

/* 13 px rendus, viewBox 24 → 2,77 */
.theme-toggle svg { stroke-width: 2.77; }

/* 11 px rendus, viewBox 24 → 3,27. La plus petite du site : sans
   ce rattrapage son trait tombait a 0,98, presque moitie moins que
   ses voisines. */
.ob2-info svg { stroke-width: 3.27; }

/* Les logos de paiement et les pictogrammes de marque sont des
   formes pleines, pas des traits : ils ne sont pas concernés et
   ne doivent surtout pas être rattrapés ici. */


/* =========================================================
   LES ÉTATS : UN TABLEAU, PAS UN PAVÉ

   CE QUE C’ÉTAIT. Sous le libellé de la fiche, deux lignes de
   texte gris expliquaient UN niveau sur cinq. Elles disaient ce
   que « Très bon état » recouvre, jamais où il se situe — alors
   que c’est la seule question que l’acheteur se pose vraiment.
   Et elles s’imposaient à tout le monde, y compris à qui connaît
   déjà l’échelle.

   CE QUE C’EST. Un mot qu’on peut ignorer, et derrière lui les
   cinq niveaux d’un coup d’œil, par-dessus la fiche — on ne perd
   pas la pièce qu’on regardait.
   ========================================================= */

/* Le libellé et son point, sur une ligne. baseline et non center :
   le point doit s'asseoir sur la même ligne que le texte, pas se
   centrer sur sa hauteur de boîte. */
.condition-ligne {
    display: inline-flex;
    align-items: baseline;
    gap: 9px;
    flex-wrap: wrap;
}

/* RÉDUIT AU POINT. Le bouton n'a plus de texte visible : son nom
   accessible est porté par aria-label, et le titre l'affiche au
   survol. La cible fait 24 px — le minimum praticable — alors que
   le dessin n'en occupe que 14. */
.condition-aide {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    /* Recale la cible sur la ligne de base du texte : sans ça, les
       24 px de hauteur poussent la ligne vers le bas. */
    margin-bottom: -5px;
    background: none;
    border: 0;
    color: var(--grey);
    cursor: pointer;
    transition: color .2s ease;
}

.condition-aide:hover {
    color: var(--ink);
}

.condition-aide:focus-visible {
    outline: 1px solid var(--ink);
    outline-offset: 3px;
}

/* 14 px rendus, viewBox 16 → 1,5 × 16/14 = 1,71 (contrat des icônes). */
.condition-aide-picto {
    width: 14px;
    height: 14px;
    flex: none;
    stroke-width: 1.71;
}

/* LA COUCHE. z-index 300 : au-dessus de l’en-tête (5000 est la
   navbar, mais elle n’est pas au-dessus du voile — celui-ci est en
   position fixe sur toute la fenêtre et vient après dans le flux).
   On reste donc au-dessus de la barre d’achat fixée au bas (200). */
.etats-voile {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 6000;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(10, 10, 10, .78);
}

.etats-voile.ouvert {
    display: flex;
}

/* La page dessous ne défile plus : sans ça, la molette fait glisser
   la fiche derrière la couche, et on la retrouve ailleurs en sortant. */
body.etats-ouverts {
    overflow: hidden;
}

.etats-boite {
    position: relative;
    width: min(560px, 100%);
    max-height: 86vh;
    overflow-y: auto;
    padding: 34px 32px 30px;
    background: var(--black);
    border: 1px solid rgba(var(--ink-rgb), .14);
    border-radius: 14px;
}

/* LA CROIX SE VOIT AVANT D’ÊTRE CHERCHÉE.
   44 × 44, bordée, détachée du texte. La modale de connexion se
   contente de 32 px sans cadre ; ici la sortie doit être le premier
   élément que l’œil trouve, et la cible atteignable au pouce sans
   viser (44 px est le minimum confortable, 24 le strict minimum). */
.etats-fermer {
    position: absolute;
    top: 16px;
    right: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    background: none;
    border: 1px solid rgba(var(--ink-rgb), .22);
    border-radius: 50%;
    color: var(--ink);
    cursor: pointer;
    transition: background .2s ease, border-color .2s ease;
}

.etats-fermer:hover {
    background: rgba(var(--ink-rgb), .08);
    border-color: var(--ink);
}

.etats-fermer:focus-visible {
    outline: 1px solid var(--ink);
    outline-offset: 2px;
}

/* 20 px rendus, viewBox 24 → 1,80 (contrat des icônes). */
.etats-fermer svg {
    width: 20px;
    height: 20px;
    stroke-width: 1.8;
}

.etats-titre {
    margin: 0 56px 6px 0;
    font-family: "Anton", sans-serif;
    font-size: clamp(19px, 2.4vw, 24px);
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ink);
}

.etats-intro {
    margin: 0 0 22px;
    font-size: 13.5px;
    line-height: 1.55;
    color: var(--grey);
}

/* Le tableau. Une <dl> et non une <table> : il n’y a pas deux
   dimensions à croiser, seulement un terme et sa définition. */
.etats-table {
    margin: 0;
}

.etats-nom {
    padding-top: 14px;
    border-top: 1px solid rgba(var(--ink-rgb), .1);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--ink);
}

.etats-table > .etats-nom:first-child {
    padding-top: 0;
    border-top: 0;
}

.etats-def {
    margin: 4px 0 14px;
    font-size: 13.5px;
    line-height: 1.55;
    color: var(--grey-light);
}

.etats-table > .etats-def:last-child {
    margin-bottom: 0;
}

@media (max-width: 560px) {

    .etats-boite {
        padding: 28px 20px 24px;
    }

    .etats-titre {
        margin-right: 52px;
    }

}


/* =========================================================
   LE FLUX « POUR VOUS »

   Une pièce par écran, qu'on fait défiler comme un fil vidéo.
   La forme vient de là ; ce qu'il y a dedans, non.

   DEUX DÉCISIONS QUI SE VOIENT :

     · L'IMAGE EST EN « contain », PAS EN « cover ». Sur une
       vidéo on remplit l'écran. Sur un vêtement, recadrer coupe
       une manche ou un col — exactement ce qu'on vient voir. Le
       vide autour est le prix, et il est volontairement sombre
       pour que la pièce reste le seul point clair.

     · LE CALAGE EST « mandatory ». En « proximity », un petit
       geste laisse la page entre deux pièces : on voit deux
       moitiés et plus aucune image entière. C'est la différence
       entre un fil et une page qui glisse.

   La hauteur est en « dvh » et non « vh » : sur mobile, la
   barre d'adresse se rétracte au défilement et « vh » fige la
   valeur du départ — une diapositive dépasserait de l'écran de
   la hauteur de la barre, et le calage sauterait.
   ========================================================= */

/* LE FIL COMMENCE COMME UNE SECTION DU SITE.

   Un rectangle noir plein écran dès l'arrivée coupait le fil du
   reste : plus d'en-tête, plus de largeur de site, plus rien à
   quoi se raccrocher. Il s'ouvre donc aux dimensions des autres
   sections — et ne prend tout l'écran qu'au premier geste, quand
   on a montré qu'on venait regarder.

   La hauteur de départ laisse voir ce qu'il y a dessous : c'est
   ce débord qui dit « ça continue » bien mieux qu'une consigne. */
.flux {
    /* LA HAUTEUR D'UNE PIÈCE N'EXISTE QU'ICI.

       Les diapositives étaient en « height: 100% ». Un
       pourcentage contre un parent de hauteur automatique vaut
       « auto » : elles se sont effondrées, le contenu total est
       tombé à la hauteur d'un écran, et le fil n'avait plus
       RIEN à faire défiler. Mesuré : scrollHeight == clientHeight.

       Une variable règle les deux à la fois, sans que la valeur
       soit écrite deux fois — et c'est ce doublon qui aurait
       fini par diverger. */
    --flux-h: 78dvh;

    position: relative;
    height: var(--flux-h);
    max-width: 62rem;
    margin: clamp(1.5rem, 4vw, 3rem) auto;
    border-radius: var(--r-surface);
    overflow-y: auto;
    overflow-x: hidden;
    scroll-snap-type: y mandatory;
    overscroll-behavior-y: contain;
    background: #0B0B0C;
    scrollbar-width: none;
}

/* Au premier geste : plein écran, coins perdus, au-dessus de
   tout. « fixed » et non « height:100dvh » — sinon la page
   continue de défiler derrière et les deux se disputent. */
.flux.plein {
    /* --flux-haut : hauteur de l'en-tête, posée par le script. Le fil
       s'ouvre SOUS l'en-tête, qui reste en place : c'est lui qui permet
       de revenir au site. */
    --flux-h: calc(100dvh - var(--flux-haut, 0px));

    position: fixed;
    inset: var(--flux-haut, 0px) 0 0 0;
    z-index: 4900; /* sous l'en-tête (5000) */
    height: var(--flux-h);
    max-width: none;
    margin: 0;
    border-radius: 0;
}

/* Le corps se fige pendant le plein écran : sans ça, la page
   défile DERRIÈRE le fil, et on en sort par accident. */
body.flux-plein { overflow: hidden; }

.flux-sortir {
    position: fixed;
    top: calc(var(--flux-haut, 0px) + .75rem);
    right: 1rem;
    z-index: 4910;
    display: grid;
    place-items: center;
    width: 2.6rem;
    height: 2.6rem;
    padding: 0;
    background: rgba(32, 32, 34, .9);
    border: 0;
    border-radius: 50%;
    color: #F4F3EF;
    cursor: pointer;
}

.flux-sortir svg { width: 1.2rem; height: 1.2rem; }
.flux-sortir:hover { background: rgba(52, 52, 55, .95); }
.flux-sortir:focus-visible { outline: 2px solid #F4F3EF; outline-offset: 3px; }

.flux::-webkit-scrollbar { display: none; }

/* « 100% » ET NON « 100dvh » : la diapositive doit faire la
   hauteur de SON CONTENANT, qui vaut 78 dvh en section et 100
   en plein écran. Figée à 100dvh, elle débordait de la section
   et le calage tombait entre deux pièces. */
.flux-diapo {
    position: relative;
    height: var(--flux-h);
    scroll-snap-align: start;
    scroll-snap-stop: always;
    display: grid;
    place-items: center;
    overflow: hidden;
}

/* LE CADRE : tout s'y accroche.

   L'image, la légende et le rail étaient posés sur la
   diapositive, donc sur la fenêtre. Sur un écran large, l'image
   restait centrée pendant que les boutons filaient au bord : des
   centimètres de vide entre la pièce et ce qui la commande.

   Ils partagent maintenant une boîte de largeur bornée, centrée.
   Le rail suit l'image partout — c'est la correction qui règle
   d'un coup le téléphone et le bureau. */
.flux-cadre {
    position: relative;
    /* 40rem et non 30 : mesuré, une photo carrée plafonnait à
       404 px de large sur un écran de 1440, donc 45 % de la
       hauteur en plein écran — le reste était du vide. Ces
       photos sont limitées par la LARGEUR, pas par la hauteur :
       c'est elle qu'il faut rendre. */
    width: min(100%, 40rem);
    height: 100%;
    margin: 0 auto;
}

/* L'IMAGE PREND CE QUI RESTE, et on le CALCULE au lieu de le
   deviner en pourcentages de fenêtre.

   Les marges étaient en « vh » : sur un écran court elles
   écrasaient la photo, sur un écran long elles la noyaient. Ici
   elles valent exactement la place du rail à droite et celle de
   la légende en bas — deux grandeurs qu'on connaît. */
/* L'IMAGE PREND TOUTE LA LARGEUR, le rail se pose DESSUS.

   Je lui réservais 4 rem à droite. Sur une photo carrée, quatre
   rem de largeur en moins coûtent aussi quatre rem de hauteur :
   l'image tombait à 37 % de l'écran en plein écran, et tout le
   reste était du noir.

   Les fils vidéo font l'inverse — le média remplit, les boutons
   flottent par-dessus. Leur ombre portée suffit à les garder
   lisibles sur une photo claire, et c'est déjà ce qu'ils ont. */
.flux-image {
    position: absolute;
    top: 0;
    right: .5rem;
    bottom: 6.5rem;
    left: .5rem;
    /* PAS DE GRILLE ICI.

       Avec « display:grid; place-items:center », la rangée est
       dimensionnée en « auto » — donc par son contenu. Une
       hauteur en pourcentage sur l'image se résout alors contre
       cette rangée… qui attend la hauteur de l'image : c'est
       circulaire, et le navigateur retombe sur la hauteur
       intrinsèque. Mesuré : 624 de haut dans une boîte de 598,
       et la photo mordait sur la légende.

       En bloc, la boîte a une hauteur définie (haut et bas
       posés), et « height:100% » se résout contre elle. */
    display: block;
    padding: 1rem 0 0;
}

/* « height/width: 100% » ET NON « max-* ».

   Mesuré : avec max-width/max-height à 100 %, l'image sortait à
   624 de haut dans une boîte de 598 — le plafond en pourcentage
   ne la bridait pas, et elle mordait sur la légende. Dans une
   grille centrée, un pourcentage de hauteur ne se résout pas
   comme on l'attend.

   En donnant à la balise la taille EXACTE de sa boîte et en
   laissant « contain » faire le cadrage, il n'y a plus de
   résolution ambiguë : la boîte est la boîte, la photo se loge
   dedans. */
.flux-image img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

/* --- la légende, en bas à gauche --- */

.flux-legende {
    position: absolute;
    /* LE DÉGRADÉ COURT JUSQU'AU BORD, le texte s'arrête avant le
       rail. Je l'avais borné à droite (right: 4.25rem) pour que
       le texte ne passe pas sous les boutons — mais le fond
       s'arrêtait avec lui, et sa coupure verticale se voyait en
       capture, comme un panneau posé contre le rail. Le
       rembourrage de droite fait maintenant la réserve, pas la
       boîte. */
    left: 0; right: 0; bottom: 0;
    padding: 3rem 5rem 1.4rem .75rem;
    color: #F4F3EF;
    /* Un dégradé, pas un bandeau : sur une photo claire le texte
       doit tenir, sur une photo sombre le bandeau se verrait. */
    background: linear-gradient(0deg, rgba(11,11,12,.92) 0%, rgba(11,11,12,.55) 52%, rgba(11,11,12,0) 100%);
    pointer-events: none;
}

.flux-legende a { pointer-events: auto; }

.flux-marque {
    margin: 0 0 .35rem;
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: rgba(244, 243, 239, .72);
}

.flux-nom {
    margin: 0 0 .45rem;
    /* 18,4 px mesures : le nom dominait la legende entiere. Sur
       un fil, la piece EST l'image ; le texte la nomme, il ne
       la remplace pas. On revient au palier « confort », celui
       du texte courant, et le prix redevient son egal. */
    font-size: var(--t-confort);
    font-weight: 600;
    line-height: 1.3;
}

.flux-nom a { color: inherit; text-decoration: none; }
.flux-nom a:hover { text-decoration: underline; text-underline-offset: 3px; }

.flux-prix {
    margin: 0;
    display: flex;
    align-items: baseline;
    gap: .75rem;
    font-size: var(--t-confort);
    font-weight: 600;
}

.flux-etat {
    font-size: var(--t-etiquette);
    font-weight: 400;
    color: rgba(244, 243, 239, .66);
}

/* --- le rail des actions, à droite --- */

/* LE RAIL LONGE L'IMAGE. Il est accroché au cadre, pas à la
   fenêtre : sur grand écran il reste à côté de la pièce au lieu
   de partir au bord de l'écran. */
.flux-rail {
    position: absolute;
    right: .35rem;
    bottom: 6.5rem;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
    z-index: 2;
}

.flux-action {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .3rem;
    width: 3.5rem;
    padding: 0;
    background: none;
    border: 0;
    color: #F4F3EF;
    font-family: inherit;
    font-size: var(--t-micro);
    letter-spacing: .04em;
    text-decoration: none;
    cursor: pointer;
    /* Une ombre portée plutôt qu'un fond : le rail doit rester
       lisible sur une photo claire sans poser de pastilles
       grises par-dessus la pièce. */
    filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .55));
    transition: transform .12s ease-out, opacity .12s ease-out;
}

.flux-action svg { width: 1.85rem; height: 1.85rem; }

.flux-action:hover { transform: translateY(-1px); }
.flux-action:active { transform: scale(.94); }

.flux-action:focus-visible {
    outline: 2px solid #F4F3EF;
    outline-offset: 4px;
    border-radius: var(--r-controle);
}

.flux-action[disabled] { opacity: .38; cursor: default; }
.flux-action[disabled]:hover { transform: none; }

.flux-action.est-dedans { color: #8FD3A6; }

.flux-action-mot { font-weight: 600; }

/* --- le panneau d'informations --- */

/* « :not([hidden]) » N'EST PAS DU ZELE.

   L'attribut « hidden » vaut « display: none » — mais c'est une
   regle du navigateur, de faible poids. N'importe quel
   « display » ecrit dans une feuille la bat, en silence. Ce
   panneau etait donc TOUJOURS affiche : invisible parce que son
   opacite vaut zero, mais bien la, en position fixe sur tout
   l'ecran, a intercepter chaque clic de la page.
   
   Resultat : aucun bouton du fil ne repondait. Mes essais, eux,
   passaient — ils appelaient .click() sur l'element, ce qui
   court-circuite le test de visee. Un vrai doigt n'atteignait
   rien. */
.flux-infos:not([hidden]) {
    position: fixed;
    inset: 0;
    z-index: 5120;
    display: grid;
    place-items: end center;
    background: rgba(8, 8, 10, .6);
    opacity: 0;
    transition: opacity .18s ease-out;
}

.flux-infos.ouvert { opacity: 1; }

.flux-infos-boite {
    width: min(42rem, 100%);
    max-height: 82dvh;
    overflow-y: auto;
    padding: 1.6rem 1.5rem 2rem;
    background: var(--black);
    color: var(--ink);
    border-radius: var(--r-surface) var(--r-surface) 0 0;
    transform: translateY(1.5rem);
    transition: transform .18s ease-out;
}

.flux-infos.ouvert .flux-infos-boite { transform: none; }

.flux-infos-fermer {
    float: right;
    width: 2.2rem; height: 2.2rem;
    margin: -.4rem -.3rem 0 0;
    background: none;
    border: 0;
    color: var(--grey);
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
}

.flux-infos-fermer:hover { color: var(--ink); }

.flux-infos-marque {
    margin: 0 0 .25rem;
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--grey);
}

.flux-infos-nom { margin: 0 0 .3rem; font-size: 1.25rem; font-weight: 600; }
.flux-infos-prix { margin: 0 0 1rem; font-size: var(--t-confort); font-weight: 600; }

.flux-infos-texte {
    margin: 0 0 1.2rem;
    font-size: var(--t-confort);
    line-height: 1.6;
    color: var(--grey-light);
}

.flux-infos-faits { margin: 0 0 1.4rem; }

.flux-infos-faits > div {
    display: grid;
    grid-template-columns: minmax(110px, 34%) minmax(0, 1fr);
    gap: 1rem;
    padding: .75rem 0;
    border-bottom: 1px solid var(--pdp-trait);
}

.flux-infos-faits dt { font-size: var(--t-lien); color: var(--grey); }
.flux-infos-faits dd { margin: 0; font-size: var(--t-texte); color: var(--ink); }

.flux-infos-lien {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 1.1rem;
    border: 1px solid var(--line);
    border-radius: var(--r-controle);
    color: var(--ink);
    text-decoration: none;
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.flux-infos-lien:hover { background: rgba(var(--ink-rgb), .06); }

/* --- le retour d'action --- */

.flux-annonce {
    position: fixed;
    left: 50%;
    bottom: 3.5rem;
    transform: translate(-50%, .5rem);
    z-index: 5130;
    padding: .7rem 1.1rem;
    background: rgba(8, 8, 10, .92);
    color: #F4F3EF;
    border-radius: var(--r-pilule);
    font-size: var(--t-etiquette);
    opacity: 0;
    pointer-events: none;
    transition: opacity .16s ease-out, transform .16s ease-out;
}

.flux-annonce.visible { opacity: 1; transform: translate(-50%, 0); }

/* Meme piege, meme parade : sans « :not([hidden]) », le message
   « aucune piece » s'affichait par-dessus les photos alors meme
   que trente-sept pieces etaient chargees. */
.flux-vide:not([hidden]) {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    padding: 2rem;
    text-align: center;
    color: rgba(244, 243, 239, .7);
    font-size: var(--t-confort);
}

/* --- au clavier, et sans animation --- */

@media (prefers-reduced-motion: reduce) {
    .flux { scroll-behavior: auto; }
    .flux-action,
    .flux-infos,
    .flux-infos-boite,
    .flux-annonce { transition: none; }
}

/* Plus de règle « grand écran » : le cadre borne déjà la largeur
   et le rail s'accroche à lui. La règle qui bornait la
   DIAPOSITIVE laissait le rail au bord de la fenêtre — c'était
   la cause du vide entre la pièce et ses boutons. */


/* =========================================================
   L'INDICE D'ARRIVEE DU FIL

   Un fil vertical n'a aucune affordance : à l'arrêt, rien ne
   dit qu'il y a autre chose sous la première pièce. Un chevron
   qui monte et s'efface le dit en une seconde, sans phrase.

   DEUX FOIS, PAS EN BOUCLE. Une consigne qui clignote sans fin
   cesse d'être une aide et devient un reproche. Elle part au
   premier geste — et d'elle-même au bout de six secondes, si
   le geste ne vient pas.
   ========================================================= */

.flux-indice {
    position: absolute;
    left: 50%;
    /* Juste au-dessus de la légende (≈ 6,5 rem de zone image) :
       il passe sur le bas de la photo, jamais sur le texte. */
    bottom: 7.5rem;
    transform: translateX(-50%);
    z-index: 3;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .15rem;
    text-shadow: 0 1px 6px rgba(0, 0, 0, .75), 0 0 2px rgba(0, 0, 0, .6);
    color: rgba(244, 243, 239, .95);
    font-size: var(--t-etiquette);
    letter-spacing: .1em;
    text-transform: uppercase;
    white-space: nowrap;
    pointer-events: none;
    animation: flux-indice-entre .4s cubic-bezier(.2, .8, .2, 1) both;
    transition: opacity .35s ease-out, transform .35s ease-out;
}

.flux-indice.parti {
    opacity: 0;
    transform: translateX(-50%) translateY(.6rem);
}

@keyframes flux-indice-entre {
    from { opacity: 0; transform: translateX(-50%) translateY(.8rem) scale(.94); }
    to   { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}

/* LE GESTE, MONTRÉ : un doigt pose son point sur la pièce, le
   fait remonter en laissant une traînée, puis s'efface. C'est le
   mouvement qu'on attend de soi — pas un symbole à décoder.

   Il n'y a plus de pastille : sur une photo claire elle faisait une
   tache, et vide à certains instants du cycle elle ressemblait à un
   bouton cassé. Le texte porte sa propre ombre. */
.flux-indice-geste {
    position: relative;
    display: block;
    width: 2.4rem;
    height: 5rem;
}

.flux-indice-trace {
    position: absolute;
    left: 50%;
    bottom: .6rem;
    width: 3px;
    height: 3.6rem;
    margin-left: -1.5px;
    border-radius: 3px;
    background: linear-gradient(0deg, rgba(244, 243, 239, .7), rgba(244, 243, 239, 0));
    transform-origin: 50% 100%;
    opacity: 0;
    animation: flux-trace 2.3s cubic-bezier(.3, .6, .3, 1) var(--cycles, 3) both;
}

.flux-indice-doigt {
    position: absolute;
    left: 50%;
    bottom: .2rem;
    width: 1.7rem;
    height: 1.7rem;
    margin-left: -.85rem;
    border-radius: 50%;
    background: rgba(244, 243, 239, .92);
    box-shadow: 0 0 0 .45rem rgba(244, 243, 239, .22), 0 2px 10px rgba(0, 0, 0, .5);
    opacity: 0;
    animation: flux-doigt 2.3s cubic-bezier(.3, .6, .3, 1) var(--cycles, 3) both;
}

@keyframes flux-doigt {
    0%   { opacity: 0; transform: translateY(0) scale(1.15); }
    12%  { opacity: 1; transform: translateY(0) scale(.88); }
    22%  { opacity: 1; transform: translateY(0) scale(.88); }
    55%  { opacity: 1; transform: translateY(-3rem) scale(.88); }
    66%  { opacity: 0; transform: translateY(-3.4rem) scale(1.1); }
    100% { opacity: 0; transform: translateY(-3.4rem) scale(1.1); }
}

@keyframes flux-trace {
    0%, 20% { opacity: 0; transform: scaleY(0); }
    30%     { opacity: 1; transform: scaleY(.1); }
    55%     { opacity: 1; transform: scaleY(1); }
    68%     { opacity: 0; transform: scaleY(1); }
    100%    { opacity: 0; transform: scaleY(1); }
}

/* Le mot reste lisible pendant que les chevrons battent : l'animer
   lui aussi ferait vibrer le texte, ce qui se lit mal. */
.flux-indice-mot { font-weight: 600; margin-top: .15rem; }

@media (prefers-reduced-motion: reduce) {
    .flux-indice { display: none; }
}


/* --- le bouton d'ouverture, section fermée --- */

.flux-outils {
    position: absolute;
    top: .75rem;
    right: .75rem;
    z-index: 4;
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

/* Les deux flèches au CENTRE du bord droit, l'agrandissement reste en haut. */
/* À 36 % et non 50 : la section fermée est courte, et le centre
   tombait sur le premier bouton de la rail (constaté en capture). */
.flux-outils-fleches {
    /* Milieu de la place libre entre le bouton d'agrandissement (3,6 rem)
       et le haut de la rail (hauteur du cadre − 22,1 rem). Un pourcentage
       fixe tombait sur le premier bouton dès que la section changeait de
       hauteur. */
    /* Désormais accrochées à la diapositive (js/flux.js, replacerOutils) :
       50 % est le centre du rectangle noir, right est son vrai bord.
       Le rail chevauchait pourtant sur téléphone : js/flux.js
       (placerFleches) remplace ce 50 % par le milieu mesuré entre le
       bouton d'agrandissement et le rail. 50 % ne sert qu'en repli. */
    top: 50%;
    transform: translateY(-50%);
}

.flux-ouvrir[disabled] { opacity: .3; cursor: default; }

.flux-ouvrir {
    display: grid;
    place-items: center;
    width: 2.4rem;
    height: 2.4rem;
    padding: 0;
    background: rgba(32, 32, 34, .78);
    border: 0;
    border-radius: 50%;
    color: #F4F3EF;
    cursor: pointer;
    transition: background .14s ease-out, transform .1s ease-out;
}

.flux-ouvrir svg { width: 1.1rem; height: 1.1rem; }
.flux-ouvrir:hover { background: rgba(52, 52, 55, .95); }
.flux-ouvrir:active { transform: scale(.93); }
.flux-ouvrir:focus-visible { outline: 2px solid #F4F3EF; outline-offset: 3px; }

/* Ouverte, la croix de sortie prend la place. */
.flux.plein .flux-outils { display: none; }

/* Section fermée, le fil ne défile pas de lui-même : c'est la page
   qu'on traverse. Le premier geste l'ouvre (js/flux.js). */
.flux:not(.plein) { overflow-y: hidden; }

/* Pendant l'ouverture et la fermeture, la boîte est pilotée pas à pas
   par le script : ni marge ni plafond de largeur ne doivent s'y
   mêler, et le calage attend la fin. */
.flux.en-mouvement {
    margin: 0;
    max-width: none;
    right: auto;
    bottom: auto;
    scroll-snap-type: none;
}

.flux-sortir,
.flux-fleches { animation: flux-apparait .35s ease-out both; }

@keyframes flux-apparait {
    from { opacity: 0; }
    to   { opacity: 1; }
}


.flux-sortir[hidden] { display: none; }


/* =========================================================
   LES FLECHES DU FIL, ET LE FORMULAIRE DE MESSAGE

   LES FLÈCHES. Au doigt on balaie ; à la souris, rien ne dit
   que ça défile et un clic ne fait rien. Deux boutons rendent
   le fil utilisable sans deviner — c'est pour ça que TikTok
   les a sur son site et pas dans son application.

   Elles s'ÉTEIGNENT aux extrémités au lieu de disparaître : un
   bouton qui s'évapore déplace son voisin, et on clique à côté.

   LE FORMULAIRE. Écrire au vendeur renvoyait vers la fiche
   produit — on sortait du fil pour trois lignes et le
   défilement repartait de zéro. Il vit maintenant dans le même
   panneau que les informations.
   ========================================================= */

/* Les flèches n'apparaissent qu'en plein écran : en section, la
   molette de la page fait déjà le travail et deux boutons
   flottants au milieu de l'écran n'auraient rien à voir avec
   elle. */
.flux-fleches {
    position: fixed;
    right: 1rem;
    /* Au centre du bord droit, mais jamais sur la rail : si l'écran est
       court, la paire remonte juste au-dessus de son premier bouton
       (rail = 22,1 rem depuis le bas) avec 4 rem de marge. */
    top: max(calc(var(--flux-haut, 0px) + 7rem), min(calc(50% + var(--flux-haut, 0px) / 2), calc(100dvh - 26.1rem)));
    transform: translateY(-50%);
    z-index: 4905;
    display: none;
    flex-direction: column;
    gap: .6rem;
}

body.flux-plein .flux-fleches { display: flex; }

.flux-fleche {
    display: grid;
    place-items: center;
    width: 2.9rem;
    height: 2.9rem;
    padding: 0;
    background: rgba(32, 32, 34, .92);
    border: 0;
    border-radius: 50%;
    color: #F4F3EF;
    cursor: pointer;
    transition: background .14s ease-out, opacity .14s ease-out, transform .1s ease-out;
}

.flux-fleche svg { width: 1.35rem; height: 1.35rem; }

.flux-fleche:hover { background: rgba(52, 52, 55, .96); }
.flux-fleche:active { transform: scale(.93); }

.flux-fleche:focus-visible {
    outline: 2px solid #F4F3EF;
    outline-offset: 3px;
}

.flux-fleche[disabled] {
    opacity: .3;
    cursor: default;
}

.flux-fleche[disabled]:hover { background: rgba(32, 32, 34, .92); }


/* --- le formulaire de message --- */

.flux-msg-piece {
    margin: 0 0 1.1rem;
    font-size: var(--t-lien);
    color: var(--grey);
}

.flux-msg-form { display: flex; flex-direction: column; gap: .7rem; }

.flux-msg-label {
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--grey);
}

.flux-msg-texte {
    width: 100%;
    padding: .8rem .9rem;
    background: rgba(var(--ink-rgb), .04);
    border: 1px solid var(--line);
    border-radius: var(--r-controle);
    color: var(--ink);
    font: inherit;
    font-size: var(--t-texte);
    line-height: 1.5;
    resize: vertical;
}

.flux-msg-texte:focus-visible {
    outline: 1px solid var(--ink);
    outline-offset: 1px;
}

.flux-msg-envoyer {
    align-self: flex-start;
    min-height: 44px;
    padding: 0 1.4rem;
    background: var(--ink);
    color: var(--black);
    border: 0;
    border-radius: var(--r-controle);
    font: inherit;
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    cursor: pointer;
}

.flux-msg-envoyer[disabled] { opacity: .55; cursor: default; }

.flux-msg-note {
    margin: 0;
    font-size: var(--t-lien);
    color: var(--grey);
}

.flux-msg-note[data-type="erreur"] { color: #b4463c; }


/* Les défauts constatés, dans le panneau du fil. C'est
   l'information qui décide sur de la seconde main : elle ne
   doit pas obliger à sortir du fil pour être lue. */
.flux-infos-defauts {
    margin: 0 0 .5rem;
    font-size: var(--t-etiquette);
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--grey);
}

.flux-infos-defauts-aucun {
    font-weight: 400;
    letter-spacing: normal;
    text-transform: none;
    font-size: var(--t-lien);
}

.flux-infos-liste {
    margin: 0;
    padding-left: 1.1rem;
    font-size: var(--t-texte);
    line-height: 1.6;
    color: var(--grey-light);
}


/* =========================================================
   ZONES DE TOUCHER DE L'EN-TETE

   Mesuré sur les 46 pages, aux cinq largeurs : les commandes de
   l'en-tête font 27×42 (menu), 53×30 (thème), 36×36 (panier),
   65×19 (logo). Un doigt couvre environ 44 px : sous cette taille
   on rate, on déclenche le voisin, et on recommence.

   ON N'AGRANDIT PAS LES ICÔNES, on agrandit la ZONE QUI RÉPOND.

   Une session précédente avait volontairement réduit ces icônes
   à 36 px : à 375 px la barre faisait 410 px pour 375 de
   disponibles, et deux icônes sur trois y tenaient. Les
   regrandir ferait déborder la barre à nouveau. Un pseudo-
   élément transparent, plus grand que le bouton, reçoit le
   toucher à sa place : le dessin et la mise en page ne bougent
   pas d'un pixel.

   LES ÉCARTS TIENNENT. Thème et panier sont à 10 px l'un de
   l'autre ; chacun s'étend de 4 px vers l'autre, soit 8 px en
   tout : leurs zones ne se recouvrent pas. Le menu et le logo
   sont à 28 px — marge largement suffisante.

   SEULEMENT AU DOIGT. À la souris, 44 px de zone invisible
   ferait réagir un bouton quand on passe à côté, ce qui se
   ressent comme un défaut.
   ========================================================= */

/* PLANCHER DE 24 px, À TOUTES LES LARGEURS.

   Au bureau le logo fait 72×21 et l'icône d'accueil 21×21 : sous
   les 24 px de WCAG 2.2 AA, qui valent aussi pour la souris. Un
   pseudo-élément de 24 px minimum corrige sans rien déplacer. Le
   seuil de 44 px, lui, ne vaut qu'au doigt — plus bas. */
.navbar-top a.brand,
.home-btn {
    position: relative;
}

.navbar-top a.brand::after,
.home-btn::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: max(100%, 24px);
    height: max(100%, 24px);
    transform: translate(-50%, -50%);
}

@media (pointer: coarse), (max-width: 1024px) {

    .menu-btn,
    .navbar-top a.brand,
    #theme-toggle,
    .cart-icon,
    .home-btn {
        position: relative;
    }

    .menu-btn::after,
    .navbar-top a.brand::after,
    #theme-toggle::after,
    .cart-icon::after,
    .home-btn::after {
        content: "";
        position: absolute;
        /* Centrée sur le bouton, au moins 44 px dans les deux
           sens : « max » plutôt qu'une valeur fixe, pour qu'un
           bouton déjà plus grand ne soit pas rétréci. */
        left: 50%;
        top: 50%;
        width: max(100%, 44px);
        height: max(100%, 44px);
        transform: translate(-50%, -50%);
    }
}


/* =========================================================
   ZONES DE TOUCHER DU PIED DE PAGE

   Les liens du pied font 18 px de haut, séparés par 12 px de
   marge : un pas de 30 px. Sous les 24 px de WCAG 2.2 (critère
   2.5.8, niveau AA), donc un défaut — et sur téléphone, un doigt
   qui rate et ouvre le lien voisin.

   ON NE LES REMPLIT PAS JUSQU'À 44 px. Le pas n'est que de 30 :
   deux zones de 44 se recouvriraient de 14 px, et dans la
   bande commune le lien du dessous volerait le toucher de celui
   du dessus. Agrandir la mise en page pour y arriver ajouterait
   14 px par lien, soit près de 300 px de pied de page sur
   téléphone.

   La zone est donc calée sur le PAS exactement : 6 px au-dessus,
   6 px au-dessous. Chaque point de la colonne appartient à un
   lien et un seul, la mise en page ne bouge pas, et la zone
   passe de 18 à 30 px.
   ========================================================= */

/* À TOUTES LES LARGEURS, pas seulement au doigt : la norme (WCAG
   2.5.8) vaut aussi pour la souris, et étendre une zone de 6 px
   dans une marge vide ne se remarque pas. Mesuré au bureau : deux
   pages avaient encore des liens de 18 px. */
.footer-rich-column a,
.footer-rich-column button,
.consent-lien-pied {
    position: relative;
}

.footer-rich-column a::after,
.footer-rich-column button::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -6px;
    bottom: -6px;
}

/* Le lien de consentement du bas de page : 18 px de haut. Seule
   la hauteur est étendue, de 4 px de chaque côté — assez pour
   passer sous le seuil, pas assez pour mordre sur ce qui
   l'entoure. */
.consent-lien-pied::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -4px;
    bottom: -4px;
}


/* LE ⓘ DE LA BANDE D'OFFRE.

   11×11 px, posé contre « Offre de bienvenue » : la taille et la
   proximité étaient voulues. Sa zone de toucher, elle, ne
   pouvait pas rester à 11 px — un doigt rate, et la bande entière
   derrière lui mène à l'inscription, pas au détail.

   32 px et non 44 : au-delà, la zone mordrait largement sur le
   texte voisin et sur la bande cliquable. 32 dépasse le plancher
   de 24 sans voler le toucher au reste. */
/* .ob2-info est déjà « position: relative » plus haut : rien à
   redéclarer. */
.ob2-info::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 32px;
    height: 32px;
    transform: translate(-50%, -50%);
}


/* =========================================================
   LE FIL SUR L'ACCUEIL

   La section porte « category-section », donc le mécanisme
   d'apparition lui pose « .reveal » : un transform, même au
   repos (translateY(0) reste un transform). Or tout élément
   transformé devient le repère de ses descendants « fixed » — le
   fil, une fois ouvert en plein écran, se serait calé sur la
   SECTION et non sur la fenêtre. Constaté en mesure, pas en
   lecture. Cette section-là apparaît donc sans mouvement : le fil
   porte déjà sa propre ouverture.
   ========================================================= */
.fil-accueil.reveal,
.fil-accueil.reveal.in-view {
    opacity: 1;
    transform: none;
    transition: none;
}

.fil-accueil .flux:not(.plein) {
    margin-top: clamp(1rem, 2.5vw, 1.75rem);
    margin-bottom: 0;
}


/* Clés d'accès : bouton de connexion (même gabarit que Google) et
   liste du profil. */
.auth-passkey-btn{
    margin-top:8px;
}

.cle-acces-liste{

    margin:0 0 12px;

    padding:0;

    list-style:none;

}

.cle-acces-liste li{

    display:flex;

    align-items:center;

    justify-content:space-between;

    gap:10px;

    padding:8px 0;

    border-bottom:1px solid var(--line);

    font-size:12.5px;

    color:var(--grey-light);

}

.cle-acces-liste li .auth-secondary-btn{

    width:auto;

    margin:0;

    flex:none;

}


@media (max-width: 480px){

    .auth-modal-overlay{ padding:14px; }

    .auth-modal{
        padding:34px 20px 22px;
        border-radius:14px;
    }

    .auth-modal-title{
        margin-bottom:22px;
        font-size:20px;
    }

    .auth-form input{ font-size:16px; }

    .auth-modal{ padding-left:18px; padding-right:18px; }

    /* deux liens trop longs pour une ligne : l'un sous l'autre, sans
       le point de séparation qui resterait orphelin en bout de ligne */
    .auth-confiance-liens{
        flex-direction:column;
        align-items:center;
        gap:8px;
        margin-top:16px;
    }

    .auth-confiance-liens span{ display:none; }

}


/* =========================================================
   AUTHENTICITÉ (accueil) — bande d'attente, 24/10/2026.
   Remplace la grande photographie : une ligne fine, sceau vert,
   question, réponse, lien. Pleine largeur du rail, ~90 px de haut.
   ========================================================= */
.authenticite-bande {
    display: flex;
    align-items: center;
    gap: 18px;
    max-width: 1440px;
    margin: clamp(28px, 4vw, 48px) auto;
    padding: 18px 22px;
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
}

.authenticite-bande-sceau {
    flex: none;
    width: 34px;
    height: 34px;
}

.authenticite-bande-texte {
    flex: 1;
    min-width: 0;
}

.authenticite-bande-titre {
    margin: 0 0 3px;
    font-family: "DM Sans", sans-serif;
    font-size: 16px;
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: 0;
    text-transform: none;
    color: var(--ink);
}

.authenticite-bande-reponse {
    margin: 0;
    font-size: 13px;
    line-height: 1.45;
    color: var(--grey);
}

.authenticite-bande-lien {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    flex: none;
    padding: 10px 16px;
    border: 1px solid var(--line);
    border-radius: 999px;
    color: var(--ink);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .4px;
    text-decoration: none;
    transition: border-color .2s ease, background-color .2s ease;
}

.authenticite-bande-lien:hover,
.authenticite-bande-lien:focus-visible {
    border-color: var(--ink);
    background: rgba(var(--ink-rgb), .04);
}

@media (max-width: 640px) {
    .authenticite-bande {
        flex-wrap: wrap;
        gap: 12px 14px;
        padding: 16px;
    }
    .authenticite-bande-sceau { width: 28px; height: 28px; }
    .authenticite-bande-titre { font-size: 15px; }
    .authenticite-bande-lien { margin-left: 42px; }
}

/* =========================================================
   POUR VOUS EN THÈME CLAIR — couleurs inversées (24/10/2026)
   La page reste blanche ; c'est l'annonce qui prend le gris des
   cartes (--carte-surface), au lieu d'un panneau noir. Les textes
   posés sur la photo passent à l'encre, le dégradé de lisibilité
   devient gris clair. Le thème sombre ne change pas.
   ========================================================= */
:root[data-theme="light"] .flux { background: var(--carte-surface); }

:root[data-theme="light"] .flux-legende {
    color: var(--ink);
    background: linear-gradient(0deg, rgba(243, 243, 243, .96) 0%, rgba(243, 243, 243, .6) 52%, rgba(243, 243, 243, 0) 100%);
}

:root[data-theme="light"] .flux-marque,
:root[data-theme="light"] .flux-etat { color: var(--grey); }

:root[data-theme="light"] .flux-action { color: var(--ink); }
:root[data-theme="light"] .flux-action:focus-visible { outline-color: var(--ink); }
:root[data-theme="light"] .flux-action.est-dedans { color: #1E8A4C; }

:root[data-theme="light"] .flux-indice { color: var(--ink); }
:root[data-theme="light"] .flux-indice-trace { background: linear-gradient(0deg, rgba(28, 28, 28, .45), rgba(28, 28, 28, 0)); }
:root[data-theme="light"] .flux-indice-doigt { background: rgba(28, 28, 28, .85); }
:root[data-theme="light"] .flux-indice { text-shadow: none; }

/* =========================================================
   FILTRER — la grande recherche (24/10/2026)
   Au centre, large, comme un moteur : c'est la première chose de
   la page. Les filtres suivent, puis la grille.
   ========================================================= */
.filtrer-page { padding-top: clamp(28px, 5vw, 56px); }

.grande-recherche {
    position: relative;
    display: flex;
    align-items: center;
    width: min(720px, 100%);
    margin: 0 auto;
}

.grande-recherche-loupe {
    position: absolute;
    left: 22px;
    width: 20px;
    height: 20px;
    color: var(--grey);
    pointer-events: none;
}

.grande-recherche input {
    width: 100%;
    height: 60px;
    padding: 0 56px 0 56px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--carte-surface);
    color: var(--ink);
    font-family: inherit;
    font-size: 18px;
    box-shadow: 0 1px 6px rgba(0, 0, 0, .06);
    transition: border-color .2s ease, box-shadow .2s ease;
    -webkit-appearance: none;
    appearance: none;
}

.grande-recherche input::placeholder { color: rgba(var(--ink-rgb), .45); }

.grande-recherche input:hover { box-shadow: 0 2px 12px rgba(0, 0, 0, .09); }

.grande-recherche input:focus {
    outline: none;
    border-color: var(--ink);
    box-shadow: 0 2px 14px rgba(0, 0, 0, .1);
}

.grande-recherche input::-webkit-search-cancel-button { display: none; }

.grande-recherche-effacer {
    position: absolute;
    right: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--grey);
    cursor: pointer;
}

.grande-recherche-effacer svg { width: 16px; height: 16px; }
.grande-recherche-effacer:hover { color: var(--ink); background: rgba(var(--ink-rgb), .06); }

.grande-recherche-etat {
    min-height: 20px;
    margin: 12px auto 22px;
    font-size: 13px;
    color: var(--grey);
    text-align: center;
}

.products .card.hors-recherche { display: none !important; }

@media (max-width: 640px) {
    .grande-recherche input { height: 52px; font-size: 16px; padding: 0 48px; }
    .grande-recherche-loupe { left: 18px; }
}
.grande-recherche-effacer[hidden] { display: none; }

/* La recherche qui descend puis remonte (js/filtrer.js, 26/10/2026).
   Une seule recherche visible à la fois : sur cette page, celle de la
   barre ne se montre que si <html> porte .recherche-en-haut. On la
   cache par visibility et non par display : la barre garde sa mise
   en page, rien ne bouge autour. */
html:not(.recherche-en-haut) body:has(.grande-recherche) .navbar-search { visibility: hidden; }

/* La grande attend le script pour paraître (elle doit « arriver » de
   la barre). S'il ne tourne pas, elle se montre seule après 1,2 s. */
html:not(.recherche-prete) .grande-recherche:not(.grande-recherche-fantome) {
    visibility: hidden;
    animation: grande-recherche-secours 0s linear 1.2s forwards;
}
@keyframes grande-recherche-secours { to { visibility: visible; } }

.grande-recherche.en-vol { visibility: hidden; }

/* Le fantôme : une copie inerte, posée et redimensionnée image par
   image par le script. Au-dessus de la barre (5000), sous la fenêtre
   de connexion (6500). */
.grande-recherche.grande-recherche-fantome {
    position: fixed;
    z-index: 5500;
    width: auto;
    margin: 0;
    pointer-events: none;
}
.grande-recherche-fantome input { height: 100%; transition: none; }


/* =========================================================
   PROMOTIONS — rendu « soldes » (24/10/2026)
   Rouge franc, visible de loin : pastille en coin de photo, prix
   promo rouge, prix de référence barré, remise. Le rouge est le
   seul rouge du site — il ne sert qu'à la promotion. Le picto est
   « tag » de Lucide (ISC), la bibliothèque installée.
   ========================================================= */
/* Rouge assombri en clair, éclairci en sombre (28/10/2026) : #D7263D
   n'atteignait pas le contraste 4,5:1, ni sur blanc ni sur fond noir, et
   ne suivait pas le thème. Le site est sombre par défaut (js/theme.js) :
   le clair n'existe que sous data-theme="light". */
:root { --promo: #FF7A86; --promo-fond: rgba(215, 38, 61, .16); }
:root[data-theme="light"] { --promo: #B91C32; --promo-fond: #FDECEE; }

.badge-promo {
    position: absolute;
    top: calc(var(--cellule, 14px) + 2px);
    left: calc(var(--cellule, 14px) + 2px);
    z-index: 3;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 10px 5px 8px;
    border-radius: 6px;
    background: var(--promo);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    line-height: 1;
    text-transform: uppercase;
    box-shadow: 0 4px 12px rgba(215, 38, 61, .28);
    pointer-events: none;
    transform: rotate(-2deg);
}

.badge-promo svg { width: 13px; height: 13px; flex: none; }
.badge-promo strong { font-weight: 800; letter-spacing: 0; }

.card .product-price-promo {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 2px 8px;
}

.prix-promo { color: var(--promo); font-weight: 700; }

.prix-barre {
    color: var(--grey);
    font-size: .86em;
    font-weight: 400;
    text-decoration-thickness: 1px;
}

.prix-remise {
    padding: 2px 6px;
    border-radius: 4px;
    background: var(--promo-fond);
    color: var(--promo);
    font-size: .78em;
    font-weight: 700;
}

.card-promo { box-shadow: inset 0 0 0 1.5px rgba(215, 38, 61, .55); }

/* Fiche produit */
.pdp-prix-ligne { flex-wrap: wrap; row-gap: 6px; }
.pdp-prix.pdp-prix-promo { color: var(--promo); }

.pdp-prix-barre {
    margin: 0;
    color: var(--grey);
    font-size: 17px;
    text-decoration-thickness: 1.5px;
}

.pdp-prix-remise {
    padding: 4px 9px;
    border-radius: 6px;
    background: var(--promo);
    color: #fff;
    font-size: 13px;
    font-weight: 800;
}

.pdp-promo-bandeau {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 10px;
    margin: 12px 0 0;
    padding: 10px 14px;
    border-radius: 10px;
    background: var(--promo-fond);
    color: var(--promo);
    font-size: 13px;
}

.pdp-promo-bandeau svg { width: 16px; height: 16px; flex: none; }
.pdp-promo-bandeau strong { font-weight: 800; letter-spacing: .04em; text-transform: uppercase; }
.pdp-promo-bandeau span { color: var(--ink); }

#buy-bar-price.pdp-prix-promo { color: var(--promo); }


/* Page Offres : la grille prend la largeur du catalogue, pas celle
   d'une page de texte. */
.legal-page.offres-page { max-width: 1440px; }
.offres-grille { margin-top: 24px; }


/* Back-office : bloc Promotion de la fiche annonce */
.admin-promo-bloc {
    grid-column: 1 / -1;
    margin: 4px 0 6px;
    padding: 12px 14px;
    border: 1px solid var(--line);
    border-radius: 10px;
}
.admin-promo-titre { padding: 0 6px; }
.admin-promo-interrupteur { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; cursor: pointer; }
.admin-promo-interrupteur input { width: auto; margin: 0; accent-color: var(--promo, #D7263D); }
.admin-promo-ligne { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; margin-top: 10px; }
.admin-promo-ligne label { display: flex; flex-direction: column; gap: 5px; font-size: 12px; color: var(--grey-light); }
#f-promo-apercu { color: var(--promo, #D7263D); font-weight: 600; }
.admin-promo-bloc:has(#f-promo-on:checked) { border-color: var(--promo, #D7263D); background: var(--promo-fond, #FDECEE); }
.admin-accueil-ajouter { margin-top: 10px; }
.admin-accueil-deplier { margin-top: 12px; }
.admin-accueil-rayons-titre { margin: 40px 0 4px; font-size: 1.1rem; letter-spacing: .04em; text-transform: uppercase; }

/* =======================================================
   FORMULAIRE D'ANNONCE — REFONTE DU 26/10/2026
   Marque à choisir dans une liste, couleurs en pastilles,
   format du colis en trois choix, et un tiroir qui prend
   tout l'écran sur téléphone.
======================================================= */

.admin-drawer .admin-photos{
    margin:0 0 26px;
}

.admin-photo-ajout{
    width:100%;
    min-height:52px;
    border-style:dashed;
}

.admin-marque{
    position:relative;
}

.admin-marque-liste:not(.hidden){
    position:absolute;
    z-index:5;
    top:100%;
    left:0;
    right:0;
    display:block;
    max-height:280px;
    margin:4px 0 0;
    padding:6px 0;
    overflow-y:auto;
    list-style:none;
    border:1px solid var(--line);
    border-radius:10px;
    background:var(--black);
    box-shadow:0 12px 30px rgba(0, 0, 0, .25);
}

.admin-marque-liste li{
    padding:12px 16px;
    cursor:pointer;
}

.admin-marque-liste li:hover{
    background:rgba(var(--ink-rgb), .06);
}

.admin-marque-ajout{
    border-top:1px solid var(--line);
    font-weight:600;
}

.admin-couleurs,
.admin-colis{
    margin:0;
    padding:0;
    border:none;
}

.admin-couleurs legend,
.admin-colis legend{
    margin-bottom:10px;
    font-size:12px;
    font-weight:600;
    letter-spacing:1px;
    text-transform:uppercase;
}

.admin-couleurs-compte{
    margin-left:8px;
    font-weight:400;
    letter-spacing:0;
    text-transform:none;
}

.admin-pastilles{
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(78px, 1fr));
    gap:14px 8px;
}

.admin-pastille{
    display:flex;
    flex-direction:column;
    align-items:center;
    gap:6px;
    padding:4px 0;
    border:none;
    background:none;
    color:var(--ink);
    font:inherit;
    font-size:13px;
    cursor:pointer;
}

.admin-pastille-rond{
    display:block;
    width:40px;
    height:40px;
    border-radius:50%;
    box-shadow:0 0 0 1px rgba(var(--ink-rgb), .15);
}

.admin-pastille-clair{
    box-shadow:0 0 0 1px rgba(10, 10, 10, .25);
}

.admin-pastille-autre{
    background:repeating-linear-gradient(45deg, transparent 0 5px, rgba(var(--ink-rgb), .18) 5px 6px);
}

.admin-pastille.active .admin-pastille-rond{
    box-shadow:0 0 0 3px var(--black), 0 0 0 5px var(--ink);
}

.admin-pastille.active .admin-pastille-nom{
    font-weight:700;
}

.admin-colis-choix{
    display:grid;
    grid-template-columns:repeat(3, 1fr);
    gap:10px;
}

.admin-colis-option{
    display:flex;
    flex-direction:column;
    gap:4px;
    min-height:76px;
    padding:12px 14px;
    border:1px solid var(--line);
    border-radius:10px;
    background:transparent;
    color:var(--ink);
    font:inherit;
    text-align:left;
    cursor:pointer;
}

.admin-colis-option span{
    font-size:12px;
    opacity:.7;
}

.admin-colis-option.active{
    border-color:var(--ink);
    box-shadow:inset 0 0 0 1px var(--ink);
}

.admin-colis-tableau{
    width:100%;
    margin:14px 0 8px;
    border-collapse:collapse;
    font-size:13px;
}

.admin-colis-tableau th,
.admin-colis-tableau td{
    padding:8px 6px;
    border-bottom:1px solid var(--line);
    text-align:left;
}

.admin-colis-tableau th{
    font-weight:600;
    opacity:.75;
}

/* Téléphone : plein écran, une colonne, cibles larges, et les
   boutons d'action toujours à portée de pouce. */
@media (max-width:760px){

    .admin-drawer{
        width:100%;
        border-left:none;
    }

    .admin-drawer-head{
        padding:14px 16px;
    }

    .admin-drawer-body{
        padding:16px 16px 24px;
    }

    .admin-drawer .admin-annonce-grille{
        grid-template-columns:1fr;
        gap:16px;
    }

    .admin-drawer input,
    .admin-drawer select,
    .admin-drawer textarea{
        font-size:16px;
    }

    .admin-pastilles{
        grid-template-columns:repeat(4, 1fr);
    }

    .admin-colis-choix{
        grid-template-columns:1fr;
    }

    .admin-colis-option{
        min-height:60px;
    }

    .admin-drawer-foot{
        position:sticky;
        bottom:0;
        padding:12px 16px calc(12px + env(safe-area-inset-bottom));
        background:var(--black);
    }

    .admin-drawer-foot .admin-btn{
        min-height:48px;
    }

    /* Au-dessus des boutons du tiroir, jamais dessus. */
    .admin-toast{
        bottom:calc(84px + env(safe-area-inset-bottom));
    }

}

/* Mesures à plat du formulaire d'annonce (26/10/2026). */
.admin-mesures{
    margin:0;
    padding:0;
    border:none;
}

.admin-mesures legend{
    margin-bottom:10px;
    font-size:12px;
    font-weight:600;
    letter-spacing:1px;
    text-transform:uppercase;
}

.admin-mesures-grille{
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(150px, 1fr));
    gap:12px;
}

.admin-mesures-grille label:not([hidden]){
    display:flex;
    flex-direction:column;
    gap:6px;
    font-size:13px;
}

.admin-mesures-grille input{
    width:100%;
}

/* Volets Couleurs / Matière du formulaire d'annonce (26/10/2026),
   à la manière de Vinted : un champ fermé, un panneau sous lui. */
.admin-volet{
    position:relative;
}

.admin-volet-bouton{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:10px;
    width:100%;
    min-height:48px;
    padding:12px 16px;
    border:1px solid var(--line);
    border-radius:12px;
    background:rgba(var(--ink-rgb), .04);
    color:rgba(var(--ink-rgb), .6);
    font:inherit;
    text-align:left;
    cursor:pointer;
}

.admin-volet-bouton::after{
    content:"";
    flex:none;
    width:8px;
    height:8px;
    border-right:1.5px solid currentColor;
    border-bottom:1.5px solid currentColor;
    transform:rotate(45deg) translateY(-2px);
}

.admin-volet-bouton[aria-expanded="true"]::after{
    transform:rotate(-135deg) translateY(-2px);
}

.admin-volet-bouton.admin-volet-rempli{
    color:var(--ink);
}

.admin-volet-resume{
    overflow:hidden;
    white-space:nowrap;
    text-overflow:ellipsis;
}

.admin-volet-panneau:not(.hidden){
    position:absolute;
    z-index:6;
    top:100%;
    left:0;
    right:0;
    display:block;
    max-height:340px;
    margin-top:6px;
    padding:12px;
    overflow-y:auto;
    border:1px solid var(--line);
    border-radius:12px;
    background:var(--black);
    box-shadow:0 14px 34px rgba(0, 0, 0, .28);
}

.admin-volet-panneau .admin-pastilles{
    grid-template-columns:repeat(4, 1fr);
}

.admin-volet-recherche{
    width:100%;
    margin-bottom:8px;
}

.admin-volet-liste{
    margin:0;
    padding:0;
    list-style:none;
}

.admin-volet-liste li{
    display:flex;
    align-items:center;
    gap:12px;
    padding:11px 8px;
    border-radius:8px;
    cursor:pointer;
}

.admin-volet-liste li:hover{
    background:rgba(var(--ink-rgb), .06);
}

.admin-volet-case{
    flex:none;
    width:18px;
    height:18px;
    border:1.5px solid rgba(var(--ink-rgb), .5);
    border-radius:4px;
}

.admin-volet-liste li.active .admin-volet-case{
    border-color:var(--ink);
    background:var(--ink);
    box-shadow:inset 0 0 0 3px var(--black);
}

@media (max-width:760px){
    .admin-volet-panneau .admin-pastilles{
        grid-template-columns:repeat(3, 1fr);
    }
}

.admin-volet > label .admin-field-help{
    margin-left:6px;
    font-weight:400;
    letter-spacing:0;
    text-transform:none;
}

/* Tri et filtres de la liste des annonces (27/10/2026). */
.admin-tri{
    display:flex;
    flex-wrap:wrap;
    align-items:center;
    gap:10px;
    margin:0 0 16px;
}

.admin-tri select{
    min-height:40px;
}

.admin-date-annonce{
    font-size:12px;
}

@media (max-width:760px){
    .admin-tri .admin-tri-statut{
        width:100%;
        overflow-x:auto;
    }
    .admin-tri select{
        flex:1 1 140px;
    }
}

/* Reprise d'une saisie non enregistrée (27/10/2026). */
.admin-reprise:not(.hidden){
    display:flex;
    flex-wrap:wrap;
    align-items:center;
    justify-content:space-between;
    gap:12px;
    margin:0 0 20px;
    padding:14px 16px;
    border:1px solid var(--ink);
    border-radius:12px;
}

.admin-reprise p{
    flex:1 1 260px;
    margin:0;
}

.admin-reprise-actions{
    display:flex;
    gap:8px;
}



/* Raccourci [messagerie] dans une description (27/10/2026) : un
   lien du texte, souligné, qui ouvre la messagerie ARKWER. */
.pdp-lien-messagerie{
    color:inherit;
    font-weight:600;
    text-decoration:underline;
    text-underline-offset:3px;
}

.admin-raccourci{
    align-self:flex-start;
    margin-top:8px;
}

/* =======================================================
   « EN SAVOIR PLUS » DE LA FICHE (27/10/2026)
   Remplace le bloc Authenticité : une question d'achat par
   volet, fermés par défaut, à la manière des grandes
   plateformes de seconde main.
======================================================= */
.pdp-savoir{
    margin-top:28px;
}

.pdp-savoir-titre{
    margin:0 0 14px;
    font-size:var(--t-etiquette, 12px);
    font-weight:700;
    letter-spacing:.14em;
    text-transform:uppercase;
}

.pdp-volet{
    margin:0 0 10px;
    border-radius:var(--r-controle, 12px);
    background:rgba(var(--ink-rgb), .04);
}

.pdp-volet > summary{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:16px;
    min-height:58px;
    padding:0 22px;
    list-style:none;
    font-size:15px;
    cursor:pointer;
}

.pdp-volet > summary::-webkit-details-marker{
    display:none;
}

/* Le « + » qui devient « − » à l'ouverture. */
.pdp-volet > summary::after{
    content:"+";
    flex:none;
    font-size:24px;
    font-weight:300;
    line-height:1;
}

.pdp-volet[open] > summary::after{
    content:"−";
}

.pdp-volet > summary:focus-visible{
    outline:2px solid var(--ink);
    outline-offset:2px;
    border-radius:var(--r-controle, 12px);
}

.pdp-volet-corps{
    padding:0 22px 18px;
    font-size:14px;
    line-height:1.55;
}

.pdp-volet-corps p{
    margin:0 0 10px;
}

.pdp-volet-note{
    margin-top:12px;
    font-size:13px;
    opacity:.8;
}

.pdp-savoir-garanties{
    display:inline-block;
    margin-top:8px;
    color:inherit;
    font-size:14px;
    opacity:.75;
    text-decoration:underline;
    text-underline-offset:3px;
}

/* Avec « En savoir plus », la colonne droite est plus haute : la
   gauche garde sa hauteur naturelle au lieu de s'étirer (sinon les
   lignes « Détails de la pièce » se répartissent dans le vide). */
.pdp-details > .pdp-colonne-gauche{
    align-self:start;
}

/* RAIL « VOUS AIMEREZ AUSSI » DES FICHES, PLUS FIN ET PLUS LONG
   (27/10/2026, demande de l'utilisateur). Les cartes restent celles
   du catalogue ; seules la largeur des colonnes et la proportion de
   la photo changent sur ce rail : 6 colonnes au large, 4 au milieu,
   photo en portrait 3/4 au lieu de 1/1,2. */
.pdp .pdp-rail {
    grid-template-columns: repeat(6, minmax(0, 1fr));
}

.pdp .pdp-rail > .card:nth-child(n + 6) {
    display: flex;
}

.pdp .pdp-rail > .card:nth-child(n + 7) {
    display: none;
}

.pdp .pdp-rail .card-visuel {
    aspect-ratio: 3 / 4;
}

@media (max-width: 1199px) {
    .pdp .pdp-rail {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
    .pdp .pdp-rail > .card:nth-child(n + 4) {
        display: flex;
    }
    .pdp .pdp-rail > .card:nth-child(n + 5) {
        display: none;
    }
}

@media (max-width: 768px) {
    .pdp .pdp-rail {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
    .pdp .pdp-rail > .card:nth-child(n + 3) {
        display: flex;
    }
    .pdp .pdp-rail > .card:nth-child(n + 4) {
        display: none;
    }
}

@media (max-width: 760px) {
    /* Téléphone : le rail défile, toutes les pièces restent, plus
       étroites (42 % de l'écran au lieu de 66 %) pour en voir deux
       et le bord d'une troisième. */
    .pdp .pdp-rail > .card:nth-child(n + 4) {
        display: flex;
    }
    .pdp .pdp-rail > .card {
        flex: 0 0 42vw;
        max-width: 220px;
    }
}

.pdp-volet .pdp-contact{
    margin-top:4px;
    padding-top:0;
    border-top:none;
}

/* « En savoir plus » v3 (27/10/2026) — une seule trame :
   une ligne = une icône en pastille + une phrase forte + une phrase
   courte dessous. Boutons pleine largeur, même hauteur partout. */
.pdp-volet-petit{
    margin:14px 0 0;
    font-size:12.5px;
    line-height:1.5;
    opacity:.7;
}

.pdp-points{
    display:grid;
    gap:14px;
    margin:0 0 16px;
    padding:0;
    list-style:none;
}

.pdp-point{
    display:grid;
    grid-template-columns:38px 1fr;
    align-items:center;
    gap:14px;
}

.pdp-point-icone{
    display:grid;
    place-items:center;
    width:38px;
    height:38px;
    border-radius:10px;
    background:rgba(var(--ink-rgb), .07);
}

.pdp-point-icone svg{
    width:20px;
    height:20px;
    fill:none;
    stroke:currentColor;
    stroke-width:1.6;
    stroke-linecap:round;
    stroke-linejoin:round;
}

.pdp-point-texte{
    display:flex;
    flex-direction:column;
    gap:2px;
    font-size:14px;
    line-height:1.4;
}

.pdp-point-texte strong{
    font-weight:600;
}

.pdp-point-texte > span{
    font-size:13px;
    opacity:.72;
}

/* Les actions : pleine largeur, 48 px, texte à gauche, flèche à droite. */
.pdp-action{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:12px;
    width:100%;
    min-height:48px;
    padding:12px 18px;
    border:1px solid rgba(var(--ink-rgb), .3);
    border-radius:12px;
    background:transparent;
    color:var(--ink);
    font-family:inherit;
    font-size:14px;
    font-weight:600;
    line-height:1.3;
    letter-spacing:0;
    text-transform:none;
    text-decoration:none;
    text-align:left;
    cursor:pointer;
}

.pdp-action:hover{
    border-color:var(--ink);
    background:rgba(var(--ink-rgb), .05);
}

.pdp-action-pleine,
.pdp-action-pleine:hover{
    border-color:var(--ink);
    background:var(--ink);
    color:var(--black);
}

.pdp-action-pleine:hover{
    opacity:.9;
}

.pdp-action-fleche{
    flex:none;
    width:16px;
    height:16px;
    fill:none;
    stroke:currentColor;
    stroke-width:1.6;
    stroke-linecap:round;
    stroke-linejoin:round;
}

.pdp-actions-duo{
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:8px;
    margin-top:8px;
}

/* Le message « pièce vendue » ne parle que d'une pièce vendue. */
.pdp-contact-vendue{
    display:none;
}

.pdp[data-etat="vendue"] .pdp-contact-vendue,
.pdp[data-etat="retiree"] .pdp-contact-vendue{
    display:block;
}

/* Les groupes étiquetés : moyens de paiement, transporteurs, pays. */
.pdp-volet-groupe{
    margin:16px 0 0;
}

.pdp-volet-etiquette{
    display:block;
    margin:0 0 8px;
    font-size:11px;
    font-weight:600;
    letter-spacing:.12em;
    text-transform:uppercase;
    opacity:.6;
}

.pdp-volet-paiements{
    display:flex;
    flex-wrap:wrap;
    gap:6px;
}

.pdp-transporteurs{
    display:grid;
    grid-template-columns:repeat(3, minmax(0, 1fr));
    gap:8px;
}

.pdp-transporteur{
    display:flex;
    align-items:center;
    gap:8px;
    min-height:40px;
    padding:6px 10px;
    border:1px solid rgba(var(--ink-rgb), .14);
    border-radius:10px;
    font-size:13px;
    font-weight:600;
    white-space:nowrap;
}

.pdp-transporteur img{
    flex:none;
    width:22px;
    height:22px;
    border-radius:5px;
}

.pdp-pays{
    display:grid;
    grid-template-columns:repeat(3, minmax(0, 1fr));
    gap:8px 12px;
    margin:0;
    padding:0;
    list-style:none;
}

.pdp-pays li{
    display:flex;
    align-items:center;
    gap:8px;
    font-size:13px;
}

.pdp-pays img{
    flex:none;
    width:20px;
    height:15px;
    border-radius:2px;
    object-fit:cover;
    box-shadow:0 0 0 1px rgba(var(--ink-rgb), .15);
}

/* Les contacts d'ARKWER : trois boutons égaux, logo + nom. */
.pdp-reseaux{
    display:grid;
    grid-template-columns:repeat(3, minmax(0, 1fr));
    gap:8px;
}

.pdp-reseau{
    display:flex;
    align-items:center;
    justify-content:center;
    gap:8px;
    min-height:48px;
    padding:0 10px;
    border-radius:12px;
    color:#fff;
    font-size:14px;
    font-weight:600;
    text-decoration:none;
}

.pdp-reseau svg{
    flex:none;
    width:18px;
    height:18px;
}

.pdp-reseau:hover{
    opacity:.9;
}

.pdp-reseau-discord{
    background:#5865F2;
}

.pdp-reseau-instagram{
    background:linear-gradient(45deg, #f58529, #dd2a7b 50%, #8134af);
}

.pdp-reseau-email{
    background:#3a3a3a;
}

/* Téléphone : trois transporteurs côte à côte, logo au-dessus du
   nom ; les pays sur deux colonnes. */
@media (max-width:480px){
    .pdp-transporteur{
        flex-direction:column;
        justify-content:center;
        gap:4px;
        padding:8px 4px;
        font-size:12px;
        text-align:center;
        white-space:normal;
    }
    .pdp-pays{
        grid-template-columns:repeat(2, minmax(0, 1fr));
    }
    .pdp-reseau{
        flex-direction:column;
        gap:4px;
        min-height:56px;
        font-size:13px;
    }
}


/* Paiement et Livraison allégés (27/10/2026) : plus rien sous les
   cartes ; transporteurs en petites pastilles et pays en une rangée
   de drapeaux (nom au survol et pour les lecteurs d'écran). */
.pdp-volet-paiements{
    margin-top:4px;
}

.pdp-livraison-pied{
    display:flex;
    flex-wrap:wrap;
    align-items:center;
    justify-content:space-between;
    gap:10px 16px;
    padding-top:14px;
    border-top:1px solid rgba(var(--ink-rgb), .1);
}

.pdp-livraison-pied .pdp-transporteurs{
    display:flex;
    flex-wrap:wrap;
    gap:6px;
}

.pdp-livraison-pied .pdp-transporteur{
    flex-direction:row;
    gap:6px;
    min-height:30px;
    padding:3px 10px 3px 4px;
    border-radius:999px;
    font-size:12px;
    white-space:nowrap;
}

.pdp-livraison-pied .pdp-transporteur img{
    width:18px;
    height:18px;
    border-radius:50%;
}

.pdp-livraison-pied .pdp-pays{
    display:flex;
    flex-wrap:wrap;
    gap:6px;
}

.pdp-livraison-pied .pdp-pays li{
    display:block;
}

.pdp-livraison-pied .pdp-pays img{
    display:block;
    width:24px;
    height:18px;
}


/* Icônes alignées sur la ligne du TITRE, et non centrées sur le bloc
   titre + phrase (elles flottaient 10 px plus bas, davantage encore
   sur trois lignes). Plus petites et plus discrètes. */
.pdp-point{
    grid-template-columns:32px 1fr;
    align-items:start;
    gap:12px;
}

.pdp-point-icone{
    width:32px;
    height:32px;
    margin-top:-6px;
    border-radius:50%;
    background:rgba(var(--ink-rgb), .06);
}

.pdp-point-icone svg{
    width:17px;
    height:17px;
}

/* Icônes centrées sur l'ENSEMBLE titre + phrase (27/10/2026, demande
   de l'utilisateur) : la plupart des lignes en ont deux. */
.pdp-point{
    align-items:center;
}

.pdp-point-icone{
    margin-top:0;
}


/* Livraison v4 (27/10/2026) : deux lignes, les drapeaux sous la
   seconde, puis une rangée de transporteurs sans séparateur. */
#pdp-volet-livraison .pdp-pays{
    display:flex;
    flex-wrap:wrap;
    gap:5px;
    margin:5px 0 0;
}

#pdp-volet-livraison .pdp-pays > span{
    display:block;
}

#pdp-volet-livraison .pdp-pays img{
    display:block;
    width:20px;
    height:15px;
}

#pdp-volet-livraison .pdp-transporteurs{
    display:flex;
    flex-wrap:wrap;
    gap:6px;
}

#pdp-volet-livraison .pdp-transporteur{
    flex-direction:row;
    gap:6px;
    min-height:30px;
    padding:3px 10px 3px 4px;
    border-radius:999px;
    font-size:12px;
    white-space:nowrap;
}

#pdp-volet-livraison .pdp-transporteur img{
    width:18px;
    height:18px;
    border-radius:50%;
}


/* Sans pastilles d'icônes (27/10/2026) : trop d'icônes avec les
   drapeaux, les logos de transporteurs et les cartes de paiement,
   qui sont les vrais signaux de confiance. Une ligne = une phrase
   forte + une phrase courte. Les cartes de paiement sont centrées. */
.pdp-volet-paiements{
    justify-content:center;
    margin-top:8px;
}



/* Livraison (27/10/2026) : les trois transporteurs, logo et nom,
   centrés en bas ; les pays sont écrits, plus de drapeaux. */
#pdp-volet-livraison .pdp-transporteurs{
    justify-content:center;
    margin-top:16px;
}


/* =========================================================
   TÉLÉPHONE — EN-TÊTE COMPLET ET CARTES (27/10/2026)

   Retour du test sur téléphone : ni recherche, ni messages, ni
   profil dans la barre. Tout existait, mais caché sous 1000 px
   (recherche, pilule d'inscription) ou hors session (enveloppe).
   Sur téléphone la barre porte désormais, sur DEUX rangées :
     1. menu, logo, thème, panier, messages, profil ;
     2. la recherche, pleine largeur.
   Hors session, le profil est la pilule d'inscription réduite à
   son pictogramme : même bouton, même action (ouvre l'inscription),
   seule la forme change. Rien n'est ajouté au balisage des cent
   douze pages.
========================================================= */
@media (max-width: 700px) {

    body:not([class*="page-admin"]) .navbar-top {
        height: auto;
        min-height: 60px;
        flex-wrap: wrap;
        row-gap: 8px;
        gap: 10px;
        padding: 8px 14px 10px;
    }

    body:not([class*="page-admin"]) .navbar-top-actions {
        gap: 2px;
        min-width: 0;
    }

    body:not([class*="page-admin"]) .navbar-top-actions > .theme-toggle { order: 1; margin-right: 4px; }
    body:not([class*="page-admin"]) .navbar-top-actions > .cart-icon    { order: 2; }
    body:not([class*="page-admin"]) .navbar-top-actions > .messages-icon{ order: 3; }
    body:not([class*="page-admin"]) .navbar-top-actions > .navbar-compte{ order: 4; }

    /* La recherche : seconde rangée, pleine largeur. 16 px de police,
       sinon iOS zoome la page au toucher du champ. */
    body:not([class*="page-admin"]) .navbar-search {
        display: flex;
        order: 10;
        flex: 1 1 100%;
        max-width: none;
        padding: 10px 16px;
    }

    body:not([class*="page-admin"]) .navbar-search-input {
        font-size: 16px;
        margin-top: -10px;
        margin-bottom: -10px;
        padding-top: 10px;
        padding-bottom: 10px;
    }

    /* L'enveloppe est toujours là : hors session, elle mène à la page
       Messages, qui ouvre l'identification. .hidden est posé par
       js/auth.js ; il est ici volontairement rallumé. */
    body:not([class*="page-admin"]) .navbar-top-actions > .messages-icon.hidden {
        display: flex;
        width: 36px;
        height: 36px;
    }

    /* Le profil hors session : la pilule devient une icône. */
    body:not([class*="page-admin"]) .navbar-account-link:not(.logged-in):not(.hidden) {
        display: block;
        width: 36px;
        height: 36px;
        padding: 0;
        border: 0;
        border-radius: 0;
        font-size: 0;
        background: var(--ink);
        -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8.2' r='3.5'/%3E%3Cpath d='M5 19.4a7 7 0 0 1 14 0'/%3E%3C/svg%3E") center / 22px no-repeat;
        mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8.2' r='3.5'/%3E%3Cpath d='M5 19.4a7 7 0 0 1 14 0'/%3E%3C/svg%3E") center / 22px no-repeat;
    }

    body:not([class*="page-admin"]) .navbar-account-link:not(.logged-in):not(.hidden) > span {
        display: none;
    }

    body:not([class*="page-admin"]) .navbar-account-link:not(.logged-in):not(.hidden):hover {
        background: var(--ink);
    }

    /* UN SEUL GABARIT DE CARTE. Le rail des Tendances, le catalogue,
       « Pour vous » et les rails des fiches montrent la même carte, à
       la même largeur : une colonne de la grille à deux colonnes. */
    .selection-arkwer .products > .card,
    .pdp .pdp-rail > .card,
    .compte-bloc-decouverte .products > .card,
    #compte-favoris-apercu > .card {
        flex: 0 0 44%;
        max-width: none;
    }
}


/* TÉLÉPHONE — LA BARRE ACHETEUR REVIENT (27/10/2026).
   Catalogue, Offres, Populaires, À découvrir, Filtrer étaient
   masquées sous 760 px : on ne voyait plus ces rubriques. Elles
   reviennent en une rangée qui défile sous la recherche, sans
   jamais élargir la page. */
@media (max-width: 760px) {
    body:not([class*="page-admin"]) .mainnav {
        display: block;
        padding: 0;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scrollbar-width: none;
    }

    body:not([class*="page-admin"]) .mainnav::-webkit-scrollbar {
        display: none;
    }

    body:not([class*="page-admin"]) .mainnav-liste {
        gap: 0;
        width: max-content;
        min-width: 100%;
        padding: 0 8px;
    }

    body:not([class*="page-admin"]) .mainnav-lien {
        padding: 13px 12px;
        font-size: 12px;
    }

    body:not([class*="page-admin"]) .mainnav-lien::after {
        left: 12px;
        right: 12px;
    }

    /* Enveloppe hors session : même boîte que le panier. */
    body:not([class*="page-admin"]) .navbar-top-actions > .messages-icon.hidden {
        align-items: center;
        justify-content: center;
        color: var(--ink);
    }
}


.card .product-meta,
.card .product-brand {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}


/* =========================================================
   TÉLÉPHONE — L'EN-TÊTE DÉFILE AVEC LA PAGE (27/10/2026)
   Avec la recherche et les rubriques, l'en-tête fait 162 px :
   collé en permanence, il mangeait un cinquième de l'écran.
   Sur téléphone il se lit en haut de page, puis s'efface ; la
   fiche garde sa barre d'achat, collée en bas.
========================================================= */
@media (max-width: 700px) {
    body:not([class*="page-admin"]) .navbar {
        position: relative;
    }

    :root {
        --hauteur-header: 0px;
    }

    html {
        scroll-padding-top: 16px;
    }
}


/* =========================================================
   FICHE PRODUIT — REPRISE (27/10/2026)

   · plus de blocs qui se replient : Description, Détails de la
     pièce et Vendu par sont toujours ouverts ;
   · plus de bandeau « Authenticité vérifiée » (retiré du
     balisage) ;
   · trois commandes sous le prix, dans cet ordre : Acheter
     maintenant, Ajouter au panier, Contacter le vendeur ;
   · taille et état sur deux lignes serrées.
========================================================= */

.pdp-bloc-titre {
    cursor: default;
}

/* Contacter le vendeur : une commande comme les deux autres, en
   retrait (contour fin), sous « Ajouter au panier ». */
.pdp-actions > .pdp-contact {
    margin-top: 10px;
    padding-top: 0;
    border-top: 0;
}

.pdp-actions > .pdp-contact > .pdp-contact-ouvrir {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 52px;
    padding: 0 18px;
    background: none;
    border: 1px solid var(--pdp-trait);
    color: var(--ink);
    text-align: center;
}

.pdp-actions > .pdp-contact > .pdp-contact-ouvrir:hover {
    background: rgba(var(--ink-rgb), .06);
    border-color: var(--ink);
}

.pdp-actions > .pdp-contact > .pdp-contact-ouvrir[hidden] {
    display: none;
}

@media (max-width: 760px) {

    /* TAILLE et ÉTAT : une ligne chacun, l'intitulé à gauche, la
       valeur à droite de lui. 165 px de haut avant, une soixantaine
       maintenant. */
    .pdp-faits {
        gap: 0;
        margin-top: 12px;
        padding: 0;
        border-top: 1px solid var(--pdp-trait);
    }

    .pdp-fait {
        display: flex;
        align-items: baseline;
        gap: 14px;
        padding: 10px 0;
    }

    .pdp-fait + .pdp-fait {
        padding-left: 0;
        border-left: 0;
        border-top: 1px solid var(--pdp-trait);
    }

    .pdp-fait dt {
        flex: 0 0 56px;
        margin: 0;
    }

    .pdp-fait dd {
        flex: 1;
        min-width: 0;
    }

    .pdp-fait-etat dd,
    .pdp-fait-etat .condition-label {
        display: inline;
    }

    /* Les trois commandes ont la même hauteur et la même largeur. */
    .pdp-achat-rangee {
        gap: 10px;
    }

    .pdp-achat-rangee .pdp-cta {
        min-height: 52px;
    }

    /* La confiance : trois lignes alignées, pastille à gauche, texte
       à côté ; les logos de paiement passent sous leur ligne, calés
       sur le texte. */
    .pdp-confiance {
        margin-top: 20px;
        padding-top: 16px;
        border-top: 1px solid var(--pdp-trait);
    }

    .pdp-confiance-liste {
        gap: 12px;
        margin: 0;
        padding: 0;
    }

    .pdp-confiance-liste li {
        flex-wrap: wrap;
        gap: 4px 12px;
        font-size: 13px;
    }

    .pdp-confiance-liste li > a,
    .pdp-confiance-liste li > #pdp-livraison {
        flex: 1;
        min-width: 0;
    }

    .pdp-confiance-liste .pdp-paiements {
        flex: 0 0 100%;
        margin: 0 0 0 42px;
    }

    /* Les blocs d'information : titre simple, corps toujours visible. */
    .pdp-bloc-titre {
        padding: 20px 0 12px;
    }

    .pdp-bloc-corps {
        padding: 0 0 20px;
    }

    .pdp-details {
        margin-top: 28px;
    }
}

@media (max-width: 760px) {
    .pdp-confiance-liste .pdp-paiements {
        flex: 0 0 calc(100% - 42px);
        max-width: calc(100% - 42px);
    }
}

/* Description, Détails, Vendu par : même gabarit, un filet entre
   deux blocs et jamais deux. */
@media (max-width: 760px) {
    .pdp-details .pdp-bloc {
        margin: 0;
        padding: 0;
        border: 0;
        border-top: 1px solid var(--pdp-trait);
    }

    .pdp-details .pdp-colonne-gauche > .pdp-bloc:first-child {
        border-top: 0;
    }

    .pdp-details .pdp-bloc > .pdp-bloc-corps {
        padding: 0 0 22px;
        margin: 0;
    }

    .pdp-details .pdp-colonne {
        gap: 0;
        margin: 0;
        padding: 0;
    }

    .pdp-details .pdp-caracteristiques > div:last-child {
        border-bottom: 0;
    }
}


/* =======================================================
   HAUT DE FICHE, PLUS NET (27/10/2026)
   Alignements CENTRÉS au lieu de « ligne de base » (le grand prix,
   le petit texte et les icônes ne se calaient jamais pareil) ;
   taille en pastille, disponibilité en pilule ; bloc de confiance
   en carte, les cartes de paiement alignées sous leur ligne.
======================================================= */

.pdp-prix-ligne{
    align-items:center;
}

.pdp-dispo{
    display:inline-flex;
    align-items:center;
    gap:8px;
    padding:6px 12px;
    border-radius:999px;
    background:color-mix(in srgb, currentColor 11%, transparent);
    font-size:13px;
    line-height:1;
}

.pdp-dispo::before{
    margin:0;
    top:0;
    vertical-align:baseline;
}

.pdp-fait-taille dd{
    align-items:center;
    gap:8px 14px;
}

/* La taille retrouve sa présentation d’avant (27/10/2026) : du texte, pas une pastille. */
#quick-fact-size{
    display:inline;
}

.pdp-fait-etat dd{
    display:block;
}

.pdp-fait-etat .condition-label{
    display:inline;
}

.condition-ligne{
    align-items:center;
}

.condition-aide{
    margin-bottom:0;
}

.pdp-confiance-liste{
    gap:0;
    margin-top:16px;
    padding:2px 16px;
    border:1px solid var(--pdp-trait);
    border-radius:14px;
}

.pdp-confiance-liste li{
    padding:13px 0;
    font-size:14px;
    align-items:center;
    gap:4px 12px;
}

.pdp-confiance-liste li + li{
    border-top:1px solid var(--pdp-trait);
}

.pdp-confiance-pastille{
    width:32px;
    height:32px;
    border-radius:50%;
}

/* Les cartes : sous leur ligne, alignées sur son texte (32 + 12). */
.pdp-confiance .pdp-confiance-liste .pdp-paiements{
    flex:0 0 calc(100% - 44px);
    max-width:calc(100% - 44px);
    margin:4px 0 0 44px;
    justify-content:flex-start;
}

/* LIVRAISON sur téléphone (27/10/2026) : icône calée sur la première
   ligne du texte, et les trois transporteurs sur une seule rangée. */
@media (max-width: 760px) {
    #pdp-volet-livraison .pdp-point {
        align-items: flex-start;
    }

    #pdp-volet-livraison .pdp-transporteurs {
        flex-wrap: nowrap;
        justify-content: space-between;
        gap: 6px;
    }

    #pdp-volet-livraison .pdp-transporteur {
        flex: 1 1 0;
        min-width: 0;
        justify-content: center;
        gap: 5px;
        padding: 3px 6px;
        font-size: 11px;
    }

    #pdp-volet-livraison .pdp-transporteur img {
        width: 14px;
        height: 14px;
    }
}


/* =========================================================
   RETOUR DU TEST TÉLÉPHONE, 2e TOUR (27/10/2026)
========================================================= */

/* --- VENDU PAR : une carte qui se touche -------------------- */
.pdp-vendeur-carte {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 16px;
    border: 1px solid var(--pdp-trait);
    border-radius: 14px;
    background: rgba(var(--ink-rgb), .04);
    color: inherit;
    text-decoration: none;
    transition: border-color .2s ease, background .2s ease;
}

.pdp-vendeur-carte:hover,
.pdp-vendeur-carte:focus-visible {
    border-color: var(--ink);
    background: rgba(var(--ink-rgb), .07);
}

.pdp-vendeur-carte .pdp-vendeur-nom {
    flex: 1;
}

.pdp-vendeur-voir {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    flex: none;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    color: var(--ink);
}

.pdp-vendeur-atouts {
    display: grid;
    gap: 8px;
    margin: 14px 0 0;
    padding: 0;
    list-style: none;
    font-size: 13px;
    line-height: 1.45;
    color: var(--grey-light);
}

.pdp-vendeur-atouts li {
    position: relative;
    padding-left: 22px;
}

.pdp-vendeur-atouts li::before {
    content: "";
    position: absolute;
    left: 3px;
    top: .38em;
    width: 5px;
    height: 9px;
    border-right: 1.6px solid #1F8F50;
    border-bottom: 1.6px solid #1F8F50;
    transform: rotate(45deg);
}

/* --- PAIEMENT : sur téléphone, jusqu'à Klarna --------------- */
@media (max-width: 760px) {
    #pdp-paiements [aria-label="Klarna"] ~ *,
    #pdp-volet-paiements [aria-label="Klarna"] ~ * {
        display: none;
    }
}

/* --- FILTRES : une ligne qui défile, des onglets plus petits - */
@media (max-width: 1023px) {
    .pf-barre-tactile {
        padding-bottom: 2px;
    }

    .pf-barre-tactile .pf-groupe {
        gap: 6px;
    }

    .pf-barre-tactile .pf-bloc-tri {
        margin-right: 6px;
    }

    .pf-barre-tactile .pf-declencheur,
    .pf-barre-tactile .pf-tri {
        min-height: 36px;
        gap: 5px;
        padding: 0 11px 0 12px;
        font-size: 11px;
        letter-spacing: .06em;
    }
}

/* --- POUR VOUS ET TENDANCES SUR TÉLÉPHONE ------------------- */
@media (max-width: 768px) {
    /* Deux rangées, qui défilent de côté : deux cartes et demie
       visibles, pour que le bord de la suivante dise « il y en a
       d'autres ». Cinq cartes en colonne, c'était une longue pile. */
    #reco-accueil-grille {
        display: grid;
        grid-template-columns: none;
        grid-template-rows: auto;
        grid-auto-flow: column;
        grid-auto-columns: 44%;
        overflow-x: auto;
        overflow-y: hidden;
        overscroll-behavior-x: contain;
        scroll-snap-type: x proximity;
        scrollbar-width: none;
    }

    #reco-accueil-grille::-webkit-scrollbar {
        display: none;
    }

    #reco-accueil-grille > .card {
        scroll-snap-align: start;
    }
}

/* --- LA BANDE « CONTREFAÇON » : une carte, plus un pavé ----- */
@media (max-width: 640px) {
    .authenticite-bande {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
        margin: 28px 18px;
        padding: 18px;
        border: 1px solid var(--line);
        border-radius: 14px;
        background: rgba(var(--ink-rgb), .04);
    }

    .authenticite-bande-titre {
        font-size: 16px;
    }

    .authenticite-bande-lien {
        justify-content: center;
        margin-left: 0;
        padding: 12px 16px;
    }
}

/* --- CONNEXION : les deux liens sur la même ligne ----------- */
@media (max-width: 640px) {
    .auth-confiance-liens {
        flex-direction: row;
        flex-wrap: nowrap;
        justify-content: center;
        gap: 6px;
        font-size: 10.5px;
        white-space: nowrap;
    }

    .auth-confiance-liens span {
        display: inline;
    }
}


/* =======================================================
   ZONE D'ACHAT, EMPILÉE (27/10/2026)
   Ordre voulu : livraison en petit, Contacter le vendeur,
   Ajouter au panier, Acheter maintenant, puis un cadenas et
   « Validé par votre banque » avec les cartes. Un bandeau de
   vérification d'authenticité au-dessus de la taille.
======================================================= */
.pdp-verif{
    display:flex;
    align-items:center;
    gap:12px;
    margin:18px 0 0;
    padding:14px 16px;
    border-radius:12px;
    background:rgba(var(--ink-rgb), .06);
    color:var(--ink);
    font-size:14px;
    font-weight:600;
    line-height:1.35;
    text-decoration:none;
}

.pdp-verif:hover{
    background:rgba(var(--ink-rgb), .1);
}

.pdp-verif span{
    flex:1;
}

.pdp-verif-icone{
    flex:none;
    width:28px;
    height:28px;
    fill:none;
    stroke:currentColor;
    stroke-width:2;
    stroke-linecap:round;
    stroke-linejoin:round;
}

.pdp-verif-fleche{
    flex:none;
    width:14px;
    height:14px;
    fill:none;
    stroke:currentColor;
    stroke-width:1.8;
    stroke-linecap:round;
    stroke-linejoin:round;
}

.pdp-livraison-mini{
    margin:0 0 10px;
    font-size:12.5px;
    color:var(--grey);
    text-align:center;
}

.pdp-actions .pdp-contact{
    margin:0 0 8px;
}

.pdp-achat-rangee{
    display:flex;
    flex-direction:column;
    gap:8px;
}

.pdp-achat-rangee .pdp-cta{
    width:100%;
}

.pdp-valide{
    display:flex;
    align-items:center;
    justify-content:center;
    gap:8px;
    margin:16px 0 10px;
    font-size:13px;
    font-weight:600;
}

.pdp-valide a{
    color:inherit;
    text-decoration:none;
}

.pdp-valide a:hover{
    text-decoration:underline;
    text-underline-offset:3px;
}

.pdp-valide-cadenas{
    flex:none;
    width:16px;
    height:16px;
    fill:none;
    stroke:currentColor;
    stroke-width:1.8;
    stroke-linecap:round;
    stroke-linejoin:round;
}

.pdp-actions .pdp-paiements{
    display:flex;
    flex-wrap:wrap;
    justify-content:center;
    gap:4px;
    margin:0;
}


/* =========================================================
   RAILS SUR TÉLÉPHONE — CARTES UN PEU PLUS LARGES, TEXTE PLUS FIN
   (27/10/2026). À 40 % la carte ne laissait que 108 px au texte :
   noms sur deux lignes, « Très bon état » coupé. À 44 %, marges
   internes réduites et corps abaissés, tout tient ; la taille et
   l'état passent chacun sur leur ligne plutôt que d'être tronqués.
   Concerne Tendances, Pour vous et les rails des fiches — pas la
   grille du catalogue de l'accueil.
========================================================= */
@media (max-width: 768px) {
    .selection-arkwer .card,
    #reco-accueil-grille .card,
    .pdp .pdp-rail .card {
        padding: 10px 10px 14px;
    }

    .selection-arkwer .card .product-info,
    #reco-accueil-grille .card .product-info,
    .pdp .pdp-rail .card .product-info {
        margin-top: 10px;
        gap: 1px;
    }

    .selection-arkwer .card .product-brand,
    #reco-accueil-grille .card .product-brand,
    .pdp .pdp-rail .card .product-brand {
        font-size: 10.5px;
        letter-spacing: .06em;
    }

    .selection-arkwer .card .product-nom,
    #reco-accueil-grille .card .product-nom,
    .pdp .pdp-rail .card .product-nom {
        min-height: 2.64em;
        font-size: 12px;
    }

    .selection-arkwer .card .product-meta,
    #reco-accueil-grille .card .product-meta,
    .pdp .pdp-rail .card .product-meta {
        min-height: 2.8em;
        margin-top: 3px;
        font-size: 10.5px;
        white-space: normal;
    }

    .selection-arkwer .card .product-meta > span,
    #reco-accueil-grille .card .product-meta > span,
    .pdp .pdp-rail .card .product-meta > span {
        display: block;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .selection-arkwer .card .product-meta > .product-meta-sep,
    #reco-accueil-grille .card .product-meta > .product-meta-sep,
    .pdp .pdp-rail .card .product-meta > .product-meta-sep {
        display: none;
    }

    .selection-arkwer .card .product-price,
    #reco-accueil-grille .card .product-price,
    .pdp .pdp-rail .card .product-price {
        padding-top: 6px;
        font-size: 15px;
    }
}


/* =========================================================
   PIED DE PAGE SUR TÉLÉPHONE — COMPACT (27/10/2026)
   Les cinq colonnes de liens s'empilaient par paires de hauteurs
   inégales, avec des trous ; les mentions et l'avis occupaient
   deux écrans. Ici : deux colonnes qui se remplissent sans trou,
   interlignes serrés, mentions en petit.
========================================================= */
@media (max-width: 700px) {
    .footer-rich {
        padding: 28px 18px 22px;
    }

    .footer-rich-columns {
        display: block;
        column-count: 2;
        column-gap: 20px;
        margin-bottom: 18px;
    }

    .footer-rich-column {
        break-inside: avoid;
        margin-bottom: 18px;
    }

    .footer-rich-column h4 {
        margin-bottom: 8px;
        font-size: 11px;
    }

    .footer-rich-column a {
        margin-bottom: 7px;
        font-size: 12.5px;
        line-height: 1.3;
    }

    .footer-rich-locale {
        margin-bottom: 12px;
        padding-top: 16px;
        font-size: 12px;
    }

    .footer-rich-legal-row {
        gap: 10px;
        margin-bottom: 20px;
    }

    .footer-rich-legal-links {
        gap: 6px 16px;
    }

    .footer-rich-legal-links a {
        font-size: 11.5px;
    }

    .footer-rich-disclaimer {
        margin-bottom: 18px;
        padding-top: 18px;
    }

    .footer-rich-disclaimer h4 {
        margin-bottom: 8px;
        font-size: 12px;
    }

    .footer-rich-disclaimer p {
        margin-bottom: 8px;
        font-size: 10.5px;
        line-height: 1.5;
    }

    .footer-rich-payments {
        gap: 5px;
        margin-bottom: 14px;
    }
}

@media (max-width: 700px) {
    .footer-rich .consent-lien-pied {
        font-size: 11.5px;
    }
}


/* Livraison et « Validé par votre banque » : une seule ligne, collés,
   à gauche, au-dessus des boutons ; les cartes restent dessous, à
   gauche aussi (27/10/2026). */
.pdp-infos-achat{
    display:flex;
    flex-wrap:wrap;
    align-items:center;
    justify-content:flex-start;
    gap:6px 14px;
    margin:0 0 10px;
    font-size:12.5px;
}

.pdp-infos-achat .pdp-livraison-mini,
.pdp-infos-achat .pdp-valide{
    margin:0;
    font-size:12.5px;
    text-align:left;
}

.pdp-infos-achat .pdp-valide{
    justify-content:flex-start;
    gap:6px;
}

.pdp-actions .pdp-paiements{
    justify-content:flex-start;
    margin-top:12px;
}


/* Paiement sur une seule ligne, sous les boutons : cadenas + « Validé
   par votre banque » + cartes, à gauche (27/10/2026). La livraison,
   seule au-dessus, est alignée à gauche aussi. */
.pdp-actions .pdp-livraison-mini{
    margin:0 0 10px;
    text-align:left;
}

.pdp-paiement-ligne{
    display:flex;
    flex-wrap:wrap;
    align-items:center;
    gap:8px 12px;
    margin-top:14px;
}

.pdp-paiement-ligne .pdp-valide{
    margin:0;
    font-size:13px;
    white-space:nowrap;
}

.pdp-actions .pdp-paiement-ligne .pdp-paiements{
    margin:0;
    justify-content:flex-start;
}

/* « Retirer » sous le prix de chaque article de la commande
   (27/10/2026) : un lien discret, cible de 44 px de haut sur
   téléphone. */
.checkout-item-price{
    display:flex;
    flex-direction:column;
    align-items:flex-end;
    gap:6px;
}

.checkout-item-retirer{
    padding:4px 0;
    border:none;
    background:none;
    color:var(--grey);
    font:inherit;
    font-size:12px;
    font-weight:400;
    text-decoration:underline;
    text-underline-offset:3px;
    cursor:pointer;
}

.checkout-item-retirer:hover,
.checkout-item-retirer:focus-visible{
    color:var(--ink);
}

@media (max-width:700px){
    .checkout-item-price{
        align-items:flex-start;
    }
    .checkout-item-retirer{
        min-height:32px;
    }
}

/* « VOIR PLUS » sous Pour vous : mène au fil plein écran. */
#reco-accueil > .reco-voir-plus {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    margin: 6px 0 0;
    padding: 0 25px;
    border: 0;
}
@media (max-width: 700px) {
    #reco-accueil > .reco-voir-plus { padding: 0 18px; }
}


/* PIED DE PAGE SUR TÉLÉPHONE — 2e PASSE (27/10/2026)
   Trois colonnes de liens courts au lieu de deux longues ; une seule
   ligne de moyens de paiement (on s'arrête à Klarna, comme sur la fiche). */
@media (max-width: 700px) {
    .footer-rich-columns {
        column-count: 3;
        column-gap: 14px;
        margin-bottom: 14px;
    }

    .footer-rich-column {
        margin-bottom: 14px;
    }

    .footer-rich-column a {
        margin-bottom: 6px;
        font-size: 12px;
    }

    .footer-rich-payments {
        flex-wrap: nowrap;
        overflow: hidden;
    }

    .footer-rich-payments .payment-method-badge[aria-label="Klarna"] ~ * {
        display: none;
    }
}
@media (max-width: 700px) {
    .footer-rich-column a {
        font-size: 11.5px;
        white-space: nowrap;
    }
}

/* PIED DE PAGE SUR TÉLÉPHONE — 3e PASSE (27/10/2026)
   « Acheter » et « Vendre » sont déjà dans le menu : on ne garde en bas
   que Confiance, Aide et ARKWER, côte à côte sur une seule ligne. */
@media (max-width: 700px) {
    .footer-rich-column:nth-child(-n + 2) {
        display: none;
    }
    .footer-rich-columns {
        display: grid;
        grid-template-columns: repeat(3, auto);
        justify-content: space-between;
        column-count: auto;
        column-gap: 12px;
    }
    .footer-rich-column {
        margin-bottom: 0;
    }
}


/* FORMULAIRE « ÉCRIRE AU VENDEUR » DU FIL, SUR TÉLÉPHONE (27/10/2026)
   Feuille plus basse et plus serrée, champ à hauteur fixe, bouton pleine
   largeur, et marge de sécurité en bas pour l'iPhone. */
@media (max-width: 700px) {
    .flux-infos-boite {
        padding: 1.1rem 1.1rem calc(1.1rem + env(safe-area-inset-bottom, 0px));
    }
    .flux-infos-nom {
        font-size: 1.15rem;
        margin-bottom: .2rem;
    }
    .flux-msg-piece {
        margin-bottom: .8rem;
        display: -webkit-box;
        -webkit-line-clamp: 1;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }
    .flux-msg-form { gap: .55rem; }
    .flux-msg-texte {
        height: 6.2rem;
        min-height: 6.2rem;
        resize: none;
        font-size: 16px; /* évite le zoom automatique de l'iPhone */
    }
    .flux-msg-envoyer {
        align-self: stretch;
        width: 100%;
    }
}


/* « VOIR LES TENDANCES » : sous les annonces et non plus dans l'en-tête
   (27/10/2026). Même présentation que « Voir plus » du catalogue. */
#featured > .category-link .section-action {
    display: none;
}

#featured > .tendances-voir-plus {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    margin: 6px 0 0;
    padding: 0 25px;
    border: 0;
}

@media (max-width: 700px) {
    #featured > .tendances-voir-plus { padding: 0 18px; }
}


/* BARRE « PAYER » COLLÉE EN BAS (téléphone, tunnel de commande) —
   voir js/commande-barre.js. Masquée dès que le vrai bouton est visible. */
.barre-payer { display: none; }

@media (max-width: 900px) {
    .barre-payer:not([hidden]) {
        display: block;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 900;
        padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px));
        background: var(--black);
        border-top: 1px solid var(--line);
        box-shadow: 0 -6px 18px rgba(0, 0, 0, .25);
    }
    .barre-payer-bouton {
        display: block;
        width: 100%;
        min-height: 48px;
        padding: 0 1rem;
        background: var(--ink);
        color: var(--black);
        border: 0;
        border-radius: var(--r-controle);
        font: inherit;
        font-size: .85rem;
        font-weight: 600;
        letter-spacing: .1em;
        text-transform: uppercase;
        cursor: pointer;
    }
    .barre-payer-bouton:disabled { opacity: .55; cursor: default; }
}


/* =========================================================
   COMMANDE — ADRESSE EN BOUTON, LIVRAISON EN DEUX TEMPS (27/10/2026)
   Voir js/commande-livraison.js. Tout est conditionné par les classes
   .adresse-active et .livr-actif, posées par ce script : sans lui, la
   page garde sa mise en forme d'origine.
========================================================= */

/* ---- Adresse : une ligne-bouton qui déplie les coordonnées ---- */

.adresse-bouton:not([hidden]),
.livr-detail-bouton {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    min-height: 56px;
    padding: 10px 14px;
    background: transparent;
    color: var(--ink);
    border: 1px solid var(--line);
    border-radius: var(--r-controle, 8px);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.adresse-bouton-texte,
.livr-detail-texte {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.adresse-bouton-titre,
.livr-detail-titre {
    font-size: .95rem;
    font-weight: 600;
}

.adresse-bouton-resume,
.livr-detail-resume {
    font-size: .8rem;
    color: var(--grey);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.adresse-bouton-fleche {
    flex: none;
    font-size: 1.5rem;
    line-height: 1;
    color: var(--grey);
    transition: transform .15s ease-out;
}

.adresse-bouton[aria-expanded="true"] .adresse-bouton-fleche { transform: rotate(90deg); }

.adresse-bouton-manque .adresse-bouton-resume { color: #c9a668; }

.adresse-active #adresse-titre { display: none; }

.adresse-active #adresse-corps:not([hidden]) { margin-top: 14px; }

.adresse-facultatif-titre {
    margin: 18px 0 8px;
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--grey);
}

/* ---- Option de livraison : deux choix, puis le détail ---- */

.livr-choix-wrap:not([hidden]) { display: block; margin-top: 18px; }

.livr-sous-titre {
    margin: 0 0 10px;
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--grey);
}

.livr-choix {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin-bottom: 10px;
}

.livr-choix-carte {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    min-height: 64px;
    padding: 12px 14px;
    background: transparent;
    color: var(--ink);
    border: 1px solid var(--line);
    border-radius: var(--r-controle, 8px);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.livr-choix-carte:disabled { opacity: .45; cursor: default; }

.livr-choix-actif {
    border-color: var(--ink);
    box-shadow: inset 0 0 0 1px var(--ink);
}

.livr-choix-nom { font-size: .9rem; font-weight: 600; }
.livr-choix-prix { font-size: .8rem; color: var(--grey); }

.livr-detail-bouton:disabled { opacity: .5; cursor: default; }
.livr-detail-fait { border-color: var(--ink); }

.livr-choix-manque .livr-choix-carte { border-color: #c9a668; }

/* La liste d'origine des modes : cachée quand le choix en deux temps
   est actif ; elle ne sert plus que dans l'écran « détail ». */
.livr-actif #delivery-modes-wrap:not(.hidden):not(.livr-ouvert) { display: none; }

/* ---- L'écran « détail », en plein écran ---- */

.livr-actif #delivery-modes-wrap.livr-ouvert:not(.hidden) {
    position: fixed;
    inset: 0;
    z-index: 5200;
    display: flex;
    flex-direction: column;
    background: var(--black);
    color: var(--ink);
}

.livr-ouvert .livr-entete:not([hidden]) {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: none;
    padding: 8px 10px;
    border-bottom: 1px solid var(--line);
}

.livr-retour {
    flex: none;
    width: 44px;
    height: 44px;
    background: none;
    border: 0;
    color: var(--ink);
    font-size: 2rem;
    line-height: 1;
    cursor: pointer;
}

.livr-entete-titre {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 600;
}

.livr-ouvert .livr-corps {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    width: min(46rem, 100%);
    margin: 0 auto;
    padding: 14px 16px 28px;
    -webkit-overflow-scrolling: touch;
}

.livr-ouvert .livr-pied:not([hidden]) {
    flex: none;
    width: min(46rem, 100%);
    margin: 0 auto;
    padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--line);
}

.livr-valider {
    display: block;
    width: 100%;
    min-height: 48px;
    background: var(--ink);
    color: var(--black);
    border: 0;
    border-radius: var(--r-controle, 8px);
    font: inherit;
    font-size: .85rem;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    cursor: pointer;
}

.livr-erreur:not([hidden]) {
    margin: 0 0 8px;
    font-size: .85rem;
    color: #d0675c;
}

html.livr-bloque { overflow: hidden; }
html.livr-bloque .barre-payer { display: none !important; }

/* Point relais : on ne montre que la recherche et les points. */
.livr-vue-relais #delivery-modes,
.livr-vue-relais #delivery-modes-titre,
.livr-vue-relais #delivery-home-wrap,
.livr-vue-relais #delivery-widget-wrap { display: none; }

/* Domicile : l'adresse et les deux services, jamais les points. */
.livr-vue-domicile #delivery-colissimo-wrap,
.livr-vue-domicile #delivery-widget-wrap { display: none; }

.livr-vue-domicile .delivery-mode:not([data-kind="home"]) { display: none; }

.livr-exemple {
    margin: 8px 0 0;
    font-size: .8rem;
    color: var(--grey);
}

.livr-onglets { display: none; }

@media (max-width: 900px) {
    .livr-vue-relais .livr-onglets {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 6px;
        margin: 12px 0 4px;
        padding: 4px;
        background: rgba(var(--ink-rgb), .06);
        border-radius: var(--r-controle, 8px);
    }
    .livr-onglet {
        min-height: 40px;
        background: none;
        border: 0;
        border-radius: 6px;
        color: var(--grey);
        font: inherit;
        font-size: .85rem;
        font-weight: 600;
        cursor: pointer;
    }
    .livr-onglet[aria-selected="true"] {
        background: var(--ink);
        color: var(--black);
    }
    .livr-vue-relais[data-livr-affichage="liste"] .delivery-carte { display: none; }
    .livr-vue-relais[data-livr-affichage="carte"] .delivery-points,
    .livr-vue-relais[data-livr-affichage="carte"] #colissimo-points-plus { display: none; }
    .livr-vue-relais .delivery-selecteur .delivery-carte { max-height: 70vh; }
}


/* =======================================================
   MOBILE ET TABLETTE : JAMAIS DE ZOOM PARASITE (28/10/2026)
   - double-tap : coupé (touch-action:manipulation) ;
   - zoom automatique à la mise au point d'un champ : coupé, il
     se déclenche sous 16 px de texte (iOS) ;
   - pincement : voir initSansZoom (js/script.js) ; seule la
     visionneuse de photos (.pdp-zoom) zoome ;
   - menu du compte : défile quand il ne tient pas à l'écran.
======================================================= */
html{
    touch-action:manipulation;
}

@media (hover:none) and (pointer:coarse), (max-width:1024px){

    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]),
    select,
    textarea{
        font-size:16px !important;
    }

}

.navbar-menu:not(.hidden){
    max-height:calc(100vh - 90px);
    overflow-y:auto;
    overscroll-behavior:contain;
    -webkit-overflow-scrolling:touch;
}

.zoom-ouvert{
    overflow:hidden;
}

.pdp-zoom{
    position:fixed;
    inset:0;
    z-index:9000;
    display:flex;
    align-items:center;
    justify-content:center;
    background:rgba(0, 0, 0, .94);
    touch-action:none;
    overscroll-behavior:contain;
    -webkit-user-select:none;
    user-select:none;
}

.pdp-zoom-img{
    max-width:100%;
    max-height:100%;
    object-fit:contain;
    transform-origin:center;
    will-change:transform;
    -webkit-user-drag:none;
}

.pdp-zoom-fermer{
    position:absolute;
    top:calc(env(safe-area-inset-top, 0px) + 12px);
    right:14px;
    width:44px;
    height:44px;
    border:none;
    border-radius:50%;
    background:rgba(255, 255, 255, .16);
    color:#fff;
    font-size:28px;
    line-height:1;
    cursor:pointer;
}


/* VENDRE ET AFFILIATION : « EN CONSTRUCTION » (28/10/2026) — js/en-construction.js */
.lien-construction { opacity: .6; cursor: default; }

.lien-construction-icone {
    display: inline-flex;
    vertical-align: middle;
    margin-left: 6px;
    color: currentColor;
    opacity: .75;
}

.construction-toast {
    position: fixed;
    left: 50%;
    bottom: calc(24px + env(safe-area-inset-bottom, 0px));
    z-index: 9000;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 18px;
    background: var(--ink);
    color: var(--black);
    border-radius: 999px;
    font-size: .85rem;
    font-weight: 600;
    box-shadow: 0 6px 22px rgba(0, 0, 0, .35);
    opacity: 0;
    transform: translate(-50%, 12px);
    pointer-events: none;
    transition: opacity .18s ease-out, transform .18s ease-out;
}

.construction-toast-visible {
    opacity: 1;
    transform: translate(-50%, 0);
}


/* PAGE PROFIL — MISE EN FORME (28/10/2026)
   « Enregistrer » et « Se déconnecter » étaient de simples liens soulignés
   perdus sous les champs : ce sont de vrais boutons, tenant la largeur du
   champ. Espacements resserrés sur téléphone. */
.compte-page .compte-champ-action .auth-secondary-btn,
.compte-page .compte-encart .auth-secondary-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: auto;
    min-height: 44px;
    margin-top: 0;
    padding: 0 1.4rem;
    background: transparent;
    border: 1px solid var(--line);
    border-radius: var(--r-controle, 8px);
    color: var(--ink);
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    text-decoration: none;
}

.compte-page .compte-champ-action .auth-secondary-btn:hover,
.compte-page .compte-encart .auth-secondary-btn:hover {
    border-color: var(--ink);
}

.compte-page .compte-encart .auth-secondary-btn { margin-top: .8rem; }

.compte-page .compte-champ-action .auth-secondary-btn.hidden,
.compte-page .compte-encart .auth-secondary-btn.hidden { display: none; }

@media (max-width: 700px) {
    .compte-page .compte-titre { font-size: 2rem; }
    .compte-page .compte-bloc { margin-bottom: 1.8rem; }
    .compte-page .compte-champ-action { margin-top: .8rem; }
    .compte-page .compte-champ-action .auth-secondary-btn { width: 100%; }
    .compte-page .compte-detail { gap: 1.2rem; }
}


/* CGV : date de version, et champs restant à remplir (bien visibles,
   pour ne pas publier un crochet par mégarde). */
.legal-maj { margin: -.4rem 0 1.6rem; font-size: .85rem; color: var(--grey); }
.legal-a-completer { background: rgba(208, 103, 92, .18); color: inherit; padding: 0 .25em; border-radius: 3px; }

/* Une seule option de livraison pour ce pays : la carte prend toute la ligne,
   et une carte sans mode n'est jamais affichée. */
.livr-choix-carte[hidden] { display: none; }
.livr-choix-seul .livr-choix { grid-template-columns: 1fr; }


/* =========================================================
   VERROU D'ENTRÉE (28/10/2026) — js/verrou.js
   Tant qu'aucun code valable n'est saisi, tout le site est masqué
   et seul l'écran d'entrée s'affiche.
========================================================= */
html.verrou-ferme { overflow: hidden; }
html.verrou-ferme body > *:not(.verrou-ecran) { display: none !important; }

.verrou-ecran {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: grid;
    place-items: center;
    padding: 24px 16px;
    background: var(--black);
    color: var(--ink);
}

.verrou-boite {
    width: min(26rem, 100%);
    text-align: center;
}

.verrou-marque {
    margin: 0 0 28px;
    font-family: "Anton", sans-serif;
    font-size: 2.2rem;
    letter-spacing: .06em;
}

.verrou-titre {
    margin: 0 0 10px;
    font-family: "Anton", sans-serif;
    font-size: 1.4rem;
    font-weight: 400;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.verrou-texte {
    margin: 0 0 24px;
    color: var(--grey);
    font-size: .95rem;
    line-height: 1.5;
}

.verrou-form { display: flex; flex-direction: column; gap: 10px; text-align: left; }

.verrou-label {
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--grey);
}

.verrou-champ {
    width: 100%;
    min-height: 50px;
    padding: 0 14px;
    background: rgba(var(--ink-rgb), .04);
    border: 1px solid var(--line);
    border-radius: var(--r-controle, 8px);
    color: var(--ink);
    font: inherit;
    font-size: 18px;
    letter-spacing: .12em;
    text-transform: uppercase;
    text-align: center;
}

.verrou-champ:focus-visible { outline: 1px solid var(--ink); outline-offset: 1px; }

.verrou-erreur:not([hidden]) { margin: 0; color: #d0675c; font-size: .85rem; text-align: center; }

.verrou-bouton {
    min-height: 50px;
    background: var(--ink);
    color: var(--black);
    border: 0;
    border-radius: var(--r-controle, 8px);
    font: inherit;
    font-size: .85rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    cursor: pointer;
}

.verrou-bouton:disabled { opacity: .6; cursor: default; }

.verrou-contact { margin: 22px 0 0; font-size: .85rem; color: var(--grey); }
.verrou-contact a { color: var(--ink); }

/* Administration — onglet Accès (verrou d'entrée). */
.admin-acces-etat { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 12px; }
.admin-acces-etat .admin-help { margin: 0; font-weight: 600; }
.admin-acces-nouveau:not(.hidden) { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin: 14px 0; }
.admin-acces-nouveau .admin-help { flex-basis: 100%; margin: 0; }
.admin-acces-code { font-size: 1.3rem; letter-spacing: .12em; padding: 6px 12px; }


/* =========================================================
   ZONE PROTÉGÉE DU HAUT — ENCOCHE ET BARRE D'ÉTAT (28/10/2026)

   Toutes les pages déclarent viewport-fit=cover, et l'application
   posée sur l'écran d'accueil s'ouvre en plein écran avec une barre
   d'état transparente (black-translucent). Sur un iPhone à encoche,
   le haut de l'écran appartient donc à l'heure et à la batterie :
   la barre du site, la croix du menu, celle des filtres, le retour
   du volet de livraison y passaient dessous, et un doigt posé là
   fait remonter la page au lieu de toucher le bouton.

   UNE SEULE RÈGLE pour tout ce qui touche le haut de l'écran : la
   zone est prise par une BORDURE TRANSPARENTE de la hauteur de
   env(safe-area-inset-top). Pourquoi une bordure plutôt qu'une
   marge intérieure :
     · le fond de l'élément passe sous la bordure (background-clip
       vaut border-box) : la barre reste peinte jusqu'au bord, sous
       l'heure, sans bande vide ;
     · tout le contenu descend, Y COMPRIS les enfants en position
       absolue (la croix du menu, celle de la connexion) : ils se
       placent depuis l'intérieur de la bordure ;
     · les marges intérieures d'origine restent intactes.
   Ailleurs qu'en plein écran sur iPhone, la zone vaut 0 : rien ne
   bouge.

   Un élément de plus qui se colle au haut de l'écran ? L'ajouter
   à la liste ci-dessous, pas lui écrire sa propre règle. Exception
   déjà en place : le zoom photo (.pdp-zoom-fermer place sa croix
   avec env() lui-même ; la bordure la décalerait deux fois).
   Le menu du compte, lui, est placé par js/auth.js (placerMenu) :
   le backdrop-filter de .navbar fait de la barre le repère de ses
   enfants « fixes », donc le script mesure ce repère, qui commence
   sous la bordure.

   Contrôle : ARKWER ADMIN/SUPABASE/tests/test-hauteur-telephone.js
   (encoche simulée, chaque menu et panneau ouverts).
========================================================= */

:root {
    --zone-haut: env(safe-area-inset-top, 0px);
}

.navbar,
.sidebar,
.pf-feuille:not(.pf-feuille-tri),
.livr-actif #delivery-modes-wrap.livr-ouvert:not(.hidden),
.auth-modal-overlay,
.consent-panneau-fond,
.etats-voile,
.verrou-ecran {
    border-top: var(--zone-haut) solid transparent;
}

/* Ce qui se cale sous l'en-tête (ancres, colonnes collantes) compte
   la zone en plus : sur téléphone l'en-tête défile, la zone reste. */
html {
    scroll-padding-top: calc(var(--hauteur-header) + var(--zone-haut) + 16px);
}

/* Les commandes des barres et des panneaux : 44 px au doigt,
   comme les liens du menu latéral (même garde pointer: coarse). */
@media (pointer: coarse) {
    .navbar-menu-lien {
        display: flex;
        align-items: center;
        min-height: 44px;
    }

    .sidebar-nav .menu-secondaire a,
    .auth-modal-close,
    .consent-panneau-fermer,
    .flux-sortir,
    .flux-infos-fermer {
        min-width: 44px;
        min-height: 44px;
    }

    /* Liens texte seuls sur leur ligne : la zone de toucher grandit
       de 14 px de chaque côté, et la marge négative rend exactement
       cette place à la mise en page. Rien ne bouge à l'œil. */
    .auth-confiance-liens a,
    .flux-nom a {
        display: inline-block;
        padding-block: 14px;
        margin-block: -14px;
    }
}

/* Avis vérifiés (29/10/2026) : l'option « anonyme » est en tête, bien visible. */
.avis-anonyme { display: flex; align-items: center; gap: 10px; padding: 12px 14px; margin: 4px 0 6px; border: 1px solid var(--border, rgba(255,255,255,.18)); border-radius: 12px; font-weight: 600; cursor: pointer; }
.avis-anonyme input { width: 20px; height: 20px; flex: none; }
.review-form .review-star-input span:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.review-form .avis-anonyme { display: flex; align-items: center; gap: 12px; text-transform: none; letter-spacing: normal; font-size: 15px; font-weight: 600; margin: 4px 0 8px; }
.review-form .avis-anonyme input[type="checkbox"] { width: 22px; height: 22px; margin: 0; flex: none; accent-color: currentColor; }
.review-form .avis-anonyme + .review-form-note { margin: 0 0 18px; text-align: left; }

/* Avis : peu d'avis (< 6) = cartes centrées, sans défilement ni doublon. */
.testimonials-statique .testimonials-carousel { -webkit-mask-image: none; mask-image: none; overflow: visible; }
.testimonials-statique .testimonials-carousel.reverse { display: none; }
.testimonials-statique .testimonials-list { width: auto; flex-wrap: wrap; justify-content: center; gap: 16px; transform: none; }
.testimonials-statique .testimonial-card { width: min(340px, 100%); }

/* =========================================================
   AVIS VÉRIFIÉS — nouvelle présentation (30/10/2026)
   js/avis-accueil.js. Remplace le carrousel automatique.
========================================================= */
.avis-section { max-width: 1200px; margin: 0 auto 48px; padding: 0 24px; }
.avis-entete { display: flex; flex-direction: column; align-items: center; gap: 10px; margin-bottom: 24px; text-align: center; }
.avis-surtitre { font-size: 12px; letter-spacing: .2em; text-transform: uppercase; opacity: .6; margin: 0; }
.avis-score { display: flex; align-items: center; gap: 14px; }
.avis-moyenne { font-size: 52px; font-weight: 700; line-height: 1; letter-spacing: -.02em; }
.avis-score-droite { text-align: left; }
.avis-etoiles-moy { font-size: 20px; letter-spacing: 2px; margin: 0; }
.avis-total { font-size: 13px; opacity: .65; margin: 2px 0 0; }
.avis-badge { font-size: 12px; padding: 6px 12px; border: 1px solid rgba(127,127,127,.35); border-radius: 999px; color: inherit; opacity: .8; text-decoration: none; }
.avis-badge:hover { opacity: 1; }

.avis-cadre { position: relative; }
.avis-piste { display: flex; justify-content: center; gap: 16px; flex-wrap: wrap; }
.avis-cadre--defile .avis-piste { justify-content: flex-start; flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding: 0 4px; padding: 4px 4px 12px; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.avis-cadre--defile .avis-piste::-webkit-scrollbar { display: none; }

.avis-carte { flex: 0 0 320px; max-width: 100%; scroll-snap-align: start; display: flex; flex-direction: column; gap: 10px; padding: 18px; border-radius: 16px; background: linear-gradient(165deg, var(--card, #2a2a2a) 0%, var(--dark, #1c1c1c) 100%); border: 1px solid rgba(127,127,127,.18); }
.avis-carte-haut { display: flex; align-items: center; gap: 10px; }
.avis-avatar { width: 36px; height: 36px; flex: none; border-radius: 50%; display: grid; place-items: center; font-size: 13px; font-weight: 700; background: rgba(127,127,127,.2); }
.avis-qui p { margin: 0; }
.avis-auteur { font-weight: 600; font-size: 14px; }
.avis-meta { font-size: 12px; opacity: .6; }
.avis-note { margin: 0; font-size: 15px; letter-spacing: 2px; }
.avis-texte { margin: 0; font-size: 14px; line-height: 1.55; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden; }
.avis-reponse { margin-top: auto; padding: 10px 12px; border-radius: 10px; background: rgba(127,127,127,.12); font-size: 13px; }
.avis-reponse p { margin: 0; }
.avis-reponse-titre { font-weight: 700; font-size: 12px; margin-bottom: 4px !important; }

.avis-fleche { position: absolute; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; border-radius: 50%; border: 1px solid rgba(127,127,127,.35); background: var(--dark, #1c1c1c); color: inherit; font-size: 22px; line-height: 1; cursor: pointer; z-index: 2; }
.avis-fleche--prec { left: -18px; }
.avis-fleche--suiv { right: -18px; }

@media (max-width: 700px) {
    .avis-section { padding: 0 16px; }
    .avis-carte { flex-basis: 82vw; }
    .avis-piste { flex-wrap: nowrap; justify-content: safe center; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
    .avis-fleche { display: none; }
    .avis-moyenne { font-size: 44px; }
}

/* Page temporaire essai-avis.html */
.essai-page { padding: 32px 0; }
.essai-titre { text-align: center; opacity: .6; font-size: 14px; letter-spacing: .2em; margin: 48px 0 16px; }
