/* ---------------------------------------------------------------------
   Polices de marque, servies depuis le thème.
   Elles étaient chargées depuis jtoulemonde.com ; les héberger ici évite une
   dépendance à un autre domaine (une police tierce est soumise au CORS et
   échouerait silencieusement, laissant la police de repli s'installer sans
   que personne ne s'en aperçoive).
   Couverture vérifiée : accents français complets sur les deux fontes.
   --------------------------------------------------------------------- */
@font-face {
  font-family: "Dolce Vita";
  src: url("../fonts/dolce-vita-heavy-bold.ttf") format("truetype");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Sofia Pro";
  src: url("../fonts/sofia-pro-regular.woff") format("woff"),
       url("../fonts/sofia-pro-regular.ttf") format("truetype");
  font-weight: 300 400;
  font-style: normal;
  font-display: swap;
}

/* =====================================================================
   Toulemonde — refonte visuelle
   =====================================================================

   Thème enfant de `classic`. Aucun fichier du thème parent n'est modifié :
   cette feuille est chargée en dernier et surcharge `theme.css`.

   Historique : la première version reprenait littéralement la charte du site
   institutionnel jtoulemonde.com (bleu #0000FE, capitales Dolce Vita partout,
   angles droits). L'audit visuel a montré deux limites — le bleu pur fatigue
   sur de grands aplats, et la police d'affichage devient illisible en petites
   capitales. Cette version garde l'identité et corrige l'usage.

   ÉCART À CONNAÎTRE : le bleu primaire passe de #0000FE à un bleu encre
   désaturé. #0000FE est la couleur réellement déclarée dans le kit Elementor
   de jtoulemonde.com : on s'éloigne donc de la charte institutionnelle. C'est
   un choix demandé et assumé, réversible en changeant `--tm-primary`.
   ===================================================================== */

:root {
  /* --- Couleurs -----------------------------------------------------
     Primaire : bleu encre, pour les titres et les actions principales.
     Accent : un seul ton chaud, réservé aux étiquettes et promotions.
     Les neutres portent tout le reste. */
  --tm-primary: #1b2a6b;
  --tm-primary-dark: #14205a;
  --tm-primary-light: #22307a;
  --tm-primary-wash: #f2f4fa;
  --tm-primary-line: #c9d0e6;

  /* Bleu électrique de la marque, celui de l'ancien portail et de la page de
     connexion. Distinct du bleu encre : il ne sert qu'aux actions. */
  --tm-electrique: rgb(0, 0, 254);
  --tm-electrique-sombre: rgb(0, 0, 214);

  --tm-accent: #b8763e;
  --tm-accent-dark: #9a6133;
  --tm-accent-wash: #f8f1ea;

  --tm-ink: #111111;
  --tm-ink-soft: #5a5f66;
  --tm-line: #e6e8ec;
  --tm-surface: #f7f7f5;
  --tm-white: #ffffff;

  --tm-danger: #a12a2a;
  --tm-success: #1f6b45;

  /* --- Typographie --------------------------------------------------
     Dolce Vita est une police d'affichage : ses A et V obliques la rendent
     illisible en petites capitales. Elle est donc réservée aux h1 et h2, et
     jamais sous 20px. Tout le reste — boutons, menus, libellés, footer —
     passe en Sofia Pro. */
  --tm-display: "Dolce Vita", "Arial Black", Impact, sans-serif;
  --tm-text: "Sofia Pro", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;

  --tm-fs-h1: 2.5rem;    /* 40 */
  --tm-fs-h2: 1.875rem;  /* 30 */
  --tm-fs-h3: 1.5rem;    /* 24 */
  --tm-fs-h4: 1.25rem;   /* 20 */
  --tm-fs-base: 1rem;    /* 16 */
  --tm-fs-sm: 0.875rem;  /* 14 */
  --tm-fs-xs: 0.75rem;   /* 12 */

  --tm-lh-tight: 1.2;
  --tm-lh-base: 1.6;

  /* --- Espacement : échelle de 8 --------------------------------- */
  --tm-1: 8px;
  --tm-2: 16px;
  --tm-3: 24px;
  --tm-4: 32px;
  --tm-6: 48px;
  --tm-8: 64px;
  --tm-12: 96px;

  --tm-radius: 4px;
  --tm-radius-pill: 999px;
  --tm-shadow: 0 1px 2px rgba(17, 17, 17, 0.06);
  --tm-shadow-lift: 0 6px 20px rgba(17, 17, 17, 0.1);
  --tm-transition: 160ms ease;

  --tm-header-h: 72px;
  --tm-largeur: 1440px;

  /* Alias de compatibilité : la première charte est encore référencée par
     des dizaines de règles plus bas. Les redéfinir ici évite une réécriture
     massive à haut risque, et un seul endroit continue de faire foi. */
  --tlm-bleu: var(--tm-primary);
  --tlm-bleu-voile: var(--tm-primary-wash);
  --tlm-bleu-trait: var(--tm-primary-line);
  --tlm-noir: var(--tm-ink);
  --tlm-blanc: var(--tm-white);
  --tlm-gris: var(--tm-ink-soft);
  --tlm-gris-clair: var(--tm-line);
  --tlm-gris-fond: var(--tm-surface);
  --tlm-titre: var(--tm-display);
  --tlm-texte: var(--tm-text);
  --tlm-trait: 2px;
  --tlm-largeur: var(--tm-largeur);
}

/* ---------------------------------------------------------------------
   Base
   --------------------------------------------------------------------- */
body,
body.lang-fr {
  font-family: var(--tlm-texte);
  font-weight: 300;
  /* Le site de référence descend à -0.7px, soit -0.05em. Tenable sur du texte
     éditorial, illisible sur un tableau de commandes ou un formulaire
     d'adresse. Le resserrement est conservé, à un tiers de l'intensité. */
  letter-spacing: -0.02em;
  line-height: 1.6;
  color: var(--tlm-noir);
  background: var(--tlm-blanc);
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0;
  line-height: 1.05;
  color: var(--tlm-noir);
  text-wrap: balance;
}

h1, .h1 { font-size: 2.5rem; }
h2, .h2 { font-size: 1.9rem; }
h3, .h3 { font-size: 1.4rem; }
h4, .h4 { font-size: 1.15rem; }
h5, .h5,
h6, .h6 { font-size: 1rem; }

a {
  color: var(--tlm-bleu);
  text-decoration: none;
  transition: color 120ms ease;
}

a:hover,
a:focus {
  color: var(--tlm-noir);
  text-decoration: none;
}

/* Le site institutionnel n'a pas d'ornement : les séparations sont des traits
   nets, jamais des ombres ni des dégradés.
   
   Le trait épais est réservé aux séparations de SECTION, posées explicitement
   (en-tête de page, header, footer, en-têtes de tableaux). Un <hr> générique
   reste discret : le thème en sème à l'intérieur de composants — carte
   d'adresse, formulaire de connexion — où un trait noir de 2px coupe le
   contenu en deux au lieu de le structurer. */
hr {
  border: 0;
  border-top: 1px solid var(--tlm-gris-clair);
  opacity: 1;
}

#wrapper {
  background: var(--tlm-blanc);
  padding-top: 1.5rem;
}

#wrapper .container,
#header .container,
#footer .container {
  max-width: var(--tlm-largeur);
}

/* Encadrés de contenu : fond blanc, trait franc, pas d'arrondi ni d'ombre. */
#main .page-header,
#main .page-content,
#main .page-footer,
.card,
.block-categories,
#search_filters,
.cart-summary,
.cart-container,
#js-checkout-summary {
  background: var(--tlm-blanc);
  border: 1px solid var(--tlm-gris-clair);
  border-radius: 0;
  box-shadow: none;
}

#main .page-header {
  border: 0;
  border-bottom: var(--tlm-trait) solid var(--tlm-noir);
  padding-bottom: 0.75rem;
  margin-bottom: 1.5rem;
}

#main .page-header h1 {
  margin-bottom: 0;
}

/* ---------------------------------------------------------------------
   Boutons

   Le site de référence les veut carrés, en majuscules, bordure pleine de 2px,
   avec deux variantes : bleu plein et contour bleu sur blanc. Le survol
   inverse les deux couleurs — c'est tout l'effet, il n'y a ni ombre ni
   déplacement.

   Écart assumé : la référence pose 22px de corps et 17px/40px de rembourrage,
   dimensions d'un bouton de page d'accueil. Une interface e-commerce en compte
   plusieurs par écran ; l'échelle est ramenée à celle d'une interface, la forme
   et les couleurs sont conservées telles quelles.
   --------------------------------------------------------------------- */
.btn,
.btn-primary,
.btn-secondary,
.btn-tertiary,
button.btn,
input[type="submit"].btn {
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  font-size: 0.875rem;
  line-height: 1.2;
  border-radius: 0;
  border: var(--tlm-trait) solid transparent;
  padding: 0.75rem 1.75rem;
  box-shadow: none;
  transition: background-color 140ms ease, color 140ms ease, border-color 140ms ease;
}

.btn-primary,
.btn-primary:not(:disabled):not(.disabled) {
  background: var(--tlm-bleu);
  border-color: var(--tlm-bleu);
  color: var(--tlm-blanc);
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active,
.btn-primary:not(:disabled):not(.disabled):active {
  background: var(--tlm-blanc);
  border-color: var(--tlm-bleu);
  color: var(--tlm-bleu);
}

.btn-secondary,
.btn-tertiary {
  background: var(--tlm-blanc);
  border-color: var(--tlm-bleu);
  color: var(--tlm-bleu);
}

.btn-secondary:hover,
.btn-secondary:focus,
.btn-tertiary:hover,
.btn-tertiary:focus {
  background: var(--tlm-bleu);
  border-color: var(--tlm-bleu);
  color: var(--tlm-blanc);
}

.btn.disabled,
.btn:disabled {
  background: var(--tlm-gris-clair);
  border-color: var(--tlm-gris-clair);
  color: var(--tlm-gris);
  opacity: 1;
}

/* Un contour visible au clavier : le survol seul laisserait la navigation au
   clavier sans repère. */
.btn:focus-visible,
a:focus-visible,
.form-control:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: var(--tlm-trait) solid var(--tlm-bleu);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------
   Formulaires
   --------------------------------------------------------------------- */
.form-control,
input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="tel"],
input[type="number"],
select,
textarea {
  font-family: var(--tlm-texte);
  font-weight: 300;
  border: 1px solid var(--tlm-gris-clair);
  border-radius: 0;
  box-shadow: none;
  background: var(--tlm-blanc);
  color: var(--tlm-noir);
}

.form-control:focus,
input:focus,
select:focus,
textarea:focus {
  border-color: var(--tlm-bleu);
  box-shadow: none;
}

.form-control-label,
label {
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--tlm-noir);
}

.form-control-comment {
  font-size: 0.8rem;
  color: var(--tlm-gris);
}

/* ---------------------------------------------------------------------
   En-tête et navigation
   --------------------------------------------------------------------- */
#header {
  background: var(--tlm-blanc);
  color: var(--tlm-noir);
  box-shadow: none;
  border-bottom: var(--tlm-trait) solid var(--tlm-noir);
}

#header .header-top {
  background: var(--tlm-blanc);
  border-bottom: 1px solid var(--tlm-gris-clair);
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
}

#header .header-top a,
#header .header-nav a,
#header .header-top .dropdown-toggle {
  color: var(--tlm-noir);
  font-family: var(--tlm-texte);
}

#header .header-top a:hover,
#header .header-nav a:hover,
#header .header-top .dropdown-toggle:hover {
  color: var(--tlm-bleu);
}

/* Barre de service : liens courts, en majuscules, sans ornement. */
#header .header-nav {
  background: var(--tlm-blanc);
  border-bottom: 1px solid var(--tlm-gris-clair);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

#header #_desktop_user_info .account,
#header #_desktop_language_selector .dropdown-toggle,
#header #_desktop_currency_selector .dropdown-toggle,
#header #contact-link {
  border: 0;
  border-radius: 0;
  padding: 0.35rem 0.6rem;
  font-family: var(--tlm-titre);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 400;
}

#header #_desktop_user_info .account:hover,
#header #_desktop_language_selector .dropdown-toggle:hover,
#header #_desktop_currency_selector .dropdown-toggle:hover,
#header #contact-link:hover {
  background: var(--tlm-bleu-voile);
  color: var(--tlm-bleu);
}

/* Menu principal. Le soulignement bleu remplace le fond coloré du thème
   classique : le site de référence marque l'état actif par un trait, jamais par
   un aplat. */
#header .menu > ul > li > a,
#_desktop_top_menu .top-menu a[data-depth="0"] {
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.9rem;
  color: var(--tlm-noir);
  padding: 0.9rem 1rem;
  border-bottom: var(--tlm-trait) solid transparent;
}

#header .menu > ul > li > a:hover,
#_desktop_top_menu .top-menu a[data-depth="0"]:hover,
#_desktop_top_menu .top-menu li.current > a[data-depth="0"] {
  color: var(--tlm-bleu);
  border-bottom-color: var(--tlm-bleu);
  background: transparent;
}

#_desktop_top_menu .top-menu .sub-menu,
#header .popover {
  border: 1px solid var(--tlm-gris-clair);
  border-radius: 0;
  box-shadow: none;
}

#header .logo,
#_desktop_logo img {
  max-height: 64px;
  width: auto;
}

/* Recherche */
#search_widget form input[type="text"],
.search-widgets input[type="text"] {
  border: 1px solid var(--tlm-gris-clair);
  border-radius: 0;
}

#search_widget form button[type="submit"],
.search-widgets button[type="submit"] {
  color: var(--tlm-bleu);
}

/* Panier d'en-tête */
#_desktop_cart .cart-preview .header,
#_desktop_cart a {
  color: var(--tlm-noir);
}

#_desktop_cart .cart-products-count {
  font-family: var(--tlm-titre);
  color: var(--tlm-bleu);
}

/* ---------------------------------------------------------------------
   Fil d'Ariane
   --------------------------------------------------------------------- */
.breadcrumb {
  background: transparent;
  padding-left: 0;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.breadcrumb li a {
  color: var(--tlm-gris);
}

.breadcrumb li:last-child span {
  color: var(--tlm-noir);
}

/* ---------------------------------------------------------------------
   Listing produits (accueil, catégorie, résultats de recherche)
   --------------------------------------------------------------------- */
/* Étiquettes produit : carrées, bleu plein, comme les boutons. */
.product-flags .product-flag,
.product-flag {
  border-radius: 0;
  background: var(--tlm-bleu);
  color: var(--tlm-blanc);
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.7rem;
  box-shadow: none;
}

.product-flag.discount,
.product-flag.on-sale {
  background: var(--tlm-noir);
}

/* Tri, pagination, filtres */
.products-sort-order .select-title,
.pagination .page-list li a {
  border-radius: 0;
  border: 1px solid var(--tlm-gris-clair);
  color: var(--tlm-noir);
}

.pagination .page-list li.current a {
  background: var(--tlm-bleu);
  border-color: var(--tlm-bleu);
  color: var(--tlm-blanc);
}

#search_filters .facet-title,
.block-categories .block-title,
.block-title {
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--tlm-noir);
}

/* ---------------------------------------------------------------------
   Fiche produit
   --------------------------------------------------------------------- */
#product .product-prices .current-price,
#product .product-price,
.product-prices .price {
  font-family: var(--tlm-titre);
  font-weight: 400;
  color: var(--tlm-bleu);
  font-size: 2rem;
  line-height: 1.1;
}

#product .product-prices .tax-shipping-delivery-label {
  font-family: var(--tlm-texte);
  font-size: 0.8rem;
  color: var(--tlm-gris);
  text-transform: none;
}

#product h1,
#product .product-title,
.product-detail-name {
  font-family: var(--tlm-titre);
  text-transform: uppercase;
  line-height: 1.05;
}

#product .product-reference,
#product .product-quantities {
  font-size: 0.85rem;
  color: var(--tlm-gris);
}

/* Le bouton d'ajout au panier est l'action principale de la page : il prend le
   bleu plein, sur toute la largeur de sa colonne. */
#product .add-to-cart,
.product-add-to-cart .add-to-cart {
  width: 100%;
  padding: 1rem 1.75rem;
  font-size: 1rem;
}

#product .product-quantity .input-group,
#product .qty .input-group {
  border-radius: 0;
}

#product .product-quantity input.input-group,
#product #quantity_wanted {
  border-radius: 0;
  border: 1px solid var(--tlm-gris-clair);
  font-family: var(--tlm-titre);
}

/* Déclinaisons. Le catalogue monte à plusieurs centaines de coloris sur un
   même article : la liste est donc bornée en hauteur et défilante, sinon la
   fiche produit devient impraticable. Aucune structure n'est modifiée, seule
   la boîte du groupe est contrainte. */
#product .product-variants .product-variants-item {
  margin-bottom: 1rem;
}

#product .product-variants .product-variants-item > label,
#product .product-variants .form-control-label {
  display: block;
  margin-bottom: 0.4rem;
}

#product .product-variants .product-variants-item select.form-control {
  border-radius: 0;
  max-width: 420px;
}

/* La grille défilante des pastilles natives a été retirée : le module
   `toulemondecolorpicker` possède désormais ce bloc et masque la liste native.
   La conserver obligeait le module à lutter de spécificité contre elle. */

#product .product-variants .input-color + span,
#product .product-variants .color {
  border-radius: 0;
  border: 1px solid var(--tlm-gris-clair);
}

#product .product-variants .input-color:checked + span,
#product .product-variants .input-color:focus-visible + span {
  outline: var(--tlm-trait) solid var(--tlm-bleu);
  outline-offset: 1px;
  border-color: var(--tlm-bleu);
}

/* Onglets de description */
#product .tabs,
.product-tabs {
  border-radius: 0;
  box-shadow: none;
  border: 1px solid var(--tlm-gris-clair);
}

#product .tabs .nav-tabs {
  border-bottom: var(--tlm-trait) solid var(--tlm-noir);
}

#product .tabs .nav-tabs .nav-link {
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--tlm-gris);
  border: 0;
  border-bottom: var(--tlm-trait) solid transparent;
  border-radius: 0;
}

#product .tabs .nav-tabs .nav-link.active,
#product .tabs .nav-tabs .nav-link:hover {
  color: var(--tlm-bleu);
  border-bottom-color: var(--tlm-bleu);
  background: transparent;
}

/* ---------------------------------------------------------------------
   Panier
   --------------------------------------------------------------------- */
.cart-grid-body .card,
.cart-container {
  border-radius: 0;
  box-shadow: none;
}

.cart-summary,
#js-checkout-summary {
  border-radius: 0;
  box-shadow: none;
  background: var(--tlm-bleu-voile);
  border: 1px solid var(--tlm-bleu-trait);
}

.cart-summary .cart-summary-line .label,
.cart-summary-line .label {
  font-family: var(--tlm-texte);
  color: var(--tlm-gris);
  text-transform: none;
}

.cart-summary .cart-total .value,
.cart-total .value,
.cart-summary-totals .cart-total {
  font-family: var(--tlm-titre);
  font-weight: 400;
  color: var(--tlm-bleu);
  font-size: 1.3rem;
}

.cart-item .product-line-info a.label,
.cart-item .product-line-info .label {
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  color: var(--tlm-noir);
}

.cart-item .product-price,
.product-line-grid-body .product-price {
  font-family: var(--tlm-titre);
  color: var(--tlm-bleu);
}

.cart-detailed-actions .btn,
.checkout .btn {
  width: 100%;
  padding: 1rem 1.75rem;
}

.cart-empty .no-items,
#cart .no-items {
  color: var(--tlm-gris);
}

/* ---------------------------------------------------------------------
   Tunnel de commande
   --------------------------------------------------------------------- */
.checkout-step {
  border: 1px solid var(--tlm-gris-clair);
  border-radius: 0;
  box-shadow: none;
  margin-bottom: 1rem;
}

.checkout-step .step-title,
.checkout-step h1.step-title {
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--tlm-noir);
  font-size: 1.05rem;
}

.checkout-step.-current {
  border-color: var(--tlm-bleu);
  border-width: var(--tlm-trait);
}

.checkout-step.-current .step-title {
  color: var(--tlm-bleu);
}

/* Numéro d'étape : carré bleu, pas de pastille ronde. */
.checkout-step .step-number,
.checkout-step .step-edit {
  border-radius: 0;
  color: var(--tlm-bleu);
}

.checkout-step.-complete .step-title .done,
.checkout-step .done {
  color: var(--tlm-bleu);
}

.delivery-option,
.payment-option {
  border: 1px solid var(--tlm-gris-clair);
  border-radius: 0;
  background: var(--tlm-blanc);
}

.delivery-option:hover,
.payment-option:hover {
  border-color: var(--tlm-bleu-trait);
}

.order-confirmation-table,
#order-details {
  border: 1px solid var(--tlm-gris-clair);
  border-radius: 0;
}

/* ---------------------------------------------------------------------
   Compte client
   --------------------------------------------------------------------- */
.page-my-account #content .links a,
#my-account .links a,
.account-list a {
  color: var(--tlm-noir);
  font-family: var(--tlm-texte);
}

.page-my-account #content .links a span.link-item,
#my-account .links a span.link-item {
  background: var(--tlm-blanc);
  border: 1px solid var(--tlm-gris-clair);
  border-radius: 0;
  box-shadow: none;
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: 0.85rem;
  transition: border-color 140ms ease, color 140ms ease;
}

.page-my-account #content .links a:hover span.link-item,
#my-account .links a:hover span.link-item {
  border-color: var(--tlm-bleu);
  color: var(--tlm-bleu);
}

.page-my-account #content .links a i,
#my-account .links a i {
  color: var(--tlm-bleu);
}

/* Historique de commandes, adresses, avoirs : des tableaux, donc des traits. */
.table,
.table-striped,
.table-bordered,
.table-labeled {
  border-radius: 0;
}

.table thead th,
.thead-default th {
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: 0.8rem;
  color: var(--tlm-noir);
  border-bottom: var(--tlm-trait) solid var(--tlm-noir);
  background: transparent;
}

.table td,
.table-labeled td {
  border-color: var(--tlm-gris-clair);
  /* Les colonnes de montants et de dates s'alignent chiffre à chiffre. */
  font-variant-numeric: tabular-nums;
}

/* La classe `address` sert à DEUX composants distincts :
     - compte client : <article class="address"> — la carte entière ;
     - tunnel        : <div class="address"> — les seules lignes d'adresse,
                       imbriquées dans .address-item.
   Encadrer les deux dessinait un cadre parasite autour du texte dans le
   tunnel. Le sélecteur retient donc l'élément, pas seulement la classe. */
article.address {
  border: 1px solid var(--tlm-gris-clair);
  border-radius: 0;
  box-shadow: none;
}

article.address .address-body {
  padding: 1rem;
}

article.address .address-body h4 {
  font-family: var(--tlm-titre);
  text-transform: uppercase;
  font-size: 0.95rem;
  margin-bottom: 0.5rem;
}

article.address .address-footer {
  background: var(--tlm-bleu-voile);
  border-top: 1px solid var(--tlm-gris-clair);
  padding: 0.6rem 1rem;
}

/* ---------------------------------------------------------------------
   Notifications
   --------------------------------------------------------------------- */
.alert,
.notifications-container .alert {
  border-radius: 0;
  border-width: 0 0 0 var(--tlm-trait);
  box-shadow: none;
  font-family: var(--tlm-texte);
}

.alert-success {
  background: var(--tlm-bleu-voile);
  border-left-color: var(--tlm-bleu);
  color: var(--tlm-noir);
}

.alert-info {
  background: var(--tlm-gris-fond);
  border-left-color: var(--tlm-noir);
  color: var(--tlm-noir);
}

.alert-warning,
.alert-danger {
  background: var(--tlm-gris-fond);
  border-left-color: var(--tlm-noir);
  color: var(--tlm-noir);
}

/* ---------------------------------------------------------------------
   Parcours PunchOut

   Le bouton de transfert vers Coupa reste l'action principale du panier : même
   traitement que les autres actions primaires. Il n'est pas distingué
   visuellement de l'action « Commander » du parcours standard, parce qu'un
   acheteur ne voit jamais les deux — le marqueur de panier détermine lequel
   s'affiche.
   --------------------------------------------------------------------- */
.punchout-handoff-form .btn,
#punchout-handoff .btn,
.cart-detailed-actions .btn-punchout {
  width: 100%;
  padding: 1rem 1.75rem;
  font-size: 1rem;
}

/* ---------------------------------------------------------------------
   Pied de page

   Le site de référence sépare le pied de page par un trait de 2px et garde un
   fond clair : pas de bandeau sombre.
   --------------------------------------------------------------------- */
#footer {
  background: var(--tlm-blanc);
  border-top: var(--tlm-trait) solid var(--tlm-noir);
  padding-top: 2rem;
  color: var(--tlm-noir);
}

#footer .footer-container {
  background: transparent;
  box-shadow: none;
  margin-top: 0;
  padding-top: 0;
}

#footer .h3,
#footer .myaccount-title,
#footer .block-contact .block-contact-title,
#footer .links .h3 {
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: 0.95rem;
  color: var(--tlm-noir);
}

#footer a,
#footer .links a {
  color: var(--tlm-gris);
  font-size: 0.9rem;
}

#footer a:hover,
#footer .links a:hover {
  color: var(--tlm-bleu);
}

#footer .block-contact {
  border-left: 0;
  padding-left: 0;
  color: var(--tlm-gris);
  font-size: 0.9rem;
}

#footer .copyright,
#footer .bottom-footer {
  border-top: 1px solid var(--tlm-gris-clair);
  margin-top: 1.5rem;
  padding: 1rem 0;
  font-size: 0.8rem;
  color: var(--tlm-gris);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* ---------------------------------------------------------------------
   Écran de connexion

   Il reste le premier écran vu par un client B2B : il porte la charte de façon
   plus marquée que le reste, sans changer la structure du formulaire.
   --------------------------------------------------------------------- */
/* `#authentication` a été retiré de cette section : la page de connexion est
   entièrement reprise plus bas, et ces règles — deux identifiants de
   spécificité — l'emportaient sur elle. Reste `#password`, l'écran de
   récupération, qui garde l'habillage courant de la boutique. */
#password .page-header {
  border-bottom: var(--tlm-trait) solid var(--tlm-noir);
}

#password .form-control-label {
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

#password .form-control {
  padding: 0.7rem 0.9rem;
}

#password .forgot-password a {
  font-size: 0.85rem;
}

/* ---------------------------------------------------------------------
   Adaptations petits écrans
   --------------------------------------------------------------------- */
@media (max-width: 767px) {
  h1, .h1 { font-size: 1.9rem; }
  h2, .h2 { font-size: 1.5rem; }

  #header .logo,
  #_desktop_logo img { max-height: 48px; }

  #product .product-prices .current-price,
  #product .product-price { font-size: 1.6rem; }

  .btn,
  .btn-primary,
  .btn-secondary { padding: 0.7rem 1.25rem; }

  /* Le thème remplace déjà le tableau d'historique par des blocs .order en
     dessous de « sm ». Reste le tableau de confirmation de commande, qui n'a
     pas d'équivalent : il défile dans sa propre boîte plutôt que d'élargir la
     page. */
  .order-confirmation-table {
    display: block;
    overflow-x: auto;
  }

  #history .orders .order {
    border: 1px solid var(--tlm-gris-clair);
    margin-bottom: 0.5rem;
    padding: 0.75rem;
  }
}

/* Les animations d'apparition du thème ne sont pas imposées à qui les refuse. */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* =====================================================================
   Corrections de l'audit visuel du 28 août 2026

   Regroupées ici, et non fondues dans les sections ci-dessus, pour qu'on
   voie d'un coup d'œil ce qui a été ajouté après coup et pourquoi.

   `custom.css` est chargée en DERNIER par le thème : à spécificité égale
   elle l'emporte déjà. Les sélecteurs ci-dessous ne sont alourdis que
   lorsqu'il faut battre une règle plus spécifique du thème parent ou d'un
   module, et le commentaire dit alors laquelle.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1. Carte d'adresse du tunnel (page « Commande », étape 2)

   Trois défauts cumulés. Le cadre parasite et le filet noir venaient de la
   charte, corrigés plus haut à la source. Restait le vide : le thème impose
   11.7rem de hauteur minimale à l'en-tête de la carte pour aligner deux
   cartes côte à côte. Avec une seule adresse courte, cela laisse ~80px de
   blanc. Le conteneur est déjà en flex, qui égalise les hauteurs tout seul :
   la hauteur minimale ne sert plus à rien.
   --------------------------------------------------------------------- */
body#checkout section.checkout-step .address-item > header {
  min-height: 0;
  padding-bottom: 0.5rem;
}

/* Le <div class="address"> interne ne porte plus de cadre (voir article.address
   plus haut), mais il garde une marge propre pour ne pas coller au libellé. */
body#checkout section.checkout-step .address-item .address {
  margin-top: 0.35rem;
  padding: 0;
  border: 0;
}

/* Le <hr> interne de la carte : simple séparation avant les actions. */
body#checkout section.checkout-step .address-item hr {
  margin: 0;
  border-top-color: var(--tlm-gris-clair);
}

/* ---------------------------------------------------------------------
   2. Phrase d'introduction de l'historique de commandes

   Le thème balise « Vous trouverez ici vos commandes… » en <h6>. La règle
   générale de titraison la passait en majuscules dans la police d'affichage,
   qui est faite pour des titres courts : sur une phrase entière, elle devient
   pénible à lire. On la rend à sa nature de texte courant.

   Ciblé sur #history uniquement : ailleurs, un <h6> reste un titre.
   --------------------------------------------------------------------- */
#history .page-content > h6,
#order-detail .page-content > h6 {
  font-family: var(--tlm-texte);
  font-weight: 300;
  text-transform: none;
  letter-spacing: -0.02em;
  line-height: 1.6;
  font-size: 1rem;
  color: var(--tlm-gris);
  margin-bottom: 1.25rem;
}

/* ---------------------------------------------------------------------
   3. Bloc panier de l'en-tête

   Thème parent : `#header .header-nav .cart-preview.active` — un identifiant
   et trois classes. Il faut au moins autant pour reprendre la main.
   --------------------------------------------------------------------- */
#header .header-nav .blockcart.cart-preview,
#header .header-nav .blockcart.cart-preview.active {
  background: var(--tlm-bleu);
}

#header .header-nav .blockcart.cart-preview a,
#header .header-nav .blockcart.cart-preview.active a,
#header .header-nav .blockcart.cart-preview.active i,
#header .header-nav .blockcart.cart-preview .cart-products-count {
  color: var(--tlm-blanc);
}

#header .header-nav .blockcart.cart-preview a:hover,
#header .header-nav .blockcart.cart-preview.active a:hover {
  color: var(--tlm-blanc);
  text-decoration: underline;
}

/* ---------------------------------------------------------------------
   4. Étiquettes produit

   Thème parent : `.product-flags li.product-flag` — deux classes ET un
   élément. Ma règle à deux classes perdait sur le seul `li`.
   --------------------------------------------------------------------- */
.product-flags li.product-flag,
.product-miniature .product-flags li.product-flag {
  background: var(--tlm-bleu);
  color: var(--tlm-blanc);
  border-radius: 0;
  font-family: var(--tlm-titre);
  font-weight: 400;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
}

.product-flags li.product-flag.discount,
.product-flags li.product-flag.on-sale {
  background: var(--tlm-noir);
}

/* ---------------------------------------------------------------------
   5. Adresse sélectionnée dans le tunnel

   Thème parent : bordure cyan de 3px. On garde l'épaisseur — c'est ce qui
   rend la sélection lisible — et on change la couleur.
   --------------------------------------------------------------------- */
body#checkout section.checkout-step .address-item.selected {
  background: var(--tlm-blanc);
  border: var(--tlm-bleu) 3px solid;
}

body#checkout section.checkout-step .address-item {
  background: var(--tlm-blanc);
  border: 3px solid var(--tlm-gris-clair);
}

/* ---------------------------------------------------------------------
   6. Pastille de l'étape courante

   Elle est verte dans le thème : seule tache de vert du site, juste à côté
   d'un titre bleu.
   --------------------------------------------------------------------- */
body#checkout section.checkout-step .step-number,
body#checkout section.checkout-step.-reachable.-current .step-number,
body#checkout section.checkout-step.-current.-reachable.-complete .step-number {
  background: var(--tlm-bleu);
  color: var(--tlm-blanc);
  border-radius: 0;
  font-family: var(--tlm-titre);
}

/* ---------------------------------------------------------------------
   7. Badge d'état de commande

   Sa COULEUR vient de l'état de commande défini en back-office, appliquée en
   style en ligne : le CSS ne peut pas la reprendre sans `!important`, et le
   faire masquerait une information — le vert d'« expédiée » et le rouge d'une
   annulation ont un sens pour l'acheteur. On ne touche donc qu'à la FORME,
   pour la ramener aux angles droits du reste de l'interface.
   --------------------------------------------------------------------- */
.label-pill,
#history .label-pill,
#order-detail .label-pill {
  border-radius: 0;
  font-family: var(--tlm-titre);
  font-weight: 400;
  letter-spacing: 0.03em;
  padding: 0.3rem 0.6rem;
}

/* ---------------------------------------------------------------------
   8. Bouton « Afficher » du mot de passe

   Thème parent : `.input-group .input-group-btn > .btn`, trois classes et un
   enfant direct.
   --------------------------------------------------------------------- */
.input-group .input-group-btn > .btn,
.input-group .input-group-btn > .btn[data-action="show-password"] {
  background: var(--tlm-blanc);
  border: var(--tlm-trait) solid var(--tlm-bleu);
  color: var(--tlm-bleu);
  border-radius: 0;
  font-family: var(--tlm-titre);
  text-transform: uppercase;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  padding: 0.4rem 0.9rem;
}

.input-group .input-group-btn > .btn:hover,
.input-group .input-group-btn > .btn:focus {
  background: var(--tlm-bleu);
  color: var(--tlm-blanc);
}

/* ---------------------------------------------------------------------
   9. Boutons du module d'avis

   `productcomments.css` est chargée avant `custom.css` : une même spécificité
   suffit à reprendre la main.
   --------------------------------------------------------------------- */
/* `.btn.btn-comment` et non `.btn-comment` seul : ma propre règle de base
   contient `button.btn`, qui vaut une classe et un élément et l'emportait
   donc sur une simple classe. C'est la charte qui se battait contre
   elle-même — le fond et la couleur passaient, la bordure non. */
.btn.btn-comment,
.btn.btn-comment-big,
.btn.btn-comment-huge,
.btn.btn-comment-inverse {
  background: var(--tlm-blanc);
  border: var(--tlm-trait) solid var(--tlm-bleu);
  color: var(--tlm-bleu);
  border-radius: 0;
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  box-shadow: none;
}

.btn.btn-comment:hover,
.btn.btn-comment-big:hover,
.btn.btn-comment-huge:hover,
.btn.btn-comment-inverse:hover {
  background: var(--tlm-bleu);
  border-color: var(--tlm-bleu);
  color: var(--tlm-blanc);
}

.btn.btn-comment .material-icons,
.btn.btn-comment-big .material-icons,
.btn.btn-comment-huge .material-icons {
  color: inherit;
}

/* ---------------------------------------------------------------------
   10. Sélecteur de quantité

   Régression de la charte, découverte en mobile. Le rembourrage généreux
   posé sur tous les `.btn` s'appliquait aussi aux deux flèches du composant
   touchspin, qui deviennent alors trop larges pour tenir à côté du champ et
   passent à la ligne. Les flèches sont un contrôle, pas un bouton d'action :
   elles reprennent leur gabarit d'origine.
   --------------------------------------------------------------------- */
.bootstrap-touchspin .input-group-btn-vertical > .btn,
.bootstrap-touchspin .btn {
  padding: 6px 10px;
  border: 1px solid var(--tlm-gris-clair);
  border-radius: 0;
  min-width: 0;
  line-height: 1;
}

.bootstrap-touchspin input.form-control,
.bootstrap-touchspin input.input-group {
  border-radius: 0;
  background: var(--tlm-blanc);
}

/* Réduire le rembourrage ne suffisait pas : le composant empile un champ et
   une colonne de flèches avec des flottants et un `display: table-cell`. Dès
   que la place manque — c'est-à-dire en mobile — les flèches passent sous le
   champ. Une rangée flex les y maintient quelle que soit la largeur, sans
   toucher au script qui pilote le composant. */
#product .product-quantity .qty,
#product .product-add-to-cart .qty {
  flex: 0 0 auto;
}

#product .bootstrap-touchspin {
  display: flex;
  align-items: stretch;
  float: none;
  width: auto;
}

#product .bootstrap-touchspin input.form-control,
#product .bootstrap-touchspin input.input-group {
  float: none;
  width: 3rem;
  height: auto;
}

#product .bootstrap-touchspin .input-group-btn-vertical {
  display: flex;
  flex-direction: column;
  float: none;
  width: auto;
  vertical-align: initial;
}

#product .bootstrap-touchspin .input-group-btn-vertical > .btn {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  height: auto;
}

/* Les flèches sont dessinées en position absolue par le thème ; une fois le
   bouton passé en flex, ce calage n'a plus lieu d'être. */
#product .bootstrap-touchspin .input-group-btn-vertical i {
  position: static;
  top: auto;
  left: auto;
}

/* ---------------------------------------------------------------------
   11. Curseur de prix des filtres

   jQuery UI, laissé gris par défaut. Rien d'autre à faire que recolorer :
   le script n'est pas touché.
   --------------------------------------------------------------------- */
#search_filters .ui-slider,
#search_filters .ui-slider-horizontal {
  background: var(--tlm-gris-clair);
  border: 0;
  border-radius: 0;
  height: 4px;
}

#search_filters .ui-slider .ui-slider-range,
#search_filters .ui-slider-horizontal .ui-slider-range {
  background: var(--tlm-bleu);
  border-radius: 0;
}

#search_filters .ui-slider .ui-slider-handle,
#search_filters .ui-slider-horizontal .ui-slider-handle {
  background: var(--tlm-bleu);
  border: 0;
  border-radius: 0;
  width: 12px;
  height: 16px;
  top: -6px;
  cursor: pointer;
}

/* ---------------------------------------------------------------------
   12 & 13. Liste d'envies, partage

   Seuls éléments ronds d'une interface entièrement à angles droits. On
   supprime l'arrondi et l'ombre, on garde la cible tactile.
   --------------------------------------------------------------------- */
.wishlist-button-add,
.product-miniature .wishlist-button-add,
.wishlist-button-product,
.product-actions .wishlist-button-add {
  border-radius: 0;
  box-shadow: none;
  border: 1px solid var(--tlm-gris-clair);
  background: var(--tlm-blanc);
}

.wishlist-button-add:hover,
.wishlist-button-product:hover {
  border-color: var(--tlm-bleu);
}

.wishlist-button-add i,
.wishlist-button-product i,
.wishlist-button-add svg,
.wishlist-button-product svg {
  color: var(--tlm-bleu);
  fill: var(--tlm-bleu);
}

.social-sharing a,
.social-sharing li a,
#product .social-sharing li {
  border-radius: 0;
  box-shadow: none;
}

.social-sharing li a:hover,
.social-sharing a:hover {
  color: var(--tlm-bleu);
}

/* ---------------------------------------------------------------------
   14. Titre du bandeau newsletter

   Ce n'est pas un titre au sens du balisage — le thème l'écrit dans un
   élément porteur de l'identifiant `block-newsletter-label` — d'où son
   apparence différente de tous les autres titres de section.
   --------------------------------------------------------------------- */
.block_newsletter #block-newsletter-label,
#footer .block_newsletter #block-newsletter-label {
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  font-size: 1.15rem;
  line-height: 1.15;
  color: var(--tlm-noir);
}

/* ---------------------------------------------------------------------
   15. Barre de service

   « Contactez-nous » est seul dans une colonne de grille dimensionnée pour
   bien plus de contenu, d'où le vide. On laisse la grille faire et on ramène
   simplement les blocs l'un vers l'autre.
   --------------------------------------------------------------------- */
@media (min-width: 992px) {
  #header .header-nav .left-nav {
    padding-right: 0;
  }

  #header .header-nav .right-nav {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.25rem;
  }

  #header .header-nav > .container > .row {
    align-items: center;
  }
}

/* ---------------------------------------------------------------------
   16. Formulaire de connexion

   Le <hr> générique est désormais discret (voir la règle `hr`), mais dans un
   formulaire aussi court même un filet clair n'apporte rien : il sépare le
   bouton de connexion de la création de compte, alors que les deux forment
   une seule proposition.
   --------------------------------------------------------------------- */
#password .page-content hr {
  display: none;
}

/* ---------------------------------------------------------------------
   17. Logo de l'en-tête du tunnel

   Le tunnel a son propre en-tête, avec son propre conteneur : la limite de
   hauteur posée sur l'en-tête courant ne l'atteignait pas.
   --------------------------------------------------------------------- */
body#checkout #header .logo,
body#checkout #_desktop_logo img,
body#checkout .header .logo,
#checkout #header img.logo {
  max-height: 64px;
  width: auto;
}

/* ---------------------------------------------------------------------
   18. Tuiles du tableau de bord du compte

   Le thème pose 1.875rem de marge basse sous chaque tuile. Le cadre ajouté
   par la charte s'arrête au contenu, mais la marge, elle, crée une bande
   entre les rangées. On passe par une grille : espacement régulier, plus de
   marge résiduelle.
   --------------------------------------------------------------------- */
.page-my-account #content .links {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
  justify-content: initial;
}

.page-my-account #content .links a {
  margin-bottom: 0;
  padding: 0;
  width: auto;
}

.page-my-account #content .links a span.link-item {
  height: 100%;
  padding: 1.5rem 1rem;
}

/* ---------------------------------------------------------------------
   19. Actions de la carte d'adresse

   Gris clair sur fond bleu pâle : ce sont les deux seules actions de la page.
   Le thème les met en `.text-muted`, une classe faite pour du texte
   secondaire, pas pour des commandes.
   --------------------------------------------------------------------- */
/* Le thème pose `.page-addresses .address .address-footer a` — trois classes.
   Il faut donc au moins trois classes de notre côté. */
.page-addresses article.address .address-footer a,
.page-addresses .addresses-footer a {
  color: var(--tlm-bleu);
  font-weight: 400;
}

.page-addresses article.address .address-footer a:hover,
.page-addresses .addresses-footer a:hover {
  color: var(--tlm-noir);
  text-decoration: underline;
}

/* Dans le tunnel, les mêmes liens portent `.text-muted`, que Bootstrap
   déclare en `!important`. C'est le seul endroit de cette feuille où on y
   répond de la même façon : sans cela, la règle est inatteignable, et il
   s'agit des deux seules actions de la carte. */
body#checkout .address-item .address-footer a,
body#checkout .address-item .address-footer a.text-muted {
  color: var(--tlm-bleu) !important;
}

body#checkout .address-item .address-footer a:hover,
body#checkout .address-item .address-footer a.text-muted:hover {
  color: var(--tlm-noir) !important;
}

/* ---------------------------------------------------------------------
   20. Libellé de la carte d'adresse

   Compte : <h4>. Tunnel : <span class="address-alias h4">. Les deux passent
   dans la police d'affichage, comme les autres titres de bloc.
   --------------------------------------------------------------------- */
article.address .address-body h4,
body#checkout .address-item .address-alias,
body#checkout .address-item header .h4 {
  font-family: var(--tlm-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  font-size: 0.95rem;
  color: var(--tlm-noir);
}

/* ---------------------------------------------------------------------
   21. En-tête d'étape du tunnel en mobile

   Le titre passe sur deux lignes et pousse « Modifier » en dessous. Le titre
   et son action tiennent sur une ligne partagée, le titre absorbant le
   rétrécissement.
   --------------------------------------------------------------------- */
@media (max-width: 767px) {
  body#checkout section.checkout-step .step-title {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    font-size: 1.05rem;
  }

  body#checkout section.checkout-step .step-title .step-edit {
    flex: 0 0 auto;
    font-size: 0.75rem;
    white-space: nowrap;
  }
}

/* ---------------------------------------------------------------------
   22. Titres produit du listing

   Les majuscules serrées de la police d'affichage mangent la place, et la
   référence — la seule chose qui distingue deux articles voisins — se fait
   tronquer. On desserre légèrement, on réduit d'un cran, et on autorise deux
   lignes au lieu d'une.
   --------------------------------------------------------------------- */
/* ---------------------------------------------------------------------
   Résidus de cyan relevés à la vérification

   Le marqueur des boutons radio du thème — visible sur la sélection
   d'adresse et le choix du transporteur. Le sélecteur du thème vaut trois
   classes et deux éléments, il faut au moins autant.
   --------------------------------------------------------------------- */
.custom-radio input[type="radio"]:checked + span,
body#checkout .custom-radio input[type="radio"]:checked + span {
  background-color: var(--tlm-bleu);
}

.custom-checkbox input[type="checkbox"]:checked + span,
.custom-checkbox input[type="checkbox"] + span .checkbox-checked {
  color: var(--tlm-bleu);
}

/* ---------------------------------------------------------------------
   Fiche produit en mobile : la rangée quantité + ajout + liste d'envies

   Remettre les flèches de quantité à leur place a élargi la rangée de 14px,
   assez pour pousser le bouton « liste d'envies » hors de l'écran. La rangée
   doit pouvoir se contracter : les flèches reprennent un gabarit plus étroit,
   le bouton d'ajout accepte de rétrécir, et la rangée peut passer à la ligne
   plutôt que de déborder.
   --------------------------------------------------------------------- */
@media (max-width: 767px) {
  #product .product-actions .product-add-to-cart,
  #product .product-quantity {
    flex-wrap: wrap;
    row-gap: 0.5rem;
  }

  #product .product-quantity .add,
  #product .product-actions .add {
    flex: 1 1 auto;
    min-width: 0;
  }

  #product .add-to-cart {
    padding-left: 0.9rem;
    padding-right: 0.9rem;
    min-width: 0;
  }

  #product .bootstrap-touchspin .input-group-btn-vertical > .btn {
    padding: 4px 7px;
  }
}

/* =====================================================================
   REFONTE — couche de correction

   Chargée après tout le reste, y compris après la première charte plus haut :
   à spécificité égale, c'est elle qui fait foi. Les sélecteurs ne sont
   alourdis que pour battre une règle plus spécifique du thème parent.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1. Discipline typographique

   Dolce Vita est une police d'affichage. Ses A et V obliques la rendent
   illisible dès qu'on descend en petites capitales — c'était visible sur
   « VOTRE COMPTE », les libellés de formulaire et les titres de colonnes du
   pied de page. Elle est désormais cantonnée aux h1/h2, jamais sous 20px.

   Tout le reste passe en Sofia Pro 600 avec un interlettrage de 0.04em, qui
   donne le même caractère affirmé sans le coût de lisibilité.
   --------------------------------------------------------------------- */
h1, .h1,
h2, .h2 {
  font-family: var(--tm-display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0;
  line-height: var(--tm-lh-tight);
  color: var(--tm-ink);
}

h1, .h1 { font-size: var(--tm-fs-h1); margin-bottom: var(--tm-3); }
h2, .h2 { font-size: var(--tm-fs-h2); margin-bottom: var(--tm-2); }

/* h3 à h6 : ce sont des intertitres, pas des titres d'affichage. */
h3, .h3,
h4, .h4,
h5, .h5,
h6, .h6 {
  font-family: var(--tm-text);
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0.01em;
  line-height: 1.3;
  color: var(--tm-ink);
}

h3, .h3 { font-size: var(--tm-fs-h3); margin-bottom: var(--tm-2); }
h4, .h4 { font-size: var(--tm-fs-h4); margin-bottom: var(--tm-1); }
h5, .h5,
h6, .h6 { font-size: var(--tm-fs-base); margin-bottom: var(--tm-1); }

body {
  font-family: var(--tm-text);
  font-weight: 300;
  font-size: var(--tm-fs-base);
  line-height: var(--tm-lh-base);
  letter-spacing: 0;
  color: var(--tm-ink);
  background: var(--tm-white);
}

/* Titre de page : lisible, pas étiré sur toute la largeur. Une ligne de 40px
   qui traverse 1440px force le lecteur à balayer au lieu de lire. */
#main .page-header {
  border: 0;
  border-bottom: 1px solid var(--tm-line);
  padding-bottom: var(--tm-2);
  margin-bottom: var(--tm-4);
}

#main .page-header h1,
#main .page-header .h1 {
  max-width: 45ch;
  margin: 0;
  text-align: left;
}

/* Les libellés, boutons, onglets et en-têtes de tableau reviennent au texte. */
.btn, .btn-primary, .btn-secondary, .btn-tertiary,
button.btn, input[type="submit"].btn,
.form-control-label, label,
.table thead th, .thead-default th,
#product .tabs .nav-tabs .nav-link,
body#checkout section.checkout-step .step-title,
.product-miniature .product-title,
.product-miniature .product-title a,
#footer .h3, #footer .links .h3, #footer .myaccount-title,
#footer .block-contact .block-contact-title,
.page-my-account #content .links a span.link-item,
#search_filters .facet-title, .block-categories .block-title, .block-title,
#header .menu > ul > li > a,
#_desktop_top_menu .top-menu a[data-depth="0"],
article.address .address-body h4,
body#checkout .address-item .address-alias,
.block_newsletter #block-newsletter-label,
.product-flags li.product-flag {
  font-family: var(--tm-text);
  font-weight: 600;
  letter-spacing: 0.04em;
}

/* ---------------------------------------------------------------------
   2. Rythme vertical

   Les filets pleine largeur qui coupaient la page sans rien séparer
   disparaissent, et le pied de page cesse de flotter au milieu du vide sur
   les pages courtes.
   --------------------------------------------------------------------- */
#wrapper {
  padding-top: var(--tm-4);
  padding-bottom: var(--tm-8);
}

#wrapper > .container > hr,
#main > hr,
#content-wrapper > hr {
  display: none;
}

#main {
  min-height: 50vh;
}

/* Un conteneur vide ne dessine plus de cadre : c'est ce qui produisait les
   grands rectangles blancs bordés sur les pages sans contenu. */
#main .page-content:empty,
#main .page-footer:empty,
.block-categories:empty,
#category-description:empty,
.category-description:empty,
#category #content-wrapper .block-category:empty {
  display: none;
}

#main .page-content,
#main .page-footer {
  border: 0;
  padding: 0;
}

/* ---------------------------------------------------------------------
   3. En-tête

   Une seule ligne, hauteur fixe, rien collé au bord. Le bloc panier était un
   aplat coloré coupé par le haut et plaqué contre le bord de la fenêtre.
   --------------------------------------------------------------------- */
#header {
  background: var(--tm-white);
  border-bottom: 1px solid var(--tm-line);
  box-shadow: none;
  position: sticky;
  top: 0;
  z-index: 100;
}

#header .header-top {
  padding: 0 var(--tm-4);
  border-bottom: 0;
}

#header .header-top > .container,
#header .header-nav > .container {
  max-width: var(--tm-largeur);
}

#header .header-nav {
  min-height: var(--tm-header-h);
  padding: 0 var(--tm-4);
  border-bottom: 1px solid var(--tm-line);
  font-size: var(--tm-fs-sm);
  text-transform: none;
  letter-spacing: 0;
}

#header .header-nav > .container > .row,
#header .header-top > .container > .row {
  align-items: center;
  min-height: var(--tm-header-h);
}

/* Logo : hauteur fixe. L'image d'origine fait 1768px de large pour un
   affichage à 90 : c'est un réglage back-office (voir la liste), mais la
   hauteur est déjà cadrée ici. */
#header .logo,
#_desktop_logo img,
#header img.logo {
  max-height: 40px;
  width: auto;
}

/* Le panier n'est plus un aplat plein bord à bord : icône + compteur. */
#header .header-nav .blockcart.cart-preview,
#header .header-nav .blockcart.cart-preview.active {
  height: auto;
  margin-left: var(--tm-2);
  padding: var(--tm-1) var(--tm-2);
  background: var(--tm-surface);
  border-radius: var(--tm-radius);
  white-space: nowrap;
}

#header .header-nav .blockcart.cart-preview a,
#header .header-nav .blockcart.cart-preview.active a,
#header .header-nav .blockcart.cart-preview.active i {
  color: var(--tm-ink);
}

#header .header-nav .blockcart.cart-preview .cart-products-count {
  display: inline-block;
  min-width: 20px;
  padding: 0 6px;
  margin-left: var(--tm-1);
  background: var(--tm-primary);
  color: var(--tm-white);
  border-radius: var(--tm-radius-pill);
  font-size: var(--tm-fs-xs);
  font-weight: 600;
  line-height: 20px;
  text-align: center;
}

/* Ordre du bloc compte : le nom d'abord, la déconnexion ensuite et en
   secondaire. Le DOM les place dans l'ordre inverse ; `order` les remet sans
   toucher au gabarit. */
#header .header-nav #_desktop_user_info {
  display: flex;
  align-items: center;
  gap: var(--tm-1);
}

#header .header-nav #_desktop_user_info .account {
  order: 1;
  font-weight: 600;
}

#header .header-nav #_desktop_user_info .logout {
  order: 2;
  color: var(--tm-ink-soft);
  font-size: var(--tm-fs-sm);
}

/* Recherche : elle pesait un quart de la largeur, plus lourde que le logo. */
#header #search_widget,
#header .search-widgets {
  max-width: 280px;
  margin-left: auto;
}

#header #search_widget form,
#header .search-widgets form {
  position: relative;
}

#header #search_widget form input[type="text"],
#header .search-widgets input[type="text"] {
  height: 40px;
  padding-left: var(--tm-2);
  border: 1px solid var(--tm-line);
  border-radius: var(--tm-radius);
  background: var(--tm-white);
  font-size: var(--tm-fs-sm);
}

/* ---------------------------------------------------------------------
   4. Menu principal

   Le module n'était accroché à aucun hook d'affichage : le menu n'existait
   pas dans la page. Corrigé côté configuration ; ici on l'habille.
   --------------------------------------------------------------------- */
#header .menu,
#_desktop_top_menu {
  display: block;
}

#header .menu > ul,
#_desktop_top_menu .top-menu {
  display: flex;
  align-items: center;
  gap: var(--tm-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

#header .menu > ul > li > a,
#_desktop_top_menu .top-menu > li > a[data-depth="0"] {
  display: inline-block;
  padding: var(--tm-3) 0;
  font-size: var(--tm-fs-sm);
  color: var(--tm-ink);
  border-bottom: 2px solid transparent;
  background: transparent;
  transition: color var(--tm-transition), border-color var(--tm-transition);
}

#header .menu > ul > li > a:hover,
#_desktop_top_menu .top-menu > li > a[data-depth="0"]:hover,
#_desktop_top_menu .top-menu > li.current > a[data-depth="0"] {
  color: var(--tm-primary);
  border-bottom-color: var(--tm-primary);
  background: transparent;
}

#_desktop_top_menu .top-menu .sub-menu {
  border: 1px solid var(--tm-line);
  border-radius: var(--tm-radius);
  box-shadow: var(--tm-shadow-lift);
  padding: var(--tm-2);
}

/* ---------------------------------------------------------------------
   5. Boutons

   Primaire en bleu encre, secondaire en contour. Le rayon de 4px et l'ombre
   discrète remplacent l'aplat à angles vifs.
   --------------------------------------------------------------------- */
.btn,
.btn-primary,
.btn-secondary,
.btn-tertiary,
button.btn,
input[type="submit"].btn {
  min-height: 48px;
  padding: 0 var(--tm-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--tm-1);
  font-size: var(--tm-fs-sm);
  text-transform: uppercase;
  border-radius: var(--tm-radius);
  border: 1px solid transparent;
  box-shadow: none;
  transition: background-color var(--tm-transition), color var(--tm-transition),
              border-color var(--tm-transition), box-shadow var(--tm-transition);
}

.btn-primary,
.btn-primary:not(:disabled):not(.disabled) {
  background: var(--tm-primary);
  border-color: var(--tm-primary);
  color: var(--tm-white);
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:not(:disabled):not(.disabled):active {
  background: var(--tm-primary-dark);
  border-color: var(--tm-primary-dark);
  color: var(--tm-white);
  box-shadow: var(--tm-shadow);
}

.btn-secondary,
.btn-tertiary {
  background: var(--tm-white);
  border-color: var(--tm-primary);
  color: var(--tm-primary);
}

.btn-secondary:hover,
.btn-secondary:focus,
.btn-tertiary:hover,
.btn-tertiary:focus {
  background: var(--tm-primary-wash);
  border-color: var(--tm-primary);
  color: var(--tm-primary-dark);
}

/* Le bouton d'affichage du mot de passe reste un contrôle, pas une action. */
.input-group .input-group-btn > .btn {
  min-height: 40px;
  padding: 0 var(--tm-2);
  font-family: var(--tm-text);
  font-weight: 600;
  background: var(--tm-surface);
  border: 1px solid var(--tm-line);
  color: var(--tm-ink-soft);
}

.input-group .input-group-btn > .btn:hover {
  background: var(--tm-line);
  color: var(--tm-ink);
}

/* Focus clavier visible partout. */
:focus-visible {
  outline: 2px solid var(--tm-primary);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------
   6. Listing catégorie
   --------------------------------------------------------------------- */
/* Palier abaissé de 260 à 220 px. À 260, la page catégorie — dont la colonne
   de filtres ne laisse que 825 px — ne tenait que deux colonnes de 400 px :
   avec le cadre en 4:5, les tuiles montaient à 643 px de haut. À 220, elle en
   tient trois de 259 px, soit exactement la densité de la page d'accueil, qui
   dispose de 1110 px et reste à quatre colonnes de 259,5 px. */
#products .products,
.products.row,
#js-product-list .products {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--tm-3);
  margin: 0;
}

#products .products > *,
.products.row > *,
#js-product-list .products > * {
  width: auto;
  max-width: none;
  flex: none;
  padding: 0;
  margin: 0;
}

/* Vignette « plein cadre ».
   ---------------------------------------------------------------------
   Le gabarit imbrique les coloris trois niveaux plus bas que l'endroit où
   ils doivent s'afficher :

       .thumbnail-container
         .thumbnail-top
           a.product-thumbnail
           .highlighted-informations      <- absolue, révélée au survol
             a.quick-view
             .variant-links               <- les pastilles sont ici
         .product-description
           .product-title
           .product-price-and-shipping

   `display: contents` fait disparaître les boîtes intermédiaires sans
   toucher au gabarit : leurs enfants deviennent des enfants flex directs de
   la carte, plaçables par `order`. `.product-description` doit en faire
   partie, sinon le prix reste enfermé et les pastilles ne peuvent pas
   s'intercaler entre la référence et lui. Le retrait latéral, porté par
   cette boîte, se reporte donc sur chacun des blocs de texte. */
.product-miniature .thumbnail-top,
.product-miniature .highlighted-informations,
.product-miniature .product-description {
  display: contents;
}

/* La carte doit occuper toute la hauteur de sa rangée, sinon les prix ne
   s'alignent pas d'une colonne à l'autre.

   `.js-product` reste un bloc. L'y passer en `display: flex` réduisait
   l'article à la largeur de son CONTENU : les colonnes de la grille faisaient
   bien 401 px, mais les cartes sortaient entre 230 et 268 px selon la
   longueur du titre, et le cadre 4:5 traduisait aussitôt cet écart en
   différence de hauteur. Un conteneur flex de niveau bloc, lui, occupe
   naturellement toute la largeur. */
.js-product.product {
  height: 100%;
}

.product-miniature {
  display: flex;
  height: 100%;
}

.product-miniature .thumbnail-container,
.product-miniature .card {
  position: relative;
  flex: 1 1 auto;
  align-self: stretch;
  display: flex;
  flex-direction: column;
  gap: var(--tm-1);
  background: transparent;
  border: 0;
  box-shadow: none;
  /* Le recadrage descend sur le cadre image : la carte, elle, doit laisser
     dépasser l'étiquette et la surcouche d'aperçu rapide. */
  overflow: visible;
  transition: none;
}

/* Survol : seule l'image réagit. Plus de `translateY` — la carte ne se
   dérobe plus sous le curseur au moment du clic. */
.product-miniature .thumbnail-container:hover .product-thumbnail img {
  transform: scale(1.03);
}

/* --- Cadre image ---------------------------------------------------- */
/* Trois classes, pas deux. Le thème parent pose
   `.product-miniature .thumbnail-container .product-thumbnail { height: calc(100% - 70px) }` :
   une hauteur explicite l'emporte sur `aspect-ratio`, qui n'a plus rien à
   calculer. Le cadre sortait à 295 × 300 au lieu de 4:5. On égale sa
   spécificité et on remet la hauteur en automatique. */
.product-miniature .thumbnail-container a.product-thumbnail {
  order: 1;
  position: relative;
  display: block;
  overflow: hidden;
  height: auto;
  /* Carré et non 4:5. Le produit est une bobine, une forme carrée la cadre
     aussi bien, et sur un listing de huit articles la page raccourcit d'un
     cinquième. La surcouche d'aperçu rapide, plus bas, suit le même ratio :
     les deux valeurs doivent rester identiques. */
  aspect-ratio: 1 / 1;
  border-radius: var(--tm-radius);
  background: var(--tm-surface);
}

/* Le gabarit enveloppe l'image dans un `<picture>`. Le sortir du flux n'est
   pas un ornement, c'est ce qui rend le cadre indéformable :

   - en ligne (par défaut), sa hauteur restait celle du fichier et l'image
     flottait en haut d'un cadre de 313 px ;
   - en bloc avec `height: 100%`, le pourcentage ne se résolvait pas contre un
     parent à hauteur automatique : l'image reprenait sa taille intrinsèque et
     poussait le cadre à 316 px de haut pour 307 de large — le ratio 4:5
     tombait à 1,028.

   En absolu, le cadre n'a plus de contenu dans le flux : sa hauteur ne vient
   donc que de `aspect-ratio`, quelle que soit la taille du fichier. */
.product-miniature .thumbnail-container a.product-thumbnail picture {
  position: absolute;
  inset: 0;
  display: block;
}

/* Surcouche d'aperçu rapide, exactement aux dimensions du cadre. Le lien
   reste celui du thème : son gestionnaire d'évènement est intact, on ne fait
   que le déplacer et le révéler au survol. */
/* Trois sélecteurs, et non un seul : le thème parent pose
   `.product-miniature .highlighted-informations .quick-view { color: #7a7a7a }`,
   soit trois classes. Une règle à deux classes laissait le libellé en gris sur
   le voile bleu. */
.product-miniature .quick-view,
.product-miniature .highlighted-informations .quick-view,
.product-miniature .thumbnail-container .quick-view {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  /* Même ratio que le cadre : la surcouche le recouvre exactement, sans
     dépendre d'une hauteur qu'elle ne connaît pas. */
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin: 0;
  border-radius: var(--tm-radius);
  /* Voile aux couleurs de la marque, plutôt que le blanc laiteux d'origine et
     le gris du thème parent. `color-mix` évite de réécrire le bleu en dur :
     la teinte reste celle de `--tm-primary`. La première déclaration sert de
     repli pour les navigateurs qui ne connaissent pas la fonction. */
  background: var(--tm-primary);
  background: color-mix(in srgb, var(--tm-primary) 82%, transparent);
  color: var(--tm-white);
  font-size: var(--tm-fs-sm);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--tm-transition);
}

.product-miniature .thumbnail-container:hover .quick-view,
.product-miniature .quick-view:focus-visible {
  opacity: 1;
  pointer-events: auto;
}

/* --- Titre ---------------------------------------------------------- */
.product-miniature .product-title,
.product-miniature .product-title a {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: var(--tm-fs-sm);
  line-height: 1.35;
  letter-spacing: 0.01em;
  overflow-wrap: anywhere;
  text-transform: none;
  color: var(--tm-ink);
}

.product-miniature .product-title {
  order: 2;
  margin: 0;
  padding: 0 var(--tm-1);
  /* Le thème parent centre le titre et le prix, mais pas la référence ni les
     coloris : la carte mélangeait deux alignements. Tout passe à gauche. */
  text-align: left;
  /* Deux lignes réservées, même quand le nom en tient une : sans cela les
     prix ne s'alignent plus d'une carte à l'autre. */
  min-height: 2.7em;
}

.product-miniature .product-title a:hover {
  color: var(--tm-primary);
}

/* --- Référence ------------------------------------------------------ */
.product-miniature .product-reference {
  order: 3;
  padding: 0 var(--tm-1);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: var(--tm-fs-xs);
  color: var(--tm-ink-soft);
}

/* --- Coloris, visibles sans survol ----------------------------------
   Le thème parent posait `.variant-links` en `position: relative` dans un
   conteneur absolu, avec un fond blanc et 2,5rem de hauteur minimale. Tout
   cela n'a plus lieu d'être une fois la bande remise dans le flux. */
.product-miniature .variant-links {
  order: 4;
  position: static;
  top: auto;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 4px;
  width: auto;
  /* Hauteur constante, et pas seulement celle d'une pastille. Le compteur
     « +153 » n'est ajouté par le thème que lorsqu'un article dépasse cinq
     coloris : sans réserve, la bande mesurait 19 px avec compteur et 15 px
     sans, et deux cartes de la même colonne ne finissaient pas à la même
     hauteur. */
  min-height: 20px;
  padding: 0 var(--tm-1);
  background: none;
  text-align: left;
}

.product-miniature .variant-links a.color {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  margin: 0;
  border: 0;
  border-radius: 50%;
  /* Liseré interne plutôt qu'une bordure : sans lui, un coloris blanc
     disparaît sur fond blanc, et une bordure décalerait le diamètre. */
  box-shadow: inset 0 0 0 1px rgba(17, 17, 17, 0.2);
}

.product-miniature .variant-links a.color:hover,
.product-miniature .variant-links a.color:focus-visible {
  box-shadow: inset 0 0 0 1px rgba(17, 17, 17, 0.2), 0 0 0 2px var(--tm-primary);
}

/* PAS de règle limitant le nombre de pastilles ici, et c'est délibéré.
   `theme.js` du thème parent s'en charge déjà, en JavaScript :

       if ($(m).find('.color').length > 5) {
         $(m).find('.color').each((i, n) => { i > 4 && ($(n).hide(), compte++) });
         $(m).find('.js-count').append(`+${compte}`);
       }

   Il masque au-delà de la cinquième en style EN LIGNE — qu'aucune règle de
   feuille ne peut défaire sans `!important` — et il calcule le compteur à
   partir de ce même 5 : « +153 » pour 158 coloris. En afficher sept
   demanderait de forcer l'affichage ET laisserait un compteur faux de deux
   unités. On garde donc les cinq du thème, cohérents avec leur compteur. */

.product-miniature .variant-links .js-count {
  flex: 0 0 auto;
  margin-left: 2px;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: var(--tm-fs-xs);
  color: var(--tm-ink-soft);
  white-space: nowrap;
}

/* --- Prix ------------------------------------------------------------ */
.product-miniature .product-price-and-shipping {
  order: 5;
  margin-top: auto;
  padding: 0 var(--tm-1) var(--tm-1);
  text-align: left;
}

.product-miniature .product-price-and-shipping,
.product-miniature .price {
  font-family: var(--tm-text);
  font-weight: 600;
  font-size: var(--tm-fs-base);
  /* Chiffres de largeur fixe : les montants s'alignent en colonne. */
  font-variant-numeric: tabular-nums;
  color: var(--tm-ink);
}

/* Mention de taxe. Les groupes clients de cette boutique sont réglés sur
   `price_display_method = 1`, donc hors taxes : l'acheteur Coupa lit du HT et
   le montant doit le dire. Vérifié avant de l'écrire, et le thème n'appose
   aucune mention de son côté. */
.product-miniature .product-price-and-shipping .price::after {
  content: " HT";
  font-size: var(--tm-fs-xs);
  font-weight: 400;
  color: var(--tm-ink-soft);
}

/* Étiquette discrète, en accent chaud, plus l'aplat bleu criard. */
.product-flags li.product-flag,
.product-miniature .product-flags li.product-flag {
  min-width: 0;
  min-height: 0;
  padding: 3px 8px;
  background: var(--tm-accent);
  color: var(--tm-white);
  border-radius: var(--tm-radius-pill);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.product-flags li.product-flag.discount,
.product-flags li.product-flag.on-sale {
  background: var(--tm-ink);
}

/* Barre d'outils du listing sur une ligne. */
#js-product-list-top,
.products-selection {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--tm-2);
  margin-bottom: var(--tm-3);
  padding: 0;
}

#js-product-list-top .total-products,
.products-selection .total-products {
  margin: 0;
  color: var(--tm-ink-soft);
  font-size: var(--tm-fs-sm);
}

.products-sort-order {
  max-width: 220px;
  margin-left: auto;
}

.products-sort-order .select-title {
  height: 40px;
  display: flex;
  align-items: center;
  border: 1px solid var(--tm-line);
  border-radius: var(--tm-radius);
  font-size: var(--tm-fs-sm);
}

/* L'image remplit le cadre, elle ne le définit plus.
   Les attributs `width="250" height="250"` du gabarit sont neutralisés par
   `width/height: 100%` et `aspect-ratio: auto`. Aucun saut de rendu : c'est
   `a.product-thumbnail` qui porte le ratio 4:5, la place est donc réservée
   avant même que le fichier arrive. */
.product-miniature .thumbnail-container img,
.product-miniature img.product-thumbnail,
.product-miniature .thumbnail-container a.product-thumbnail img {
  width: 100%;
  max-width: none;
  height: 100%;
  margin: 0;
  aspect-ratio: auto;
  object-fit: cover;
  object-position: center;
  background: var(--tm-surface);
  transition: transform var(--tm-transition);
}

/* ---------------------------------------------------------------------
   7. Fiche produit
   --------------------------------------------------------------------- */
#product .product-cover,
#product .images-container .product-cover img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: var(--tm-surface);
  border: 1px solid var(--tm-line);
  border-radius: var(--tm-radius);
}

#product h1,
#product .product-title,
.product-detail-name {
  font-size: 1.75rem;
  line-height: 1.2;
  margin-bottom: var(--tm-1);
}

#product .product-reference {
  color: var(--tm-ink-soft);
  font-size: var(--tm-fs-sm);
  margin-bottom: var(--tm-2);
}

#product .product-prices {
  margin: var(--tm-2) 0;
}

#product .product-prices .current-price,
#product .product-price,
.product-prices .price {
  display: flex;
  align-items: baseline;
  gap: var(--tm-1);
  font-family: var(--tm-text);
  font-weight: 600;
  font-size: 1.75rem;
  line-height: 1.2;
  color: var(--tm-ink);
}

#product .product-prices .tax-shipping-delivery-label {
  display: block;
  margin-top: 2px;
  font-size: var(--tm-fs-xs);
  color: var(--tm-ink-soft);
}

/* Sélecteur de coloris : une vraie liste déroulante, pas un champ inerte. */
#product .product-variants .product-variants-item select.form-control {
  max-width: 280px;
  height: 48px;
  border: 1px solid var(--tm-line);
  border-radius: var(--tm-radius);
  background: var(--tm-white);
  padding: 0 var(--tm-2);
  font-size: var(--tm-fs-base);
  appearance: auto;
}

/* Quantité et ajout au panier à la même hauteur, alignés. */
#product .product-add-to-cart .product-quantity {
  display: flex;
  align-items: stretch;
  gap: var(--tm-2);
}

#product .bootstrap-touchspin input.form-control,
#product .bootstrap-touchspin input.input-group {
  height: 48px;
  width: 3.5rem;
  text-align: center;
  border: 1px solid var(--tm-line);
  border-right: 0;
}

#product .bootstrap-touchspin .input-group-btn-vertical > .btn {
  min-height: 24px;
  height: 24px;
  padding: 0 10px;
  border: 1px solid var(--tm-line);
}

#product .add-to-cart,
#product .product-add-to-cart .add-to-cart {
  min-height: 48px;
  flex: 1 1 auto;
  font-size: var(--tm-fs-base);
}

/* Un seul appel à donner un avis : deux boutons quasi identiques sur la même
   page se neutralisent. Celui du bas, plus visible, est conservé. */
#product .product-actions .btn-comment,
#product .product-additional-info .btn-comment {
  display: none;
}

.btn.btn-comment,
.btn.btn-comment-big,
.btn.btn-comment-huge {
  background: var(--tm-white);
  border: 1px solid var(--tm-primary);
  color: var(--tm-primary);
  font-family: var(--tm-text);
  font-weight: 600;
}

/* ---------------------------------------------------------------------
   8. Pied de page

   Un seul fond, un seul rythme, et une inscription à la newsletter dont le
   champ et le bouton font la même hauteur.
   --------------------------------------------------------------------- */
#footer {
  margin-top: var(--tm-8);
  padding-top: var(--tm-8);
  padding-bottom: var(--tm-4);
  background: var(--tm-surface);
  border-top: 1px solid var(--tm-line);
  color: var(--tm-ink);
}

#footer .footer-container {
  background: transparent;
  box-shadow: none;
  padding: 0;
  margin: 0;
}

#footer .h3,
#footer .links .h3,
#footer .myaccount-title,
#footer .block-contact .block-contact-title {
  font-size: var(--tm-fs-sm);
  text-transform: uppercase;
  color: var(--tm-ink);
  margin-bottom: var(--tm-2);
}

#footer a,
#footer .links a {
  color: var(--tm-ink-soft);
  font-size: var(--tm-fs-sm);
  line-height: 2;
}

#footer a:hover,
#footer .links a:hover {
  color: var(--tm-primary);
}

.block_newsletter {
  max-width: none;
  margin-bottom: var(--tm-6);
  background: transparent;
}

.block_newsletter #block-newsletter-label {
  font-size: var(--tm-fs-h4);
  margin-bottom: var(--tm-2);
}

.block_newsletter form .input-wrapper,
.block_newsletter form input[type="email"],
.block_newsletter form input[type="text"] {
  height: 48px;
  border: 1px solid var(--tm-line);
  border-radius: var(--tm-radius);
  padding: 0 var(--tm-2);
  background: var(--tm-white);
}

.block_newsletter form .btn,
.block_newsletter form button[type="submit"] {
  min-height: 48px;
}

#footer .copyright,
#footer .bottom-footer {
  border-top: 1px solid var(--tm-line);
  margin-top: var(--tm-6);
  padding: var(--tm-3) 0 0;
  font-size: var(--tm-fs-xs);
  color: var(--tm-ink-soft);
  text-transform: none;
  letter-spacing: 0;
}

/* ---------------------------------------------------------------------
   9. Page 404
   --------------------------------------------------------------------- */
#pagenotfound #main .page-header h1,
#pagenotfound .page-not-found h1 {
  max-width: 20ch;
  font-size: var(--tm-fs-h2);
}

#pagenotfound .page-not-found {
  max-width: 640px;
  padding: var(--tm-6) 0;
}

#pagenotfound .page-not-found .search-widget {
  margin-top: var(--tm-3);
}

/* ---------------------------------------------------------------------
   10. Responsive
   --------------------------------------------------------------------- */
@media (max-width: 991px) {
  #header .header-nav,
  #header .header-top {
    padding: 0 var(--tm-2);
  }

  #header .logo,
  #_desktop_logo img,
  #header img.logo {
    max-height: 28px;
  }
}

@media (max-width: 767px) {
  :root { --tm-fs-h1: 1.875rem; --tm-fs-h2: 1.5rem; }

  #wrapper { padding-top: var(--tm-3); padding-bottom: var(--tm-6); }

  #products .products,
  .products.row,
  #js-product-list .products {
    grid-template-columns: 1fr;
    gap: var(--tm-2);
  }

  #js-product-list-top,
  .products-selection {
    flex-wrap: wrap;
    row-gap: var(--tm-1);
  }

  .products-sort-order { max-width: none; width: 100%; margin-left: 0; }

  #product .product-add-to-cart .product-quantity { flex-wrap: wrap; }

  #footer { margin-top: var(--tm-6); padding-top: var(--tm-6); }
}

@media (min-width: 1600px) {
  #wrapper .container,
  #header .container,
  #footer .container { max-width: var(--tm-largeur); }
}

/* ---------------------------------------------------------------------
   11. Page d'accueil

   La structure vient de `templates/index.tpl` (thème enfant). Ici, la mise en
   forme : accroche, cartes de catégories construites à partir de la sortie du
   module d'arbre des catégories, et bloc de présentation.
   --------------------------------------------------------------------- */
.page-home {
  display: flex;
  flex-direction: column;
  gap: var(--tm-8);
}

/* --- Accroche --- */
.tm-hero {
  margin: calc(var(--tm-4) * -1) calc(50% - 50vw) 0;
  padding: 0 calc(50vw - 50%);
  min-height: 62vh;
  display: flex;
  align-items: center;
  background: var(--tm-primary);
  background-image: var(--tm-hero-image, none);
  background-size: cover;
  background-position: center;
  color: var(--tm-white);
}

.tm-hero__inner {
  max-width: 640px;
  padding: var(--tm-8) 0;
}

.tm-hero__eyebrow {
  margin: 0 0 var(--tm-2);
  font-size: var(--tm-fs-sm);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.75);
}

.tm-hero__title {
  margin: 0 0 var(--tm-3);
  font-size: clamp(2rem, 5vw, 3.25rem);
  color: var(--tm-white);
}

.tm-hero__lead {
  margin: 0 0 var(--tm-4);
  font-size: var(--tm-fs-h4);
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.9);
}

.tm-hero__cta.btn-primary {
  background: var(--tm-white);
  border-color: var(--tm-white);
  color: var(--tm-primary);
}

.tm-hero__cta.btn-primary:hover {
  background: var(--tm-primary-wash);
  border-color: var(--tm-primary-wash);
  color: var(--tm-primary-dark);
}

/* --- Modules de l'accueil --- */
.tm-home-modules {
  display: flex;
  flex-direction: column;
  gap: var(--tm-8);
}

/* Arbre des catégories transformé en cartes. Le module produit une liste de
   liens ; la grille et le cadre viennent d'ici, aucune structure n'est
   touchée. Les visuels de catégorie, une fois renseignés en back-office,
   prendront la place de l'aplat. */
.page-home .block-categories,
.page-home #categories_block_left {
  border: 0;
  padding: 0;
  background: transparent;
}

.page-home .block-categories ul {
  list-style: none;
}

/* Le module rend deux <li> : le lien vers la catégorie racine « Accueil »,
   puis un conteneur portant la sous-liste des vraies familles. Mettre la liste
   de premier niveau en grille créait donc une colonne vide pour la racine et
   empilait les familles dans la seconde. La grille appartient à la sous-liste. */
.page-home .block-categories .category-top-menu {
  display: block;
  margin: 0;
  padding: 0;
}

.page-home .block-categories .category-top-menu > li:first-child {
  display: none;
}

.page-home .block-categories .category-sub-menu {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--tm-3);
  margin: 0;
  padding: 0;
}

.page-home .block-categories .category-sub-menu li {
  list-style: none;
  margin: 0;
}

.page-home .block-categories .category-sub-menu li a {
  display: flex;
  align-items: flex-end;
  min-height: 200px;
  padding: var(--tm-3);
  background: var(--tm-surface);
  border: 1px solid var(--tm-line);
  border-radius: var(--tm-radius);
  color: var(--tm-ink);
  font-family: var(--tm-text);
  font-weight: 600;
  font-size: var(--tm-fs-h4);
  text-transform: none;
  transition: box-shadow var(--tm-transition), transform var(--tm-transition),
              border-color var(--tm-transition);
}

.page-home .block-categories .category-sub-menu li a:hover {
  border-color: var(--tm-primary-line);
  box-shadow: var(--tm-shadow-lift);
  transform: translateY(-2px);
  color: var(--tm-primary);
}

/* Le module ajoute un bouton de dépliage inutile en présentation carte. */
.page-home .block-categories .navbar-toggler,
.page-home .block-categories .collapse-icons {
  display: none;
}

/* Produits mis en avant */
.page-home .featured-products .products-section-title,
.page-home .products-section-title {
  margin-bottom: var(--tm-3);
  font-family: var(--tm-display);
  font-size: var(--tm-fs-h2);
  text-transform: uppercase;
  text-align: left;
}

.page-home .featured-products .all-product-link {
  display: inline-block;
  margin-top: var(--tm-3);
  font-weight: 600;
}

/* --- La maison Toulemonde --- */
.tm-about {
  padding: var(--tm-8) 0;
  border-top: 1px solid var(--tm-line);
}

.tm-about__inner {
  max-width: 720px;
}

.tm-about__title {
  margin-bottom: var(--tm-3);
}

.tm-about p {
  margin-bottom: var(--tm-2);
  color: var(--tm-ink-soft);
  font-size: var(--tm-fs-base);
}

.tm-about .btn {
  margin-top: var(--tm-2);
}

@media (max-width: 767px) {
  .tm-hero { min-height: 45vh; }
  .tm-hero__inner { padding: var(--tm-6) 0; }
  .tm-hero__lead { font-size: var(--tm-fs-base); }
  .page-home { gap: var(--tm-6); }
  .tm-about { padding: var(--tm-6) 0; }
  .page-home .block-categories .category-sub-menu li a { min-height: 140px; }
}

/* ---------------------------------------------------------------------
   12. Barre d'en-tête unique

   Structure posée par `templates/_partials/header.tpl` (thème enfant) :
   logo · menu et recherche · compte, panier, langue · lien de service.
   --------------------------------------------------------------------- */
.tm-bar {
  display: flex;
  align-items: center;
  gap: var(--tm-3);
  min-height: var(--tm-header-h);
}

.tm-bar__logo {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
}

.tm-bar__logo img {
  max-height: 40px;
  width: auto;
  display: block;
}

.tm-bar__main {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: var(--tm-3);
  min-width: 0;
}

.tm-bar__aside {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--tm-2);
}

/* Le lien de service passe en second plan : c'est une information utile, pas
   une action principale. */
.tm-bar__meta {
  flex: 0 0 auto;
  font-size: var(--tm-fs-xs);
  color: var(--tm-ink-soft);
}

.tm-bar__meta a {
  color: var(--tm-ink-soft);
  text-transform: none;
  letter-spacing: 0;
}

/* La barre de service d'origine ne sert plus qu'au mobile. */
#header .header-nav {
  min-height: 0;
  padding: 0;
  border-bottom: 0;
}

#header .header-top {
  border-bottom: 0;
  padding: 0 var(--tm-4);
}

#header .header-top > .container {
  max-width: var(--tm-largeur);
}

/* La recherche vit maintenant dans la barre : elle ne pousse plus le menu. */
.tm-bar__main #search_widget,
.tm-bar__main .search-widgets {
  flex: 0 1 260px;
  margin-left: auto;
  max-width: 260px;
}

.tm-bar__main .menu,
.tm-bar__main #_desktop_top_menu {
  flex: 0 1 auto;
  min-width: 0;
}

/* Ombre discrète une fois la page défilée : le thème parent ajoute déjà une
   classe sur le body, on s'y raccroche plutôt que d'ajouter du script. */
#header.is-scrolled,
body.scrolled #header {
  box-shadow: var(--tm-shadow);
}

@media (max-width: 991px) {
  #header .header-top { padding: 0 var(--tm-2); }
  #header .header-nav .mobile { padding: var(--tm-1) 0; }
}

/* ---------------------------------------------------------------------
   13. Tenue de la barre entre 768 et 1200 px

   Le thème parent bascule sur son en-tête mobile en dessous de 768px
   seulement : entre 768 et 992, c'est donc la barre complète qui doit tenir
   dans une fenêtre étroite. Logo, menu, recherche, compte, panier et lien de
   service ne rentrent pas — d'où un débordement de 200px constaté sur toutes
   les pages. La barre se replie plutôt que de pousser la page.
   --------------------------------------------------------------------- */
@media (max-width: 1199px) {
  .tm-bar {
    flex-wrap: wrap;
    row-gap: var(--tm-1);
    padding-bottom: var(--tm-1);
  }

  /* Le lien de contact reste accessible depuis le pied de page. */
  .tm-bar__meta {
    display: none;
  }

  .tm-bar__main {
    order: 3;
    flex: 1 1 100%;
  }

  .tm-bar__main #search_widget,
  .tm-bar__main .search-widgets {
    flex: 1 1 160px;
    max-width: none;
  }

  .tm-bar__aside {
    margin-left: auto;
  }
}

/* Le plein cadre de l'accroche repose sur une largeur de fenêtre, qui inclut
   la barre de défilement : sans cette coupe, la page gagne une quinzaine de
   pixels de défilement horizontal dès qu'un ascenseur apparaît. `clip` coupe
   sans créer de conteneur de défilement, contrairement à `hidden`. */
#wrapper {
  overflow-x: clip;
}

/* ---------------------------------------------------------------------
   14. Équilibre de la barre d'en-tête

   Premier essai : menu et recherche partageaient l'espace restant, et le menu
   se laissait écraser jusqu'à n'afficher que « FIL ». Le menu est la
   navigation principale : il ne se contracte pas. C'est la recherche qui cède,
   puis les éléments de service.
   --------------------------------------------------------------------- */
.tm-bar__main .menu,
.tm-bar__main #_desktop_top_menu {
  flex: 0 0 auto;
  min-width: auto;
}

.tm-bar__main #search_widget,
.tm-bar__main .search-widgets {
  flex: 0 1 220px;
  min-width: 140px;
  margin-left: auto;
}

.tm-bar {
  gap: var(--tm-2);
}

/* Le lien de service quitte la barre bien avant que ça ne se voie : il reste
   accessible depuis le pied de page. */
/* Seuils calés sur le logo réel du serveur (204px de large une fois ramené à
   40px de haut), pas sur celui de démonstration : c'est lui qui décide de la
   place restante. */
@media (max-width: 1699px) {
  .tm-bar__meta { display: none; }
}

/* Sélecteurs de langue et de devise : utiles, mais ce ne sont pas des actions
   principales. Ils s'effacent avant le compte et le panier. */
@media (max-width: 1199px) {
  .tm-bar__aside #_desktop_language_selector,
  .tm-bar__aside #_desktop_currency_selector {
    display: none;
  }
}

/* ---------------------------------------------------------------------
   15. Grille des produits mis en avant

   Quatre par ligne en grand écran, comme demandé, puis dégressif.
   --------------------------------------------------------------------- */
.page-home .featured-products .products,
.page-home #js-product-list .products {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

@media (max-width: 1199px) {
  .page-home .featured-products .products,
  .page-home #js-product-list .products {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 767px) {
  .page-home .featured-products .products,
  .page-home #js-product-list .products {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 479px) {
  .page-home .featured-products .products,
  .page-home #js-product-list .products {
    grid-template-columns: 1fr;
  }
}

/* Le thème parent met la recherche en `float: right`. Dans une rangée flex, un
   flottant sort du flux : le bloc ne compte pas dans la largeur du parent et
   vient donc recouvrir les éléments suivants — langue, devise et compte se
   retrouvaient écrits par-dessus le menu. */
.tm-bar__main #search_widget,
.tm-bar__main .search-widgets {
  float: none;
}

.tm-bar__main {
  flex-wrap: nowrap;
}

/* Le bloc central était autorisé à se contracter (`min-width: 0`) alors que
   son contenu — menu et recherche — refuse de rétrécir. Résultat : une boîte
   de 199px pour 471px de contenu, qui débordait et recouvrait le bloc
   compte/panier. Il ne descend plus sous la largeur de son contenu, et la
   barre passe à la ligne plutôt que de laisser deux blocs se chevaucher. */
.tm-bar {
  flex-wrap: wrap;
  row-gap: var(--tm-1);
}

.tm-bar__main {
  flex: 1 1 auto;
  min-width: fit-content;
}

.tm-bar__aside {
  min-width: fit-content;
}

/* Réglage final de la rangée.

   `fit-content` réservait au bloc central sa largeur idéale — recherche à
   220px comprise — ce qui ne laissait plus la place au compte et au panier :
   la barre passait à la ligne. `min-content` lui réserve sa largeur
   incompressible ; la recherche peut alors se réduire jusqu'à 120px et tout
   tient sur une ligne. En dessous de 1200px, la barre a le droit de se replier
   (voir plus haut). */
@media (min-width: 1200px) {
  .tm-bar {
    flex-wrap: nowrap;
  }

  .tm-bar__main {
    flex: 1 1 auto;
    min-width: min-content;
  }

  .tm-bar__aside {
    flex: 0 0 auto;
    min-width: min-content;
  }
}

.tm-bar__main #_desktop_top_menu,
.tm-bar__main .menu {
  flex: 0 0 auto;
}

.tm-bar__main #search_widget,
.tm-bar__main .search-widgets {
  flex: 0 1 220px;
  min-width: 120px;
}

/* L'icône de loupe est posée en absolu par le thème parent, par-dessus le
   champ : le texte de substitution commençait dessous. */
.tm-bar__main #search_widget form input[type="text"],
.tm-bar__main .search-widgets input[type="text"] {
  padding-left: 40px;
}

.tm-bar__main #search_widget form button[type="submit"],
.tm-bar__main .search-widgets button[type="submit"] {
  left: 8px;
  right: auto;
  color: var(--tm-ink-soft);
}

/* À 1280, la rangée complète ne tient pas : le panier était coupé au bord.
   Les sélecteurs de langue et de devise cèdent avant lui — ils restent
   disponibles dans le pied de page et sur mobile. */
@media (max-width: 1599px) {
  .tm-bar__aside #_desktop_language_selector,
  .tm-bar__aside #_desktop_currency_selector {
    display: none;
  }
}

/* Le champ de recherche : la loupe est un bouton posé en absolu par le thème.
   Le retrait doit être appliqué à tous les types de champ possibles, le thème
   n'utilisant pas toujours `type="text"`. */
.tm-bar__main #search_widget input,
.tm-bar__main .search-widgets input,
.tm-bar__main #search_widget .ui-autocomplete-input {
  padding-left: 44px;
}

/* Selon les versions, le thème pose la loupe soit dans un <button>, soit dans
   un <i class="material-icons">. On cale les deux à gauche du champ et on
   réserve la place correspondante. */
.tm-bar__main #search_widget .material-icons,
.tm-bar__main #search_widget i.search,
.tm-bar__main .search-widgets .material-icons {
  left: 12px;
  right: auto;
  pointer-events: none;
}

.tm-bar__main #search_widget form input,
.tm-bar__main #search_widget input[type="text"],
.tm-bar__main .search-widgets form input {
  padding-left: 44px;
  text-indent: 0;
}

/* =====================================================================
   Page de connexion et récupération de mot de passe
   =====================================================================

   Reproduit l'écran d'authentification du portail React
   (`toulemonde-catalogue-poc`, `src/pages/auth/Login.jsx`). Valeurs prises
   dans le code source, pas estimées :

     bleu de marque      rgb(0,0,254)
     titre               #11164a, 900, -0.04em
     texte secondaire    rgba(17,22,74,0.62)
     libellés            #272b5f, 15px, 600
     champs              h 50, radius 7, bord rgba(17,22,74,0.18)
     bouton              h 64, radius 6, 16px/800
     colonne             460px
     police              Raleway

   La « bande diagonale » du panneau gauche n'est ni un clip-path ni un
   dégradé : c'est le monogramme `M-RVB-2.png` posé sur la photo, débordant de
   180px à droite et rogné par le panneau. Repris tel quel.

   Scopé sur `body#authentication` et `body#password` uniquement.
   `body#checkout` porte l'étape de connexion du tunnel et le hook de handoff
   PunchOut : il n'est jamais atteint.
   ===================================================================== */

@font-face { font-family: "Raleway"; src: url("../fonts/raleway-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Raleway"; src: url("../fonts/raleway-600.woff2") format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Raleway"; src: url("../fonts/raleway-700.woff2") format("woff2"); font-weight: 700; font-display: swap; }
@font-face { font-family: "Raleway"; src: url("../fonts/raleway-800.woff2") format("woff2"); font-weight: 800; font-display: swap; }
@font-face { font-family: "Raleway"; src: url("../fonts/raleway-900.woff2") format("woff2"); font-weight: 900; font-display: swap; }

body#authentication,
body#password {
  --lg-bleu: rgb(0, 0, 254);
  --lg-bleu-sombre: rgb(0, 0, 214);
  --lg-encre: #11164a;
  --lg-encre-62: rgba(17, 22, 74, 0.62);
  --lg-libelle: #272b5f;
  --lg-gris: #6b7080;
  --lg-gris-clair: #8a8fa3;
  --lg-bord: rgba(17, 22, 74, 0.18);
  --lg-police: "Raleway", system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Une seule largeur, partagée par le titre, les champs, le bouton et la
     ligne finale : c'est ce qui leur donne exactement le même bord gauche. */
  --login-w: 460px;

  margin: 0;
  padding: 0;
  font-family: var(--lg-police);
  background: #ffffff;
}

/* --- §1 · On dégage la chrome de la boutique --------------------------- */
body#authentication #header,
body#authentication #footer,
body#authentication .breadcrumb,
body#password #header,
body#password #footer,
body#password .breadcrumb {
  display: none;
}

body#authentication #wrapper,
body#password #wrapper {
  margin: 0;
  padding: 0;
  max-width: none;
  background: none;
  box-shadow: none;
  overflow-x: clip;
}

body#authentication #wrapper > .container,
body#authentication #content-wrapper,
body#password #wrapper > .container,
body#password #content-wrapper {
  max-width: none;
  width: 100%;
  margin: 0;
  padding: 0;
}

/* --- §1 · Colonne image, fixée -----------------------------------------
   En `position: fixed`, elle ne défile pas : plus de creux blanc sous la
   photo quand le document dépasse la hauteur de la fenêtre, et plus de bande
   blanche en haut ni en bas puisqu'elle ne dépend plus du flux.
   `100dvh` suit la barre d'adresse mobile ; `100vh` reste en repli. */
body#authentication::before,
body#password::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  width: 50vw;
  height: 100vh;
  height: 100dvh;
  z-index: 0;
  background:
    linear-gradient(90deg, rgba(0, 0, 0, 0.18), rgba(0, 0, 0, 0.02)),
    url("../img/login-atelier.jpg") center / cover no-repeat,
    #050505;
  filter: grayscale(1);
  pointer-events: none;
}

/* Le monogramme. Le portail le pose à `right: -180px` dans un panneau en
   `overflow: hidden` : il déborde et se fait rogner au bord. Ici la boîte est
   fixée au même endroit et le débordement est coupé au clip-path. */
body#authentication::after,
body#password::after {
  content: "";
  position: fixed;
  top: 0;
  /* Reproduction du cadrage du portail, transposée à un élément fixe.
     La boîte fait 62 % de la colonne (0,62 x 50vw = 31vw) et déborde de 180px
     à droite ; son bord gauche tombe donc à 19vw + 180px. Les 180px qui
     dépassent sont coupés, comme le faisait l'`overflow` du panneau. */
  left: calc(19vw + 180px);
  width: 31vw;
  height: 100vh;
  height: 100dvh;
  z-index: 1;
  background: url("../img/login-mark.png") left center / cover no-repeat;
  clip-path: inset(0 180px 0 0);
  pointer-events: none;
}

/* --- §1 · Colonne formulaire -------------------------------------------
   Centrée verticalement quelle que soit la hauteur du document : c'est le
   `justify-content: center` sur une colonne d'au moins une hauteur de
   fenêtre qui s'en charge, pas un calcul. */
body#authentication #main,
body#password #main {
  position: relative;
  z-index: 2;
  margin-left: 50vw;
  width: 50vw;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 24px;
  box-sizing: border-box;
  /* Halo centré sur le formulaire, pas sur la colonne. */
  background:
    radial-gradient(circle at 50% 42%, rgba(0, 0, 254, 0.06), transparent 38%),
    #ffffff;
}

/* --- §2 · Logo et titre ------------------------------------------------- */
body#authentication #main .page-header,
body#password #main .page-header {
  display: block;
  width: 100%;
  max-width: var(--login-w);
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
}

/* Le logo est posé en fond sur l'en-tête de page : il précède donc le titre
   sans qu'un seul élément soit ajouté au document. */
body#authentication #main .page-header::before,
body#password #main .page-header::before {
  content: "";
  display: block;
  height: 74px;
  width: min(300px, 100%);
  margin: 0 auto 40px;
  background: url("../img/login-logo.png") center / contain no-repeat;
}

/* Le titre reste le vrai <h1>. Le peindre en `content:` aurait collé au mot
   près à la cible, mais l'aurait sorti du texte traduisible et du lecteur
   d'écran : l'écart de formulation est une affaire de traduction. */
body#authentication #main .page-header h1,
body#password #main .page-header h1 {
  margin: 0 0 28px;
  max-width: var(--login-w);
  color: var(--lg-encre);
  font-family: var(--lg-police);
  font-size: 28px;
  font-weight: 900;
  letter-spacing: -0.04em;
  line-height: 1.15;
  text-transform: none;
  text-align: left;
}

body#authentication #content,
body#password #content {
  width: 100%;
  max-width: var(--login-w);
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

body#authentication .login-form,
body#password .forgotten-password,
body#password form {
  width: 100%;
  max-width: var(--login-w);
}

/* --- §2 · Espacement des groupes ---------------------------------------
   24px entre le bas d'un champ et le libellé suivant. */
body#authentication #login-form {
  display: grid;
  gap: 24px;
}

body#authentication .form-group.row,
body#password .form-group,
body#password .row.form-group {
  display: grid;
  gap: 10px;
  margin: 0 0 24px;
  width: 100%;
}

body#authentication .form-group.row > label.form-control-label,
body#authentication .form-group.row > label.col-md-3,
body#password .form-group label.form-control-label,
body#password .row.form-group label.form-control-label {
  display: block;
  width: 100%;
  max-width: none;
  flex: none;
  margin: 0 0 10px;
  padding: 0;
  /* Les gabarits PrestaShop portent des décalages de grille Bootstrap
     (`offset-md-2`) qui désalignaient les libellés de la colonne. */
  margin-left: 0;
  text-align: left;
  text-transform: none;
  letter-spacing: 0;
  font-family: var(--lg-police);
  font-size: 15px;
  font-weight: 600;
  color: var(--lg-libelle);
}

body#authentication .form-group.row > .js-input-column,
body#authentication .form-group.row > .col-md-6,
body#password .form-group > .email,
body#password .row.form-group > .js-input-column,
body#password .row.form-group > .col-md-4 {
  width: 100%;
  max-width: none;
  flex: none;
  margin: 0;
  padding: 0;
}

body#authentication .form-group.row > .form-control-comment {
  width: 100%;
  max-width: none;
  flex: none;
  padding: 0;
  font-size: 13px;
  color: var(--lg-encre-62);
}

body#authentication .form-group.row > .form-control-comment:empty {
  display: none;
}

/* --- §2 · Champs -------------------------------------------------------- */
body#authentication .form-control,
body#authentication input.form-control,
body#password .form-control,
body#password input.form-control {
  height: 50px;
  width: 100%;
  padding: 0 18px 0 50px;
  border: 1px solid var(--lg-bord);
  border-radius: 7px;
  background-color: #ffffff;
  background-repeat: no-repeat;
  background-position: 18px center;
  background-size: 18px 18px;
  box-shadow: none;
  color: var(--lg-encre);
  font-family: var(--lg-police);
  font-size: 15px;
}

body#authentication #field-email,
body#password input[type="email"] {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(17,22,74,0.48)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='20' height='16' x='2' y='4' rx='2'/%3E%3Cpath d='m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7'/%3E%3C/svg%3E");
}

body#authentication #field-password,
body#password input[type="password"] {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(17,22,74,0.48)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='18' height='11' x='3' y='11' rx='2' ry='2'/%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'/%3E%3C/svg%3E");
}

/* Le remplissage automatique du navigateur repeint le fond en bleu pâle et
   masque l'icône. On force le blanc sans toucher au texte saisi. */
body#authentication input:-webkit-autofill,
body#authentication input:-webkit-autofill:hover,
body#authentication input:-webkit-autofill:focus,
body#password input:-webkit-autofill,
body#password input:-webkit-autofill:hover,
body#password input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px #ffffff inset;
  box-shadow: 0 0 0 1000px #ffffff inset;
  -webkit-text-fill-color: var(--lg-encre);
  caret-color: var(--lg-encre);
  transition: background-color 5000s ease-in-out 0s;
}

body#authentication .form-control:focus,
body#password .form-control:focus {
  border-color: var(--lg-bleu);
  box-shadow: 0 0 0 3px rgba(0, 0, 254, 0.12);
  outline: none;
}

body#authentication .form-control::placeholder,
body#password .form-control::placeholder {
  color: rgba(17, 22, 74, 0.38);
}

/* --- §2 · Bouton « Afficher », fondu dans le champ --------------------- */
body#authentication .input-group.js-parent-focus {
  position: relative;
  display: block;
  background: transparent;
}

body#authentication .input-group .input-group-btn {
  position: absolute;
  top: 0;
  right: 0;
  height: 50px;
  display: flex;
  align-items: center;
  padding-right: 16px;
  z-index: 3;
}

body#authentication .input-group .input-group-btn > .btn {
  min-height: 0;
  height: auto;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--lg-gris-clair);
  font-family: var(--lg-police);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  box-shadow: none;
}

body#authentication .input-group .input-group-btn > .btn:hover,
body#authentication .input-group .input-group-btn > .btn:focus {
  background: transparent;
  color: var(--lg-bleu);
}

/* Place réservée au plus long des deux libellés (« Afficher » / « Masquer »)
   pour que le mot ne passe jamais sous le texte saisi. */
body#authentication #field-password {
  padding-right: 92px;
}

/* --- §2 · Mot de passe oublié ------------------------------------------- */
body#authentication #login-form .forgot-password {
  margin: 12px 0 28px;
  padding: 0;
  text-align: right;
  font-size: 15px;
}

body#authentication #login-form .forgot-password a {
  color: var(--lg-bleu);
  font-weight: 600;
}

/* --- §2 · Bouton principal ---------------------------------------------- */
body#authentication .form-footer,
body#password .form-fields .form-group {
  margin: 0;
  padding: 0;
  text-align: left;
}

body#authentication #submit-login,
body#authentication .form-footer .btn-primary,
body#password .form-control-submit,
body#password button[name="submit"] {
  display: block;
  width: 100%;
  height: 64px;
  min-height: 64px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: var(--lg-bleu);
  color: #ffffff;
  font-family: var(--lg-police);
  font-size: 16px;
  font-weight: 800;
  text-transform: none;
  letter-spacing: 0;
  /* L'ombre du portail est un halo diffus de 44px ; à cette largeur elle
     débordait sur le texte suivant. Resserrée. */
  box-shadow: 0 8px 24px rgba(0, 0, 255, 0.18);
  transition: background-color 160ms ease;
}

body#authentication #submit-login:hover,
body#authentication #submit-login:focus,
body#password .form-control-submit:hover,
body#password button[name="submit"]:hover {
  background: var(--lg-bleu-sombre);
  border: 0;
  color: #ffffff;
}

/* --- §4 · « Pas de compte ? » ------------------------------------------
   Décision : pas d'inscription libre. La phrase entière est le lien — il n'y
   a pas de texte hors du <a> — on la neutralise donc au clic tout en la
   laissant lisible, et on lui donne l'apparence d'une phrase, non d'un lien.
   Le texte lui-même relève des traductions, voir le rapport. */
body#authentication .no-account {
  margin: 24px 0 0;
  text-align: center;
  font-size: 15px;
  color: var(--lg-gris);
}

body#authentication .no-account a {
  pointer-events: none;
  cursor: default;
  text-decoration: none;
  color: var(--lg-gris);
  font-weight: 400;
}

/* --- §3 · Page de récupération ------------------------------------------
   Deux états dans le même gabarit : demande de lien, puis saisie du nouveau
   mot de passe. Les deux passent par les règles ci-dessus ; il reste les
   particularités de ce gabarit. */
body#password .forgotten-password header,
body#password .send-renew-password-link {
  margin: 0 0 24px;
  padding: 0;
  color: var(--lg-encre-62);
  font-size: 15px;
  line-height: 1.6;
  text-align: left;
}

/* Le gabarit pose 10px de marge gauche sur ce conteneur : les champs ne
   tombaient donc pas sur le même bord que le titre. */
body#password .form-fields {
  width: 100%;
  margin-left: 0;
  margin-right: 0;
}

/* Le gabarit place les deux boutons dans le même groupe que le champ : celui
   réservé au mobile est masqué par Bootstrap selon la largeur, on garde ce
   comportement et on se contente de dégager le bouton du champ. */
body#password .form-group.center-email-fields {
  display: grid;
  gap: 10px;
}

body#password .form-group.center-email-fields .form-control-submit {
  margin-top: 14px;
}

/* L'adresse rappelée au-dessus du nouveau mot de passe. */
body#password .form-fields.renew-password > .email {
  margin: 0 0 24px;
  color: var(--lg-encre-62);
  font-size: 15px;
}

body#password .container-fluid.field-password-policy {
  padding: 0;
  margin: 0;
  width: 100%;
}

/* Le module de robustesse du mot de passe s'affiche sous le champ. */
body#password .password-strength-feedback,
body#password .password-policy-suggestion {
  margin-top: 8px;
  font-size: 13px;
  color: var(--lg-encre-62);
}

/* Lien de retour vers la connexion, sous le bouton, aligné comme le reste. */
/* Le gabarit de réinitialisation garde les décalages de grille Bootstrap :
   `offset-md-2` sur les libellés, `offset-md-5` sur le bouton, et les marges
   négatives de `.row`. C'est ce qui décalait les champs de dix pixels par
   rapport au titre et poussait le bouton à droite. */
body#password .row.form-group,
body#password .row {
  margin-left: 0;
  margin-right: 0;
}

body#password .offset-md-2,
body#password .offset-md-3,
body#password .offset-md-4,
body#password .offset-md-5 {
  margin-left: 0;
}

body#password .row.form-group > div {
  width: 100%;
  max-width: none;
  flex: none;
  padding-left: 0;
  padding-right: 0;
}

/* Le lien de retour vit dans un `footer.page-footer`, sous forme de liste. */
body#password #main .page-footer {
  width: 100%;
  max-width: var(--login-w);
  margin: 20px 0 0;
  padding: 0;
  border: 0;
  text-align: left;
}

body#password #main .page-footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

body#password #main .page-footer a {
  color: var(--lg-bleu);
  font-family: var(--lg-police);
  font-size: 15px;
  font-weight: 600;
}

/* --- Messages ----------------------------------------------------------- */
body#authentication .alert,
body#authentication .alert-danger,
body#password .alert,
body#password .alert-danger,
body#password .ps-alert-error li {
  width: 100%;
  max-width: var(--login-w);
  margin: 0 0 20px;
  padding: 14px;
  border: 1px solid rgba(159, 29, 29, 0.18);
  border-radius: 8px;
  background: rgba(159, 29, 29, 0.08);
  color: #9f1d1d;
  font-family: var(--lg-police);
  font-size: 14px;
  list-style: none;
}

body#password .ps-alert-error:empty,
body#authentication #notifications:empty,
body#password #notifications:empty {
  display: none;
  margin: 0;
  padding: 0;
}

/* La confirmation d'envoi reprend le bleu de marque : le vert Bootstrap
   n'appartient à aucune charte du projet. */
body#authentication .alert-success,
body#password .alert-success,
body#password .ps-alert-success {
  border-color: rgba(0, 0, 254, 0.18);
  background: rgba(0, 0, 254, 0.07);
  color: var(--lg-encre);
  font-weight: 600;
}

body#authentication #notifications,
body#password #notifications {
  width: 100%;
  max-width: var(--login-w);
  margin: 0;
  padding: 0;
}

body#authentication .help-block,
body#authentication .js-invalid-feedback-browser,
body#password .help-block {
  margin-top: 6px;
  color: #9f1d1d;
  font-size: 13px;
}

/* --- §5 · Sous 992px : la photo s'efface -------------------------------- */
@media (max-width: 991px) {
  body#authentication::before,
  body#authentication::after,
  body#password::before,
  body#password::after {
    display: none;
  }

  body#authentication #main,
  body#password #main {
    margin-left: 0;
    width: 100%;
    padding: 32px 24px;
  }

  body#authentication #main .page-header::before,
  body#password #main .page-header::before {
    height: 60px;
    margin-bottom: 28px;
  }

  body#authentication #main .page-header h1,
  body#password #main .page-header h1 {
    font-size: 22px;
  }

  body#authentication #submit-login,
  body#password .form-control-submit {
    height: 58px;
    min-height: 58px;
    box-shadow: 0 6px 18px rgba(0, 0, 255, 0.16);
  }
}

/* --- §5 · Fenêtres basses -----------------------------------------------
   À 1024x768 le contenu dépassait de 27px et faisait apparaître un ascenseur
   pour rien. Le rembourrage vertical se resserre quand la fenêtre est courte,
   la colonne image étant fixe et donc insensible au défilement. */
@media (min-width: 992px) and (max-height: 820px) {
  body#authentication #main,
  body#password #main {
    padding-top: 24px;
    padding-bottom: 24px;
  }

  body#authentication #main .page-header::before,
  body#password #main .page-header::before {
    height: 62px;
    margin-bottom: 28px;
  }

  body#authentication #main .page-header h1,
  body#password #main .page-header h1 {
    margin-bottom: 20px;
  }
}

/* --- §2 · Ligne parasite sous le bouton ---------------------------------
   Le gabarit pose un <hr> entre le bouton et la ligne « pas de compte ». La
   règle qui le masquait a sauté lors de la réécriture de la passe 2 : le trait
   gris était donc bien revenu. */
body#authentication #main hr,
body#password #main hr,
body#authentication .form-footer,
body#password .form-footer {
  border: 0;
}

body#authentication #main hr,
body#password #main hr {
  display: none;
}

/* --- §2 · Défilement maîtrisé -------------------------------------------
   Sur grand écran, le document ne défile plus : c'est la colonne de droite,
   et elle seule, qui prend l'ascenseur si son contenu dépasse — message
   d'erreur long, formulaire de réinitialisation. L'image, en `fixed`, ne
   bouge alors jamais et aucun vide ne peut apparaître au-dessus ou en
   dessous d'elle.

   Volontairement limité au grand écran : verrouiller la hauteur du document
   en mobile rendrait le bas du formulaire inatteignable dès qu'un clavier
   virtuel réduit la fenêtre. */
/* `html` n'est pas ciblé ici : sa marge est déjà nulle par défaut dans tous
   les navigateurs, et une règle non scopée sortirait du périmètre de cette
   page. */
body#authentication,
body#password {
  margin: 0;
  padding: 0;
}

@media (min-width: 992px) {
  body#authentication,
  body#password {
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
  }

  body#authentication #main,
  body#password #main {
    height: 100vh;
    height: 100dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

/* =====================================================================
   Page d'accueil — corrections
   =====================================================================
   Les sélecteurs visent des classes stables : le hero vient du gabarit du
   thème enfant (`templates/index.tpl`, classes `tm-hero*`), les cartes de
   familles viennent du module d'arbre des catégories. Aucun `nth-child`.
   ===================================================================== */

/* ---------------------------------------------------------------------
   §1 · Bouton « Découvrir nos fils »

   Il n'avait ni fond ni bordure : rien ne le désignait comme une action. Il
   reprend le bleu électrique de la page de connexion. Scopé au hero pour ne
   pas déteindre sur les autres boutons primaires du site.
   --------------------------------------------------------------------- */
.page-home .tm-hero .tm-hero__cta,
.page-home .tm-hero a.tm-hero__cta.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 40px;
  padding: 18px 36px;
  min-height: 0;
  background: var(--tm-electrique);
  border: 0;
  border-radius: 6px;
  color: #ffffff;
  font-family: var(--tm-text);
  font-weight: 600;
  font-size: var(--tm-fs-sm);
  letter-spacing: 0.06em;
  box-shadow: none;
  transition: background-color var(--tm-transition);
}

.page-home .tm-hero .tm-hero__cta:hover,
.page-home .tm-hero a.tm-hero__cta.btn-primary:hover {
  background: var(--tm-electrique-sombre);
  border: 0;
  color: #ffffff;
}

/* Sur un aplat bleu, un contour bleu serait invisible : le repère clavier
   passe en blanc. */
.page-home .tm-hero .tm-hero__cta:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 3px;
}

/* ---------------------------------------------------------------------
   §2 · Hero : hauteur et moitié droite

   `min-height` et non `height` : une traduction plus longue doit pouvoir
   pousser le bloc au lieu d'être coupée.
   --------------------------------------------------------------------- */
.page-home .tm-hero {
  position: relative;
  min-height: 560px;
  overflow: hidden;
}

.page-home .tm-hero__inner {
  position: relative;
  z-index: 2;
  max-width: 640px;
}

/* La photo de l'atelier, déjà présente dans les assets pour la page de
   connexion. Le dégradé la fait naître du bleu encre au lieu de la coller
   en vignette : pas de bord franc, pas de marche. */
.page-home .tm-hero::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 55%;
  z-index: 1;
  background:
    linear-gradient(90deg,
      var(--tm-primary) 0%,
      rgba(27, 42, 107, 0.6) 35%,
      transparent 100%),
    url("../img/login-atelier.jpg") center / cover no-repeat;
  pointer-events: none;
}

/* ---------------------------------------------------------------------
   §3 · Recherche

   Le thème pose la loupe dans un `<i>` placé AVANT le champ, dans le flux :
   elle se retrouvait donc au-dessus du texte de substitution. Elle passe en
   absolu à gauche et le champ lui réserve la place.
   --------------------------------------------------------------------- */
.tm-bar__main #search_widget,
.tm-bar__main .search-widgets {
  position: relative;
}

.tm-bar__main #search_widget form,
.tm-bar__main .search-widgets form {
  position: relative;
  display: block;
}

.tm-bar__main #search_widget i.search,
.tm-bar__main .search-widgets i.search {
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  margin: 0;
  font-size: 20px;
  line-height: 1;
  color: #8a8fa3;
  pointer-events: none;
  z-index: 2;
}

.tm-bar__main #search_widget input[type="text"],
.tm-bar__main .search-widgets input[type="text"] {
  height: 48px;
  width: 100%;
  padding: 0 40px 0 48px;
  border: 1px solid #e3e5ec;
  border-radius: 6px;
  background: var(--tm-white);
  font-family: var(--tm-text);
  font-size: var(--tm-fs-sm);
  color: var(--tm-ink);
}

.tm-bar__main #search_widget input[type="text"]:focus,
.tm-bar__main .search-widgets input[type="text"]:focus {
  border-color: var(--tm-electrique);
  outline: none;
  box-shadow: 0 0 0 3px rgba(0, 0, 254, 0.1);
}

/* `i.clear` est laissée au thème : il la masque tant que le champ est vide. */

/* ---------------------------------------------------------------------
   §4 · Bloc compte et panier

   Depuis la fusion des deux barres, `#_desktop_user_info` ne vit plus dans
   `.header-nav` : les règles d'ordre écrites à l'époque ne l'atteignaient
   plus, d'où « Déconnexion » avant le nom du client.
   --------------------------------------------------------------------- */
.tm-bar__aside {
  gap: 28px;
}

.tm-bar__aside,
.tm-bar__aside a,
.tm-bar__aside .user-info a,
.tm-bar__aside .blockcart .header,
.tm-bar__aside .cart-products-count {
  font-family: var(--tm-text);
  font-size: 15px;
  font-weight: 500;
  color: var(--tm-ink);
  text-transform: none;
  letter-spacing: 0;
}

.tm-bar__aside .user-info {
  display: flex;
  align-items: center;
  gap: 28px;
  margin: 0;
  text-align: left;
}

/* Le nom d'abord, la déconnexion ensuite : le DOM les place dans l'ordre
   inverse, `order` les remet sans toucher au gabarit. */
.tm-bar__aside .user-info .account {
  order: 1;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}

.tm-bar__aside .user-info .logout {
  order: 2;
  color: var(--tm-ink-soft);
}

.tm-bar__aside .user-info .account span {
  text-transform: none;
  font-variant: normal;
}

.tm-bar__aside .blockcart .header {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* Icônes à la même taille et sur la ligne de texte. */
.tm-bar__aside .material-icons {
  font-size: 22px;
  line-height: 1;
  vertical-align: middle;
}

/* Le compteur ne passe au bleu électrique que lorsqu'il y a quelque chose
   dans le panier : le thème distingue les deux états par une classe. */
.tm-bar__aside .blockcart.cart-preview.inactive .cart-products-count {
  color: var(--tm-ink-soft);
}

.tm-bar__aside .blockcart.cart-preview.active .cart-products-count {
  color: var(--tm-electrique);
  font-weight: 600;
}

/* ---------------------------------------------------------------------
   Cartes de familles

   Le module d'arbre des catégories ne rend qu'une liste de liens : il n'expose
   ni image ni classe par famille. On s'accroche donc à l'URL, qui porte
   l'identifiant et le libellé de la catégorie et reste stable tant qu'on ne
   renomme pas celle-ci. Aucun `nth-child` : l'ordre du module peut changer.

   Les visuels sont des photos d'atelier du portail, recadrées pour écarter le
   monogramme qu'elles portent en haut à droite. Ce sont des images
   d'ambiance, PAS des photos de soie, de poly-coton ni de lin : à remplacer
   par une photo par famille quand le client en fournira. Voir le rapport.
   --------------------------------------------------------------------- */
.page-home .block-categories .category-sub-menu li a {
  position: relative;
  /* Le libellé est un simple nœud de texte : impossible de lui donner un
     `z-index`. On isole donc la carte et on envoie le voile derrière le texte
     mais devant l'image — sans `isolation`, un `z-index: -1` passerait aussi
     sous le fond de la carte et le voile disparaîtrait. */
  isolation: isolate;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  gap: 12px;
  padding: var(--tm-3);
  min-height: 220px;
  border: 0;
  overflow: hidden;
  font-size: 18px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tm-white);
  background-color: var(--tm-ink);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  transition: transform var(--tm-transition), box-shadow var(--tm-transition);
}

/* Le voile assombri n'est pas décoratif : sans lui, un titre blanc posé sur
   une photo claire devient illisible. Il est plus dense en bas, là où le
   titre se trouve. */
.page-home .block-categories .category-sub-menu li a::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    180deg,
    rgba(17, 17, 17, 0.15) 0%,
    rgba(17, 17, 17, 0.35) 45%,
    rgba(17, 17, 17, 0.78) 100%);
  transition: background var(--tm-transition);
}

.page-home .block-categories .category-sub-menu li a:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 24px rgba(17, 17, 17, 0.18);
  color: var(--tm-white);
}

.page-home .block-categories .category-sub-menu li a:hover::before {
  background: linear-gradient(
    180deg,
    rgba(27, 42, 107, 0.25) 0%,
    rgba(27, 42, 107, 0.45) 45%,
    rgba(17, 17, 17, 0.80) 100%);
}

/* Une image par famille, accrochée à l'URL de la catégorie. */
.page-home .block-categories .category-sub-menu li a[href*="fil-de-soie"] {
  background-image: url("../img/carte-soie.jpg");
}

.page-home .block-categories .category-sub-menu li a[href*="poly-coton"] {
  background-image: url("../img/carte-poly.jpg");
}

.page-home .block-categories .category-sub-menu li a[href*="fil-de-lin"] {
  background-image: url("../img/carte-lin.jpg");
}

/* ---------------------------------------------------------------------
   Responsive
   --------------------------------------------------------------------- */
@media (max-width: 991px) {
  .page-home .tm-hero {
    min-height: 420px;
  }

  .page-home .tm-hero::after {
    display: none;
  }

  .page-home .tm-hero__title {
    font-size: 40px;
  }

  .page-home .tm-hero .tm-hero__cta {
    margin-top: 28px;
    padding: 15px 28px;
  }
}

/* Le nom du client restait en petites capitales de 12px : une règle de la
   première charte, `#header #_desktop_user_info .account`, pèse deux
   identifiants et l'emportait sur une sélection par classes. On la reprend
   telle quelle — placée plus bas, elle gagne à spécificité égale. */
#header #_desktop_user_info .account,
#header #_desktop_user_info .account span {
  font-family: var(--tm-text);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--tm-ink);
  padding: 0;
  border: 0;
  border-radius: 0;
}

#header #_desktop_user_info .logout {
  font-family: var(--tm-text);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--tm-ink-soft);
}

#header #_desktop_user_info .account:hover,
#header #_desktop_user_info .logout:hover {
  background: transparent;
  color: var(--tm-primary);
}

/* Le champ de recherche gardait 16px de retrait et 40px de haut : une règle
   antérieure de cette feuille, `#header #search_widget form input[type=text]`,
   pèse deux identifiants. On la reprend à l'identique — placée plus bas, elle
   l'emporte à spécificité égale. */
#header #search_widget form input[type="text"],
#header .search-widgets form input[type="text"] {
  height: 48px;
  padding: 0 40px 0 48px;
  border: 1px solid #e3e5ec;
  border-radius: 6px;
  background: var(--tm-white);
  font-size: var(--tm-fs-sm);
}

#header #search_widget form input[type="text"]:focus {
  border-color: var(--tm-electrique);
  box-shadow: 0 0 0 3px rgba(0, 0, 254, 0.1);
  outline: none;
}

/* Le compteur du panier vide reprend le gris de texte secondaire, comme les
   autres éléments passifs de la barre. */
#header .tm-bar__aside .blockcart.cart-preview.inactive .cart-products-count {
  color: var(--tm-ink-soft);
}

#header .tm-bar__aside .blockcart.cart-preview.active .cart-products-count {
  color: var(--tm-electrique);
}

/* Le bloc panier était 4px plus haut que le nom et la déconnexion : son
   rembourrage vertical le décalait dans la rangée. */
#header .tm-bar__aside .blockcart.cart-preview {
  padding-top: 0;
  padding-bottom: 0;
  display: flex;
  align-items: center;
}

/* La loupe restait basse alors que sa boîte était centrée : mesuré, le glyphe
   rend 8px sous le centre de son propre bloc. C'est une métrique de la police
   Material Icons — son ink déborde la boîte de contenu vers le bas — et non un
   défaut de positionnement.

   On ne compense pas par un décalage arbitraire : la boîte devient un
   conteneur flex de 20x20 avec `line-height: 0`, ce qui fait collapser la
   ligne de texte et laisse `align-items: center` centrer le glyphe sur la
   boîte. Même traitement pour la croix d'effacement. */
/* `i.clear` n'est pas touchée : le thème la masque tant que le champ est vide
   et la révèle en JavaScript. Lui imposer un `display` la faisait apparaître
   en permanence, superposée à la loupe. */
#header #search_widget i.search,
#header .search-widgets i.search {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  line-height: 0;
  font-size: 20px;
}

#header #search_widget i.search,
#header .search-widgets i.search {
  position: absolute;
  left: 16px;
  top: 50%;
  margin-top: -10px;
  transform: none;
  color: #8a8fa3;
  pointer-events: none;
  z-index: 2;
}



/* =====================================================================
   En-tête sur une seule ligne
   =====================================================================

   Ce bloc est placé en dernier à dessein : les règles `.tm-bar` des passes
   précédentes sont réparties dans tout le fichier, et les réécrire une à une
   aurait été plus risqué que de poser ici l'état final. Aucun `!important` —
   quand une règle antérieure porte deux identifiants (`#header #search_widget`,
   spécificité 2-0-0), on égale sa spécificité plutôt que de la forcer.

   Deux variables NOUVELLES. `--tm-header-h` existe déjà, vaut 72px et pilote
   la barre mobile ainsi que la hauteur minimale de `.tm-bar` : la redéfinir
   aurait déplacé des blocs sans rapport avec ce chantier.

   Relevé, mesuré et non supposé :
   - la bascule mobile/desktop est à 768 px — point de rupture de
     `hidden-sm-down` / `hidden-md-up`, et valeur de
     `prestashop.responsive.min_width`, qui pilote le déplacement des blocs
     `_desktop_*` vers `_mobile_*` ;
   - au-dessus de 1200 px la barre tenait déjà sur une ligne ; entre 768 et
     1199 px elle se repliait en deux.
   ===================================================================== */

:root {
  --tm-bar-h: 88px;
  --tm-bar-h-compact: 60px;
}

@media (min-width: 768px) {

  /* --- La rangée ---------------------------------------------------- */

  #header {
    transition: box-shadow 180ms ease;
  }

  /* Dans ce thème enfant, `.header-nav` n'accueille QUE la barre mobile —
     voir `templates/_partials/header.tpl`, son seul contenu est le bloc
     `hidden-md-up`. Au-dessus de 768 px elle est donc vide, mais continuait
     d'occuper 50px : l'en-tête mesurait 139px pour une rangée de 88.
     Annuler hauteur, marge et filet ne suffisait pas — le conteneur et sa
     rangée gardaient leur propre hauteur. On la retire franchement. */
  #header .header-nav {
    display: none;
  }

  #header .tm-bar {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: var(--tm-3);
    row-gap: 0;
    height: var(--tm-bar-h);
    /* Une règle antérieure impose `min-height: var(--tm-header-h)` (72px) :
       elle empêchait l'état compact de descendre à 60. */
    min-height: 0;
    transition: height 180ms ease;
  }

  #header .header-top > .container > .row {
    min-height: 0;
  }

  /* Le déroulant du compte sort de la barre : aucun ancêtre ne doit le
     rogner. */
  #header .header-top,
  #header .header-top > .container,
  #header .tm-bar,
  #header .tm-bar__aside {
    overflow: visible;
  }

  #header .tm-bar__logo {
    flex: 0 0 auto;
  }

  #header .tm-bar__logo img {
    max-height: 40px;
    width: auto;
    transition: max-height 180ms ease;
  }

  /* LE point qui supprime le passage à la ligne. En `flex: 1 1 auto` avec
     `min-width: fit-content`, le bloc central réservait sa largeur idéale,
     recherche comprise : il ne restait plus la place pour le compte et le
     panier, et la barre se repliait. En `0 1 auto` il ne prend que ce dont
     il a besoin et cède le reste. */
  #header .tm-bar__main {
    flex: 0 1 auto;
    /* `min-content` et non `0` : le menu des catégories ne se contracte pas
       (consigne), et avec `min-width: 0` la boîte descendait sous sa largeur
       — 285px pour 307px de menu à 768px, d'où un débordement horizontal de
       la page entière. `min-content` réserve l'incompressible, pas l'idéal :
       c'est `fit-content` qui provoquait le repli sur deux lignes. */
    min-width: min-content;
    gap: var(--tm-3);
  }

  #header .tm-bar__aside {
    margin-left: auto;
    flex: 0 0 auto;
    min-width: min-content;
    display: flex;
    align-items: center;
    gap: var(--tm-1);
    order: 0;
  }

  /* Reliquats de la mise en page à deux lignes, encore actifs sous 1199 :
     `order: 3` renvoyait le bloc central APRÈS le compte et le panier — à
     768px la barre affichait logo, compte, panier, puis le menu — et
     `padding-bottom` décalait le centrage vertical. */
  #header .tm-bar__main {
    order: 0;
  }

  #header .tm-bar {
    padding-bottom: 0;
  }

  /* `displayNav1` ne rend rien sur cette boutique : le bloc mesurait 0 × 0
     tout en consommant une gouttière. */
  #header .tm-bar__meta {
    display: none;
  }

  /* Filet de séparation entre les outils et le compte, comme sur la
     maquette. Pseudo-élément : aucun markup ajouté. */
  #header .tm-bar__aside::before {
    content: "";
    flex: 0 0 auto;
    width: 1px;
    height: 24px;
    margin-right: var(--tm-1);
    background: var(--tm-line);
  }

  /* --- Menu des catégories ------------------------------------------ */

  #header .tm-bar__main #_desktop_top_menu,
  #header .tm-bar__main .menu {
    flex: 0 0 auto;
  }

  /* La classe `current` est posée par `ps_mainmenu` sur le `<li>` de la
     rubrique courante — relevée dans le DOM rendu. On s'appuie dessus, on
     n'en invente pas une autre et on ne calcule rien côté PHP. */
  #header .tm-bar__main #_desktop_top_menu li.category.current > a {
    color: var(--tm-primary);
    font-weight: 600;
    box-shadow: inset 0 -2px 0 0 var(--tm-primary);
  }

  /* --- Recherche -----------------------------------------------------
     `#header #search_widget` (2-0-0) fixait `max-width: 280px` et
     `margin-left: auto`. On égale la spécificité, sinon la pilule garde la
     largeur de l'ancienne charte. */

  #header .tm-bar__main #search_widget {
    position: relative;
    /* `0 1` et non `0 0` : c'est le seul élément de la rangée autorisé à se
       contracter. En largeur fixe, il poussait la barre au-delà du conteneur
       — 21px de débordement mesurés à 1024px, et une barre de défilement
       horizontale sur toute la page. */
    flex: 0 1 236px;
    min-width: 120px;
    max-width: none;
    margin-left: 0;
    transition: flex-basis 180ms ease;
  }

  #header .tm-bar__main #search_widget form {
    position: relative;
    width: 100%;
  }

  #header .tm-bar__main #search_widget form input[type="text"] {
    width: 100%;
    height: 38px;
    padding: 0 var(--tm-2) 0 40px;
    border: 1px solid var(--tm-line);
    border-radius: var(--tm-radius-pill);
    background: var(--tm-white);
    font-size: var(--tm-fs-sm);
  }

  #header .tm-bar__main #search_widget form input[type="text"]:focus {
    border-color: var(--tm-primary);
    outline: none;
    box-shadow: 0 0 0 3px rgba(27, 42, 107, 0.1);
  }

  /* Le bouton de repli ne sert que dans la plage étroite, plus bas. */
  #header .tm-bar__main #search_widget .tm-search__toggle {
    display: none;
  }

  /* --- Compte : déclencheur et déroulant ------------------------------ */

  #header .tm-bar__aside .tm-acct {
    position: relative;
    flex: 0 1 auto;
    min-width: 0;
  }

  #header .tm-bar__aside .tm-acct__btn {
    display: inline-flex;
    align-items: center;
    gap: var(--tm-1);
    max-width: 100%;
    height: 38px;
    padding: 0 10px;
    border: 0;
    border-radius: var(--tm-radius-pill);
    background: none;
    font: inherit;
    font-size: var(--tm-fs-sm);
    color: var(--tm-ink);
    cursor: pointer;
    transition: background-color var(--tm-transition);
  }

  #header .tm-bar__aside .tm-acct__btn:hover {
    background: var(--tm-surface);
  }

  #header .tm-bar__aside .tm-acct__btn:focus-visible {
    outline: 2px solid var(--tm-primary);
    outline-offset: 2px;
  }

  /* Le nom du client peut être long — « Acheteur Atelier Durand » sur cette
     boutique. Il se tronque plutôt que de pousser le panier hors de la
     barre. */
  #header .tm-bar__aside .tm-acct__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 200px;
  }

  #header .tm-bar__aside .tm-acct__avatar {
    font-size: 20px;
    color: var(--tm-ink-soft);
  }

  #header .tm-bar__aside .tm-acct__chev {
    font-size: 18px;
    color: var(--tm-ink-soft);
    transition: transform var(--tm-transition);
  }

  #header .tm-bar__aside .tm-acct__btn[aria-expanded="true"] .tm-acct__chev {
    transform: rotate(180deg);
  }

  #header .tm-bar__aside .tm-acct__menu {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    z-index: 30;
    width: 232px;
    margin: 0;
    padding: 6px;
    list-style: none;
    background: var(--tm-white);
    border: 1px solid var(--tm-line);
    border-radius: var(--tm-radius);
    box-shadow: var(--tm-shadow-lift);
  }

  #header .tm-bar__aside .tm-acct__menu[hidden] {
    display: none;
  }

  #header .tm-bar__aside .tm-acct__menu li {
    list-style: none;
  }

  #header .tm-bar__aside .tm-acct__menu a {
    display: block;
    padding: 8px 12px;
    border-radius: var(--tm-radius);
    color: var(--tm-ink);
    font-size: var(--tm-fs-sm);
    text-transform: none;
    letter-spacing: 0;
    text-decoration: none;
    white-space: nowrap;
  }

  #header .tm-bar__aside .tm-acct__menu a:hover,
  #header .tm-bar__aside .tm-acct__menu a:focus {
    background: var(--tm-surface);
    color: var(--tm-primary);
  }

  #header .tm-bar__aside .tm-acct__sep {
    height: 1px;
    margin: 6px 0;
    background: var(--tm-line);
  }

  #header .tm-bar__aside .tm-acct__menu a.tm-acct__out {
    color: var(--tm-danger);
  }

  /* --- Panier : mise en forme seule, aucun markup touché -------------- */

  #header .tm-bar__aside #_desktop_cart .blockcart .header {
    display: inline-flex;
    align-items: center;
    gap: var(--tm-1);
    height: 38px;
    padding: 0 var(--tm-2);
    border: 1px solid var(--tm-line);
    border-radius: var(--tm-radius-pill);
  }

  #header .tm-bar__aside #_desktop_cart .blockcart .header:hover {
    border-color: var(--tm-primary);
  }

  /* --- État compact au défilement ------------------------------------ */

  #header.is-stuck .tm-bar {
    height: var(--tm-bar-h-compact);
  }

  #header.is-stuck .tm-bar__logo img {
    max-height: 26px;
  }

  #header.is-stuck .tm-bar__main #search_widget {
    flex-basis: 190px;
  }

  /* Le libellé « Panier » disparaît, le compteur reste. On vise le span qui
     n'est pas le compteur : selon que le panier est vide ou non, le gabarit
     du module l'enveloppe ou non dans un `<a>`. */
  #header.is-stuck .tm-bar__aside #_desktop_cart .blockcart .header span:not(.cart-products-count) {
    display: none;
  }

  #header.is-stuck {
    box-shadow: 0 2px 12px rgba(20, 20, 40, 0.08);
  }
}

/* --- Zone intermédiaire : la barre ne doit jamais déborder ------------
   Dégradation, du plus large au plus étroit :
   1200+     recherche à 236 px
   992-1199  recherche à 160 px
   768-991   recherche repliée en icône, le champ s'ouvre en surimpression.
   Le menu des catégories, lui, ne cède jamais. */

@media (min-width: 1200px) {
  /* Largeur nominale de la maquette, sans contraction : à partir de 1200 la
     rangée a la place, et la pilule tombait à 202px si on la laissait céder. */
  #header .tm-bar__main #search_widget {
    flex: 0 0 236px;
  }
}

@media (min-width: 768px) and (max-width: 1199px) {
  /* Gouttières resserrées : à 1024px, garder 24px partout coûtait les
     quelques pixels qui manquaient à la recherche pour tenir à 160. */
  #header .tm-bar {
    gap: var(--tm-2);
  }

  #header .tm-bar__main {
    gap: var(--tm-2);
  }

  /* La pilule tombait à 116 px dans cette plage, alors que « Référence,
     coloris… » en réclame 174 : le texte de substitution était coupé. Les
     pixels sont repris là où ils coûtent le moins — le libellé « Panier »,
     dont l'icône et le compteur restent, et le nom du client, déjà tronqué.
     Le rembourrage intérieur du champ est aussi resserré : 34 + 10 au lieu de
     40 + 16, soit douze pixels de moins à trouver. */
  #header .tm-bar__main #search_widget {
    flex-basis: 176px;
    min-width: 150px;
  }

  #header .tm-bar__main #search_widget form input[type="text"] {
    padding-left: 34px;
    padding-right: 10px;
  }

  #header.is-stuck .tm-bar__main #search_widget {
    flex-basis: 160px;
  }

  #header .tm-bar__aside .tm-acct__name {
    max-width: 110px;
  }

  #header .tm-bar__aside #_desktop_cart .blockcart .header span:not(.cart-products-count) {
    display: none;
  }
}

@media (min-width: 768px) and (max-width: 991px) {
  #header .tm-bar {
    gap: var(--tm-2);
  }

  #header .tm-bar__main #search_widget,
  #header.is-stuck .tm-bar__main #search_widget {
    flex: 0 0 auto;
    min-width: 0;
  }

  /* À 768px, tout ne tient pas : logo, menu, recherche et bloc compte
     totalisent 802px pour 720px disponibles. Le menu ne cède pas (consigne),
     la recherche est déjà repliée en icône : c'est le nom du client qui
     s'efface. Il reste dans le document et lisible par un lecteur d'écran —
     c'est lui qui donne son nom accessible au bouton. */
  #header .tm-bar__aside .tm-acct__name {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    white-space: nowrap;
    clip-path: inset(50%);
    border: 0;
  }

  #header .tm-bar__main #search_widget .tm-search__toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    padding: 0;
    border: 1px solid var(--tm-line);
    border-radius: var(--tm-radius-pill);
    background: var(--tm-white);
    color: var(--tm-ink-soft);
    cursor: pointer;
  }

  #header .tm-bar__main #search_widget .tm-search__toggle:hover {
    border-color: var(--tm-primary);
  }

  #header .tm-bar__main #search_widget form {
    display: none;
  }

  /* Ouvert : le champ passe en surimpression sous la barre. La rangée n'est
     donc jamais élargie. */
  #header.tm-search-open .tm-bar__main #search_widget form {
    display: block;
    position: absolute;
    right: 0;
    top: calc(100% + 8px);
    z-index: 30;
    width: min(420px, calc(100vw - 48px));
  }

  #header.tm-search-open .tm-bar__main #search_widget form input[type="text"] {
    box-shadow: var(--tm-shadow-lift);
  }

  #header .tm-bar__aside .tm-acct__name {
    max-width: 96px;
  }

  #header .tm-bar__aside #_desktop_cart .blockcart .header span:not(.cart-products-count) {
    display: none;
  }
}

/* Le mode compact ne s'applique pas sous 768 px : l'en-tête mobile garde sa
   hauteur et son comportement actuels. La classe `is-stuck` est bien posée
   par le script, mais aucune règle ne la reprend en dessous de ce seuil. */

/* =====================================================================
   Sélection native dans l'en-tête

   Au clic sur le logo, un micro-déplacement de la souris suffit à déclencher
   la sélection de l'image : Chrome la surligne en bleu et la garde jusqu'au
   clic suivant. Ce n'est pas un anneau de focus — l'ancre du logo est en
   `outline: none` même en `:focus`.

   On neutralise donc la sélection et le glisser-déposer sur le logo et sur
   les éléments de navigation, qui ne contiennent aucun texte destiné à être
   copié.

   DEUX PRÉCAUTIONS.

   1. Les blocs sont visés NOMMÉMENT, jamais `#header` en bloc : l'en-tête
      contient le champ de recherche (`input[name="s"]`) et les sélecteurs de
      langue et de devise. Y figer la sélection empêcherait de corriger une
      référence déjà saisie.

   2. Les identifiants `_mobile_*` sont traités au même titre que les
      `_desktop_*`. Ils sont vides au chargement en desktop, mais sous 768 px
      `theme.js` y déplace les enfants des blocs `_desktop_*` : le logo, le
      menu, le compte et le panier y vivent alors réellement — vérifié dans le
      DOM rendu à 375 px.

   Aucun `outline: none` ajouté : sans effet sur ce défaut, et l'anneau de
   focus au clavier doit rester.
   ===================================================================== */

#_desktop_logo a,
#_desktop_logo img,
#_mobile_logo a,
#_mobile_logo img {
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
}

#_desktop_top_menu,
#_mobile_top_menu,
#_desktop_user_info,
#_mobile_user_info,
#_desktop_cart,
#_mobile_cart,
#menu-icon {
  -webkit-user-select: none;
  user-select: none;
}

/* Les icônes et pictogrammes de ces blocs sont des images ou des ligatures :
   on coupe aussi le glisser, qui produit le même surlignage. */
#_desktop_top_menu img,
#_mobile_top_menu img,
#_desktop_user_info img,
#_mobile_user_info img,
#_desktop_cart img,
#_mobile_cart img {
  -webkit-user-drag: none;
}

/* =====================================================================
   Anneau de focus des liens de l'en-tête

   Le cerclage bleu au clic sur le logo EST un anneau de focus, contrairement
   à ce qui avait été supposé. Le thème parent — reboot de Bootstrap 4 —
   impose sur toutes les ancres :

       a:focus { outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; }

   Relevé sur l'ancre du logo au moment du clic : `outline` calculé
   `auto 5px rgb(0, 95, 204)`, décalage `-2px`. L'anneau est donc dessiné à
   l'intérieur de l'élément, ce qui donne le rectangle bleu autour du logo. Il
   persiste parce que l'ancre garde le focus après le relâchement, jusqu'au
   clic suivant.

   La correction n'est PAS un `outline: none` sur `:focus`, qui supprimerait
   aussi le repère au clavier. On distingue les deux situations :

   - `:focus:not(:focus-visible)` — focus pris à la souris : pas d'anneau ;
   - `:focus-visible` — focus pris au clavier : un anneau, aux couleurs de la
     charte plutôt que le bleu du navigateur.

   Les navigateurs sans `:focus-visible` ignorent les deux règles et
   conservent le comportement actuel : aucune régression.

   PORTÉE : tout le site. Trois sélecteurs du thème parent forcent l'anneau du
   navigateur, relevés dans `theme.css` :

       a:focus      { outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px }
       button:focus { outline: 1px dotted; outline: 5px auto -webkit-focus-ring-color }
       .btn:focus   { outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px }

   Les champs de saisie ne sont PAS concernés : `.form-control:focus` pose
   `outline: 0` et un changement de bordure, c'est un état de focus dessiné,
   pas un anneau parasite. Le neutraliser priverait les formulaires de tout
   repère. Aucun `input`, `select` ni `textarea` dans les sélecteurs ci-dessous.

   `.btn:focus` est repris explicitement : la variante `.btn.active:focus` du
   thème parent pèse trois classes, qu'un simple `a:focus:not(...)` ne
   dépasserait pas.
   ===================================================================== */

a:focus:not(:focus-visible),
button:focus:not(:focus-visible),
.btn:focus:not(:focus-visible) {
  outline: none;
}

a:focus-visible,
button:focus-visible,
.btn:focus-visible {
  outline: 2px solid var(--tm-primary);
  outline-offset: 2px;
}

/* =====================================================================
   Page catégorie — passe du 10 septembre 2026
   =====================================================================

   Relevé sur `/2-accueil` à 1084 px, colonne de filtres affichée. Deux
   constats de départ se sont révélés faux à la mesure, et le corrigé en tient
   compte :

   - AUCUNE catégorie de cette boutique n'a de description, pas seulement la
     racine : `/10-fil-de-soie` non plus. La carte de catégorie ne se remplira
     donc qu'une fois les descriptions saisies en back-office ;
   - le libellé de facette est bien tronqué, mais pas là où on le croit : ce
     n'est pas le `<label>` — dont le `text-overflow` vaut `clip` — mais le
     `<a class="search-link">` qu'il contient, en `nowrap` + `ellipsis`, 138 px
     de rendu pour 168 de texte. La règle plus bas vise donc ce lien.

   Le passage du cadre produit en 1:1 n'est pas ici mais dans la section du
   listing, sur la règle d'origine : y ajouter une seconde déclaration aurait
   laissé deux valeurs contradictoires dans le fichier.
   ===================================================================== */

/* --- 1. Carte de catégorie -------------------------------------------
   Le thème parent réserve `min-height: 13.75rem` pour une description. Sans
   description, cela laissait un rectangle blanc de 220 px sous le titre.

   La règle `:empty` posée plus haut ne pouvait pas s'en charger :
   `.block-category-inner` contient un nœud de texte — des espaces — donc la
   carte n'est jamais vide au sens du sélecteur. On agit sur la hauteur
   réservée, pas sur la présence du bloc : le titre reste affiché, et la carte
   reprendra sa hauteur d'elle-même dès qu'une description sera saisie. */
.block-category,
#category #content-wrapper .block-category {
  min-height: 0;
}

/* --- 2. Sous-catégories ----------------------------------------------
   Aucune catégorie n'a de visuel : `.subcategory-image` se réduisait à un
   cadre bordé de 28 px de haut, soit trois rectangles vides.

   On vise l'ABSENCE d'image et non le conteneur. Le jour où un visuel est
   saisi en back-office, `:has(img)` devient vrai et la règle cesse d'agir
   sans qu'il faille y revenir. */
#subcategories ul.subcategories-list .subcategory-image:not(:has(img)) {
  display: none;
}

/* Grille fluide plutôt que des blocs de 200 px : trois tuiles à 1084 px, une
   seule sur téléphone, sans largeur figée.

   Les sélecteurs partent de `#subcategories`, et pas de la seule classe : le
   thème parent pose `#subcategories ul li { width: calc(100%/4 - 20px);
   min-width: 200px; margin: 10px }`, soit un identifiant. Une règle à une
   classe perdait, et les tuiles restaient à 200 px. */
#subcategories ul.subcategories-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--tm-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

#subcategories ul.subcategories-list li {
  width: auto;
  min-width: 0;
  max-width: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--tm-line);
  border-radius: var(--tm-radius);
  background: var(--tm-surface);
  text-align: center;
  transition: border-color var(--tm-transition), background-color var(--tm-transition);
}

#subcategories ul.subcategories-list li:hover {
  border-color: var(--tm-primary);
  background: var(--tm-white);
}

#subcategories ul.subcategories-list li h5 {
  margin: 0;
}

/* Le lien porte le rembourrage : toute la tuile devient cliquable, pas
   seulement les quelques pixels du libellé. */
#subcategories ul.subcategories-list li .subcategory-name {
  display: block;
  padding: var(--tm-3) var(--tm-2);
  color: var(--tm-ink);
  font-size: var(--tm-fs-sm);
  text-transform: none;
  text-decoration: none;
}

#subcategories ul.subcategories-list li:hover .subcategory-name {
  color: var(--tm-primary);
}

/* --- 3. Visuel de remplacement ---------------------------------------
   `fr-default-home_default.jpg` fait 250 × 250 et porte le texte « Aucune
   image disponible ». Recadré en `cover` dans un cadre plus grand, il était
   agrandi et rogné : le mot le plus visible de la page devenait « Aucune ».

   On vise le fichier par son nom, donc uniquement le remplacement : les
   vraies photos, quand elles arriveront, gardent `cover` et le cadre plein. */
.product-miniature .thumbnail-container a.product-thumbnail img[src*="default-home_default"] {
  object-fit: contain;
  padding: var(--tm-6);
  background: var(--tm-surface);
  opacity: 0.3;
}

/* --- 5. Navigation dupliquée ------------------------------------------
   Sur une page catégorie, l'arbre `.block-categories` de la colonne de gauche
   et la facette « Catégories » du bloc de filtres disent la même chose.

   La facette porte `data-type="category"` — attribut posé par le module de
   filtres, relevé dans le DOM : l'accroche est fiable, il n'y a pas besoin de
   passer par une désactivation en back-office.

   Le masquage est borné à `body#category`. Sur la page de recherche, la
   facette est la seule entrée par catégorie : elle doit y rester. */
body#category #search_filters .facet[data-type="category"] {
  display: none;
}

/* --- 6. Pied de page --------------------------------------------------
   La mention « Logiciel e-commerce par PrestaShop™ » n'a pas sa place sur un
   catalogue B2B destiné à un donneur d'ordre. Elle vit dans un `<p>` sans
   classe distinctive : on remonte depuis le lien, seul élément identifiable. */
#footer p:has(> a[href*="prestashop"]) {
  display: none;
}

/* Liens transactionnels du bloc compte en pied de page. Ils restent
   accessibles depuis le menu compte de l'en-tête, et n'ont rien à faire au
   même niveau que les mentions légales.

   Deux réécritures d'URL sont visées pour « Avoirs » : la boutique a deux
   langues actives (fr et en), et l'adresse change avec la langue. La
   déconnexion, elle, passe par `?mylogout` quelle que soit la langue. */
#block_myaccount_infos li:has(> a[href*="mylogout"]),
#block_myaccount_infos li:has(> a[href*="avoirs"]),
#block_myaccount_infos li:has(> a[href*="credit-slip"]) {
  display: none;
}

/* --- 6 bis. Libellés de facette --------------------------------------
   « Nouveau produit (8) » s'affichait « NOUVEAU PROD… ». La coupe vient du
   lien intérieur, pas du label : `#search_filters` pose sur
   `a.search-link` un `white-space: nowrap` avec `overflow: hidden` et
   `text-overflow: ellipsis`. Mesuré à 1084 px : 138 px de largeur de rendu
   pour 168 px de texte.

   Le libellé passe sur deux lignes plutôt que d'être amputé — dans une
   colonne de filtres, la hauteur ne coûte rien, l'ambiguïté si. */
#search_filters .facet-label a.search-link,
#search_filters a.search-link {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}
