/* === /assets/css/tokens.css === */
/* ============================================================
   LE CUBE À COMICS — DESIGN SYSTEM v1 · tokens (version de prod, child theme)
   Direction : « La Loupe du Collectionneur » (gate 1 du 07/07/2026)
   - Musée-maison de ventes ouvert la nuit : les couvertures sont des
     pièces exposées sous spot, l'expertise (grading, cotes, rareté)
     fait foi, l'achat est l'adjudication.
   - LOI DES 2 COULEURS : BLEU = je choisis · OR = j'achète.
     Aucun composant ne la contourne (le focus est bleu : c'est une
     sélection ; le hover du CTA approfondit l'or, il ne bascule
     jamais côté bleu — correctif gate 1).

   ARCHITECTURE (méthode de build, étape 4) :
   - COUCHE 1 : les valeurs (hex, familles) vivent dans theme.json —
     UNE SEULE définition. Ici, un pont mappe les presets WordPress
     (--wp--preset--*) sur les alias maison (--brand-*, --font-*) :
     le CSS du registre (design-system/components/) se transporte
     sans réécriture.
   - COUCHES 2-3 : signature, rôles, utilitaires, typo, formes,
     mouvement, contexte nuit — identiques au design system éprouvé
     (design-system/tokens.css de l'atelier, référence de conception).
   - Parent-agnostique : aucune variable ni hook Kadence
     (pas de --global-palette*, pas de classes Kadence).
   - Polices auto-hébergées : @font-face générés par WordPress depuis
     theme.json (fontFace), woff2 servis par le child.
   ============================================================ */

/* ============================================================
   REPLIS À MÉTRIQUES ALIGNÉES — correctif F42 (recette É5, S5 du 07/08/2026)

   LE DÉFAUT, mesuré : CLS du panier à 0,101 sur staging pour un seuil à
   0,100, dont 99,6 % attribués par Lighthouse à « Web font loaded ». Les
   polices sont préchargées et auto-hébergées, mais `font-display: swap`
   peint d'abord le texte avec la police système, puis rebascule : les deux
   n'occupent pas la même place, et tout ce qui suit se déplace. Reproduit
   au banc local (preuves/recette-s5-cls.mjs, polices retardées) : le
   paragraphe `.pan-livr-txt` du bordereau change de hauteur et pousse le
   bouton Commander, le code promo et le pied de page de ~21 px.

   LE CORRECTIF : on ne change ni la police, ni `swap`, ni le préchargement.
   On donne au REPLI les métriques de la police web, pour qu'il occupe
   exactement la même place — la bascule ne déplace alors plus rien.

   LES CHIFFRES viennent d'une mesure, pas d'une table :
   `node preuves/recette-s5-metriques-polices.mjs` charge chaque woff2 du
   child dans un vrai navigateur et relève au Canvas (TextMetrics) la chasse
   et les boîtes ascendante/descendante, sur un échantillon de texte
   réellement rendu par le site. Rejouable ; toute mise à jour de police
   impose de le rejouer et de reporter les valeurs ici.

   PORTÉE HONNÊTE : les surcharges sont exactes pour la police locale nommée
   par `src: local(...)`. Là où le système ne la fournit pas (Android n'a pas
   Arial et l'alias résout vers Roboto), le repli reste approché : le
   reflux est réduit, pas annulé.
   ============================================================ */

@font-face {
  font-family: "Bebas Neue repli";
  src: local("Arial");
  size-adjust: 71.29%;
  ascent-override: 133.26%;
  descent-override: 49.09%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Inter repli";
  src: local("Arial");
  size-adjust: 105.15%;
  ascent-override: 92.25%;
  descent-override: 22.83%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "IBM Plex Mono repli";
  src: local("Courier New");
  size-adjust: 99.98%;
  ascent-override: 103.02%;
  descent-override: 28%;
  line-gap-override: 0%;
}

:root {

  /* ------------------------------------------------------------
     COUCHE 1 — PONT presets theme.json → alias maison
     (source des valeurs : theme.json, ne rien redéfinir ici)
     ------------------------------------------------------------ */

  /* La nuit du musée — l'écrin des temps forts ; jamais de noir pur */
  --brand-midnight:   var(--wp--preset--color--brand-midnight);
  --brand-night:      var(--wp--preset--color--brand-night);
  --brand-vault:      var(--wp--preset--color--brand-vault);

  /* La lueur — les textes sur nuit */
  --brand-glow:       var(--wp--preset--color--brand-glow);
  --brand-dusk:       var(--wp--preset--color--brand-dusk);

  /* Le bleu Cube — la sélection, l'interaction (couleur du logo) */
  --brand-cube:       var(--wp--preset--color--brand-cube);
  --brand-cube-light: var(--wp--preset--color--brand-cube-light);
  --brand-cube-deep:  var(--wp--preset--color--brand-cube-deep);

  /* L'or champagne — l'achat, la cote */
  --brand-gold:       var(--wp--preset--color--brand-gold);
  --brand-gold-deep:  var(--wp--preset--color--brand-gold-deep);
  --brand-gold-ink:   var(--wp--preset--color--brand-gold-ink);
  --brand-gold-soft:  var(--wp--preset--color--brand-gold-soft);

  /* Le papier — le corps de page clair, là où vit le catalogue */
  --brand-paper:      var(--wp--preset--color--brand-paper);
  --brand-page:       var(--wp--preset--color--brand-page);
  --brand-ink:        var(--wp--preset--color--brand-ink);
  --brand-ink-soft:   var(--wp--preset--color--brand-ink-soft);
  --brand-line:       var(--wp--preset--color--brand-line);

  /* L'alerte — un seul rouge */
  --brand-alert:       var(--wp--preset--color--brand-alert);
  --brand-alert-light: var(--wp--preset--color--brand-alert-light);

  /* Extensions passe d'absorption (gate 08/07/2026) */
  --brand-gold-line:  var(--wp--preset--color--brand-gold-line);
  --brand-grade-mid:  var(--wp--preset--color--brand-grade-mid);
  --brand-grade-high: var(--wp--preset--color--brand-grade-high);

  /* Typo : familles servies par theme.json */
  --font-display: var(--wp--preset--font-family--display);
  --font-body:    var(--wp--preset--font-family--body);
  --font-data:    var(--wp--preset--font-family--data);

  /* ------------------------------------------------------------
     SIGNATURE — la vitrine de minuit
     L'audace est dépensée ICI (les temps forts sur nuit), nulle part
     ailleurs : le catalogue vit en clair, la nuit est un écrin, pas
     un fond d'écran. Le hero est une salle d'exposition : fond radial
     de nuit (showcase), spot doré discret (spotlight), l'objet porte
     l'ombre de scène (--shadow-showcase). La loupe (zoom circulaire,
     geste du grader) est LE composant signature.
     (Les hex et rgba littéraux sont des étapes de dégradé : la valeur
     brute vit DANS le token, pacte de la signature.)
     ------------------------------------------------------------ */
  --brand-showcase: radial-gradient(120% 90% at 72% 18%,
      #0c2f74 0%,                        /* cœur de lumière — n'existe que dans ce dégradé */
      var(--brand-vault) 38%,
      var(--brand-midnight) 100%);
  --brand-spotlight: radial-gradient(40% 50% at 30% 40%,
      rgba(243, 201, 105, .16), transparent 70%);   /* le spot du musée, posé SUR showcase */
  /* filet doré : la tranche dorée des séparations (bords de bande, tête de section) */
  --brand-giltline: linear-gradient(90deg,
      transparent, rgba(217, 159, 46, .45) 50%, transparent);
  /* papier jauni des back-issues : bande newsletter, encarts chauds */
  --brand-newsprint: linear-gradient(120deg, #fdf7e7 0%, #f6ecca 55%, #efe1b2 100%);
  /* bande nuit courte (CGC, encarts sombres hors hero) */
  --brand-band-night: linear-gradient(100deg, var(--brand-midnight), var(--brand-vault));

  /* ------------------------------------------------------------
     SIGNATURE — extensions passe d'absorption (gate 08/07/2026)
     ------------------------------------------------------------ */

  /* rampe sémantique de grading : état de conservation rouge→or→vert.
     SÉMANTIQUE MÉTIER, hors loi des 2 couleurs (condition, pas
     interaction). grade-mid/high : fonds et graduations UNIQUEMENT,
     jamais en texte (contrastes insuffisants). */
  --scale-grade: linear-gradient(90deg,
      var(--brand-alert) 0%, var(--brand-gold-deep) 38%,
      var(--brand-grade-mid) 62%, var(--brand-grade-high) 100%);

  /* signature home : le triple radial du hero (spot or + lueur bleue + nuit) */
  --brand-showcase-home:
      radial-gradient(1100px 680px at 16% 6%, rgba(243, 201, 105, .15), transparent 55%),
      radial-gradient(900px 620px at 86% 92%, rgba(14, 105, 255, .20), transparent 60%),
      radial-gradient(150% 130% at 50% 0%, var(--brand-vault) 0%, var(--brand-midnight) 72%);

  /* fond complet du footer (radial or + descente vers l'abîme #020b22) */
  --brand-footer-night:
      radial-gradient(900px 500px at 85% 0%, rgba(243, 201, 105, .08), transparent 60%),
      linear-gradient(180deg, var(--brand-vault) 0%, var(--brand-midnight) 58%, #020b22 100%);

  /* voile de lisibilité du header transparent (état top) */
  --brand-head-scrim: linear-gradient(180deg, rgba(3, 16, 47, .6) 0%, rgba(3, 16, 47, 0) 100%);

  /* spot or des panneaux nuit (dédoublonne .fb-dark::before et .ch-feat-panel::before) */
  --brand-night-spot: radial-gradient(42% 75% at 84% 12%, rgba(243, 201, 105, .14), transparent 70%);

  /* radial du sceau or (cœur de lumière #fbe6a8 — la valeur vit ici) */
  --brand-gold-burst: radial-gradient(circle at 50% 38%, #fbe6a8, var(--brand-gold) 60%, var(--brand-gold-deep));

  /* ------------------------------------------------------------
     COUCHE 2 — TOKENS SÉMANTIQUES (les rôles, remappables par contexte)
     Noms standard Progweb. Extensions e-commerce marquées [e-comm] :
     proposées au standard à l'occasion de ce 1er run e-commerce.
     ------------------------------------------------------------ */
  --surface-page:     var(--brand-page);
  --surface-warm:     #fdf7e7;              /* chaud newsprint uni (le dégradé = signature) */
  --surface-raised:   var(--brand-paper);
  --surface-inverse:  var(--brand-vault);
  --surface-night:    var(--brand-midnight);
  --surface-night-raised: rgba(238, 243, 255, .05);  /* panneau posé sur nuit (chips) */
  --border-night:         rgba(238, 243, 255, .16);

  --text-strong:      var(--brand-ink);
  --text-body:        var(--brand-ink);
  --text-soft:        var(--brand-ink-soft);
  --text-inverse:         var(--brand-glow);
  --text-inverse-strong:  #ffffff;          /* display sur nuit : titres, prix [e-comm nuit] */
  --text-inverse-soft:    var(--brand-dusk);

  --accent:           var(--brand-cube);
  --accent-strong:    var(--brand-cube-deep);
  --accent-alt:       var(--brand-gold);
  --link:             var(--brand-cube-deep);

  /* Encre du SURTITRE sur fond clair (recette É5, F33 — 06/08/2026).
     Le bleu Cube pur (#0e69ff) sur le fond de page (#f8f9fe) donne
     4,45:1 : sous les 4,5:1 exigés par l'AA pour du 12 px gras, seule
     violation de contraste du site. Jeton DÉDIÉ, et non un glissement
     de --accent : le bleu Cube porte aussi les icônes, les filets et
     les états de sélection, où il est juste. Le surtitre passe donc au
     bleu profond du DS (#0b54cc, déjà l'encre de --link : aucune
     couleur neuve n'entre à la palette) → 6,33:1 sur le fond de page,
     6,66:1 sur le papier blanc. Les contextes sombres gardent leurs
     surcharges explicites (cube-light), ils ne consomment pas ce jeton. */
  --eyebrow-ink:      var(--brand-cube-deep);

  --border-soft:      var(--brand-line);
  --border-strong:    var(--brand-ink-soft);

  /* Le CTA est LE geste du site (l'ajout au panier) : il ne change
     JAMAIS de couleur, quel que soit le contexte de page. Hover = or
     profond (le bleu au hover de la V2 était une faute de système). */
  --cta-bg:           var(--brand-gold);
  --cta-bg-hover:     var(--brand-gold-deep);
  --cta-text:         var(--brand-night);

  /* Le focus est une sélection → il est BLEU (loi des 2 couleurs).
     Visible sur clair, sur nuit, et sur l'or du CTA. */
  --focus-ring:       0 0 0 3px rgba(14, 105, 255, .55);

  /* Voix documentaire : grades (9.8, FN/VF), années, cotes, refs
     catalogue — en mono, jamais du texte courant */
  --data-ink:         var(--brand-ink-soft);
  --data-accent:      var(--brand-gold-ink);

  /* [e-comm] le prix est un objet de premier rang */
  --price-ink:        var(--brand-cube-deep);   /* prix sur clair (V2) ; blanc en contexte nuit */
  --stock-in:         var(--brand-gold-ink);    /* disponibilité sur clair ; or en contexte nuit */
  --state-alert:      var(--brand-alert);       /* épuisé, erreur, suppression */

  /* ------------------------------------------------------------
     COUCHE 2 — UTILITAIRES (passe d'absorption, gate 08/07/2026)
     Voiles, scrims, bordures translucides, ombres/halos, icônes :
     les primitives réutilisées par le chrome et les temps forts.
     Noms standard Progweb (proposés au standard à l'occasion du run).
     ------------------------------------------------------------ */

  /* voiles & scrims */
  --veil-night:       rgba(3, 16, 47, .8);      /* panneaux translucides sur photo : frise, pin, real-tag, figcap */
  --veil-night-solid: rgba(3, 16, 47, .97);     /* barres quasi opaques : sticky PDP */
  --scrim-modal:      rgba(2, 8, 20, .94);      /* fond de lightbox */
  --veil-accent-alt:  rgba(243, 201, 105, .15); /* fonds or translucides : pastilles d'étapes */
  --veil-accent:      rgba(14, 105, 255, .08);  /* fonds bleus translucides : icônes trust, hovers sur clair */
  --veil-accent-night: rgba(122, 191, 255, .15); /* hovers sur nuit : icônes header, social footer */

  /* bordures translucides */
  --border-night-strong: rgba(238, 243, 255, .28); /* input hero (le cran au-dessus de --border-night) */
  --border-accent-night: rgba(122, 191, 255, .18); /* filets bleutés du chrome nuit : footer, menu mobile */
  --border-accent-alt:   rgba(243, 201, 105, .4);  /* bordures or translucides : frise, sceau pointillé, étapes */
  --border-glass:        rgba(255, 255, 255, .5);  /* liserés blancs sur surfaces riches : ring du sceau or */

  /* ombres & halos (complètent soft / float / showcase / gold) */
  --shadow-deep:  0 36px 72px -36px rgba(3, 16, 47, .55); /* grands panneaux : acquisition, boutique, carte avis */
  --shadow-bar:   0 6px 24px rgba(3, 16, 47, .45);        /* barres fixes : header scrolled, menu mobile */
  --shadow-text:  0 1px 4px rgba(3, 16, 47, .6);          /* lisibilité du texte nav sur photo */
  --shadow-dot:   0 2px 8px rgba(3, 16, 47, .35);         /* curseurs d'échelle (marks) */
  --shadow-inset: inset 0 1px 3px rgba(3, 16, 47, .25);   /* creux : piste de grading, inputs creusés */
  --glow-accent:  0 0 8px 1px rgba(243, 201, 105, .7);    /* halo du point or CGC */

  /* iconographie (chantier gate 08/07). Icônes INTERACTIVES (liens
     sociaux…) : rôle --link existant, pas un token icône. */
  --icon:         var(--brand-cube);       /* icône informative sur clair */
  --icon-inverse: var(--brand-cube-light); /* icône informative sur nuit */

  /* ------------------------------------------------------------
     TYPOGRAPHIE
     Bebas Neue = la voix d'affiche (exigence client, assumée en
     signature) : titres + prix display, graisse 400 unique,
     letter-spacing .02-.04em, JAMAIS sous 20 px (--type-price-s est
     le plancher) — en dessous, Inter prend le relais.
     Inter = le corps (gate 1) ; `font-feature-settings:"tnum"` sur
     tout chiffre aligné (prix, cotes, tableaux).
     IBM Plex Mono = la voix documentaire (grades, années, cotes, refs).
     Familles : voir le pont couche 1 (servies par theme.json).
     ------------------------------------------------------------ */

  /* Échelle fluide — corps relevé à 17 px (la V2 vivait à 13-15 px :
     sous le plancher moderne et sous le confort de la cible 35-55 ans).
     PLANCHER ABSOLU : 12 px (--type-micro). Rien en dessous, nulle part. */
  --type-hero:     clamp(3rem, 6.5vw, 4.75rem);      /* display 400, lh .96, Bebas encaisse grand */
  --type-display:  clamp(2.25rem, 4.5vw, 3.375rem);  /* h1 PDP (54 px V2 conservé en plafond) */
  --type-title:    clamp(1.625rem, 2.6vw, 2.25rem);  /* titres de section */
  --type-subtitle: 1.375rem;                         /* Inter 600 */
  --type-lead:     1.3125rem;                        /* chapeaux, lh 1.5 */
  --type-body:     1.0625rem;                        /* 17 px — corps courant, lh 1.65 */
  --type-caption:  .875rem;                          /* 14 px — cartes denses, légendes */
  --type-micro:    .75rem;                           /* 12 px — tags, compteurs. PLANCHER */
  --type-data:     .8125rem;                         /* 13 px mono, ls .02em */
  --type-eyebrow:  .8125rem;                         /* 13 px caps, 600, ls .14em */
  /* [e-comm] les prix parlent Bebas (l'étiquette d'époque) */
  --type-price-hero: clamp(2.75rem, 4.5vw, 3.125rem);  /* PDP */
  --type-price:      1.625rem;                         /* cartes, sticky, tiroir */
  --type-price-s:    1.25rem;                          /* 20 px : le plus petit Bebas autorisé */

  /* ------------------------------------------------------------
     FORMES, PROFONDEUR, RYTHME
     3 crans + pilule (la V2 improvisait 16 valeurs). Rigueur de
     cadre de musée : rayons contenus. Ombres teintées nuit sur
     clair ; l'objet exposé sur nuit porte l'ombre de scène.
     ------------------------------------------------------------ */
  --radius-s:   8px;    /* vignettes, mini-objets */
  --radius-m:   12px;   /* boutons, chips, inputs, cadres de couverture */
  --radius-l:   18px;   /* cartes, bandes */
  --radius-arc: 999px;  /* pilules (tags, keytag) */

  --shadow-soft:     0 8px 28px -14px rgba(3, 16, 47, .25);
  --shadow-float:    0 18px 50px -20px rgba(3, 16, 47, .35);
  --shadow-showcase: 0 40px 80px -30px rgba(0, 0, 0, .75),
                     0 0 0 1px rgba(255, 255, 255, .06);   /* pièce exposée sur nuit */
  --shadow-cta:      0 16px 34px -16px rgba(243, 201, 105, .55);  /* halo du CTA */

  --space-1: .25rem;  --space-2: .5rem;  --space-3: .75rem;
  --space-4: 1rem;    --space-5: 1.5rem; --space-6: 2rem;
  --space-7: 3rem;    --space-8: 4.5rem; --space-9: 6.5rem;

  --container: 1180px;  /* constaté V2 → theme.json layout.contentSize (étape 4 : fait) */
  --container-wide: 1360px;

  /* ------------------------------------------------------------
     MOUVEMENT — feuilleter une pièce sous vitrine : départ franc,
     pose douce (l'easing des V2, conservé). CSS d'abord (décision 9
     du Modèle) ; l'orchestration vit à l'étape 3.
     ------------------------------------------------------------ */
  --ease-cube: cubic-bezier(.22, 1, .36, 1);
  --t-quick: 160ms;   /* micro-interactions */
  --t-soft:  320ms;   /* survols composés */
  --t-scene: 700ms;   /* séquences d'entrée (reveal V2 : .7s, conservé) */
}

/* ------------------------------------------------------------
   CONTEXTE NUIT — les temps forts (hero, bande CGC, sticky, footer).
   Un seul système : les rôles se remappent, les composants ne
   changent pas. Le CTA reste or (loi des 2 couleurs). Le bleu cube
   pur ne porte pas de texte ici (4.0:1) : l'interaction passe en
   bleu clair.
   ------------------------------------------------------------ */
[data-theme="night"] {
  --surface-page:     var(--brand-midnight);
  --surface-warm:     var(--brand-night);
  --surface-raised:   var(--brand-night);
  --surface-inverse:  var(--brand-paper);

  --text-strong:      var(--text-inverse-strong);
  --text-body:        var(--brand-glow);
  --text-soft:        var(--brand-dusk);

  --accent-strong:    var(--brand-cube-light);
  --link:             var(--brand-cube-light);

  --border-soft:      var(--border-night);
  --border-strong:    var(--brand-dusk);

  --data-ink:         var(--brand-dusk);
  --data-accent:      var(--brand-gold);

  --price-ink:        var(--text-inverse-strong);
  --stock-in:         var(--brand-gold);
  --state-alert:      var(--brand-alert-light);

  --shadow-soft:      0 8px 28px -14px rgba(0, 0, 0, .55);
  --shadow-float:     0 18px 50px -20px rgba(0, 0, 0, .65);
}

/* ------------------------------------------------------------
   ACCESSIBILITÉ — plancher non négociable
   Paires mesurées (WCAG, 07/07/2026) :
   - ink/paper 12.8:1 · ink/page 12.2:1 · ink-soft/page 5.1:1
   - cube-deep/paper 6.7:1 · cube/paper 4.7:1 (eyebrows AA)
   - glow/midnight 16.9:1 · dusk/midnight 9.9:1 · dusk/vault 7.1:1
   - cube-light/midnight 9.6:1 · blanc/vault 13.5:1
   - CTA : night/gold 10.8:1 · gold/midnight 12.0:1 (stockline nuit)
   - gold-ink/page 4.9:1 · alert/paper 5.1:1
   Règles : l'or #f3c969 ne porte JAMAIS de texte sur fond clair
   (gold-ink à la place) ; le bleu cube sur nuit = bordures et fonds
   uniquement (4.0:1), le texte interactif sur nuit = cube-light ;
   jamais de noir pur en texte ; rien sous 12 px.
   ------------------------------------------------------------ */
:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-s);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* === /assets/css/kadence-neutralisation.css === */
/* ------------------------------------------------------------
   NEUTRALISATION PARENT UNIQUE (passe de cohérence, 12/07/2026).
   Adaptateur d'environnement child-only : le registre reste
   parent-agnostique, ce fichier est le seul à parler Kadence.

   Le parent peint tous les états d'interaction non possédés avec
   sa palette : a:hover/:focus/:active → --global-palette-highlight-alt
   et button:hover/:focus/:active → --global-palette-btn-bg-hover,
   deux variables qui pointent sur --global-palette4 = #000000.
   C'était la racine du « noir au survol » constaté partout
   (accordéons FAQ, liens « En savoir plus », boutons RS, ajout
   panier au clic). Au lieu de multiplier les verrous ciblés, on
   repointe UNE FOIS les 6 variables d'interaction vers les tokens
   du DS : tout élément non verrouillé dégrade désormais vers le
   bleu du système, jamais vers le noir. Les composants du registre
   verrouillent en plus leurs propres états (double filet).

   :root:root (0-2-0) : le parent imprime sa palette (inline
   kadence-global) APRÈS les feuilles du child dans le head — un
   :root nu (0-1-0) perdrait à l'ordre des sources.
   ------------------------------------------------------------ */
:root:root {
  --global-palette-highlight: var(--link);
  --global-palette-highlight-alt: var(--accent-strong);
  --global-palette-btn: var(--text-inverse-strong);
  --global-palette-btn-hover: var(--text-inverse-strong);
  --global-palette-btn-bg: var(--accent);
  --global-palette-btn-bg-hover: var(--accent-strong);
}

/* === /assets/css/components/cta.css === */
/* ------------------------------------------------------------
   CTA — le bouton d'achat (l'adjudication) + bouton secondaire.
   Loi des 2 couleurs : or = j'achète (hover = or profond, jamais
   bleu, correctif gate 1) ; le secondaire est une sélection → bleu.
   Canonique depuis le gate 1 (07/07/2026). Les helpers de démo
   d'états (.is-hover, .is-focus) vivent sur la planche, pas ici.
   Les états :hover VERROUILLENT leur couleur (retour de gate É4
   Bloc 4) : posé sur un lien, le a:hover du parent Kadence
   (global.min.css, --global-palette-highlight-alt) volait le texte
   au survol — illisible sur la bande nuit. Un composant possède sa
   couleur dans tous ses états.
   ------------------------------------------------------------ */
.cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  background: var(--cta-bg); color: var(--cta-text); border: 0; cursor: pointer;
  border-radius: var(--radius-m); padding: 16px 28px;
  font-family: var(--font-display); font-weight: 400; font-size: var(--type-price-s);
  letter-spacing: .04em; text-transform: uppercase;
  box-shadow: var(--shadow-cta);
  transition: background var(--t-quick) var(--ease-cube), transform var(--t-quick) var(--ease-cube);
}
/* verrou sur les 3 états (passe de cohérence 12/07) : la recette du
   parent couvre hover, focus ET active (0-1-1) — l'active non
   verrouillé peignait l'ajout panier en noir le temps du clic, et
   son box-shadow de survol remplaçait le halo or sur hôte <button> */
.cta:hover, .cta:focus, .cta:active { background: var(--cta-bg-hover); color: var(--cta-text); box-shadow: var(--shadow-cta); }
.cta:hover { transform: translateY(-1px); }
/* le focus global (tokens.css) remplace le box-shadow : on recombine
   ring bleu + halo or, l'état démontré sur la planche */
.cta:focus-visible { box-shadow: var(--focus-ring), var(--shadow-cta); }

.btn-2nd {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface-raised); color: var(--accent-strong);
  border: 1.5px solid var(--accent); border-radius: var(--radius-m);
  padding: 14px 24px; font-weight: 600; font-size: var(--type-caption); cursor: pointer;
  /* typo gravée (passe de cohérence 12/07) : sur hôte <button>, la
     recette du parent imposait sa Bebas — la voix se déclare */
  font-family: var(--font-body); letter-spacing: 0; text-transform: none; line-height: 1.2;
  box-shadow: none;
  transition: background var(--t-quick) var(--ease-cube);
}
.btn-2nd:hover, .btn-2nd:focus, .btn-2nd:active { background: rgba(14, 105, 255, .08); color: var(--accent-strong); box-shadow: none; }
.btn-2nd:focus-visible { box-shadow: var(--focus-ring); }

/* ------------------------------------------------------------
   Variantes de géométrie (passe d'absorption, gate 08/07/2026).
   Seule la boîte change selon l'hôte : la couleur, la typo et le
   geste (loi des 2 couleurs) restent ceux du .cta canonique.
   Les pages posent ces classes au lieu d'un override local.
   ------------------------------------------------------------ */
/* barre sticky PDP : bouton dense (hauteur de barre fixe) */
.cta--compact { padding: 11px 22px; }
/* CTA soudé dans un champ composé (recherche du hero) : la hauteur
   vient du champ, d'où le padding vertical nul */
.cta--field { padding: 0 22px; }
@media (max-width: 680px) {
  /* le champ se dé-compose en colonne : le CTA reprend sa hauteur propre */
  .cta--field { padding: 14px 22px; }
}

/* === /assets/css/components/btn.css === */
/* ------------------------------------------------------------
   BTN — la famille de boutons de service (passe de cohérence,
   12/07/2026). La paire de conversion vit dans cta.css (.cta or
   = l'adjudication, .btn-2nd = le choix) ; ici les voix hors
   conversion :
   - .btn-blue  : l'action de service (bleu plein). Le « primaire »
     des espaces sans or (compte, modal, lieux) : valider, envoyer,
     se connecter, voir sur Google Maps.
   - .btn-ghost : le rebond discret (filet, texte bleu profond).
     Tertiaire : « voir tout », Click & Collect. Fusion des ex
     .btn-line / .btn-ghost-light du chrome (deux recettes, une voix).
   - .btn-ico   : le carré d'icône 38px (réseaux sociaux). Une seule
     recette ; le contexte nuit ([data-theme="night"], motif du
     footer) remappe filet, veil et couleur.
   Chaque voix grave sa typographie complète (labeur Inter) et
   VERROUILLE hover + focus + active : la recette d'états du parent
   Kadence (button:hover/:focus/:active, 0-1-1) bat une classe nue
   (0-1-0) et peignait fond noir + Bebas condensée. Le remap global
   des variables d'interaction du parent vit côté child
   (kadence-neutralisation.css) ; ici, le composant possède ses
   états, sur tout hôte (<a> comme <button>).
   ------------------------------------------------------------ */
.btn-blue {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--accent); color: var(--text-inverse-strong);
  border: 0; cursor: pointer; border-radius: var(--radius-m);
  padding: 14px 24px;
  font-family: var(--font-body); font-weight: 600; font-size: var(--type-caption);
  letter-spacing: 0; text-transform: none; line-height: 1.2;
  box-shadow: none;
  transition: background var(--t-quick) var(--ease-cube);
}
.btn-blue:hover, .btn-blue:focus, .btn-blue:active {
  background: var(--accent-strong); color: var(--text-inverse-strong); box-shadow: none;
}
.btn-blue:focus-visible { box-shadow: var(--focus-ring); }

.btn-ghost {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  background: transparent; color: var(--accent-strong);
  border: 1.5px solid var(--border-soft); cursor: pointer; border-radius: var(--radius-m);
  padding: 13px 22px;
  font-family: var(--font-body); font-weight: 600; font-size: var(--type-caption);
  letter-spacing: 0; text-transform: none; line-height: 1.2;
  box-shadow: none;
  transition: border-color var(--t-quick) var(--ease-cube), background var(--t-quick) var(--ease-cube);
}
.btn-ghost:hover, .btn-ghost:focus, .btn-ghost:active {
  border-color: var(--accent); background: var(--veil-accent);
  color: var(--accent-strong); box-shadow: none;
}
.btn-ghost:focus-visible { box-shadow: var(--focus-ring); }

.btn-ico {
  width: 38px; height: 38px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--link);
  border: 1px solid var(--border-soft); cursor: pointer; border-radius: var(--radius-m);
  box-shadow: none;
  transition: background var(--t-quick) var(--ease-cube), border-color var(--t-quick) var(--ease-cube), color var(--t-quick) var(--ease-cube);
}
.btn-ico:hover, .btn-ico:focus, .btn-ico:active {
  background: var(--veil-accent); border-color: var(--accent);
  color: var(--link); box-shadow: none;
}
.btn-ico:focus-visible { box-shadow: var(--focus-ring); }

/* contexte nuit (footer, bandes) : le veil clair ne se remappe pas,
   le motif du footer fait foi — filet bleuté, veil nuit, texte blanc */
[data-theme="night"] .btn-ico { border-color: var(--border-accent-night); }
[data-theme="night"] .btn-ico:hover,
[data-theme="night"] .btn-ico:focus,
[data-theme="night"] .btn-ico:active {
  background: var(--veil-accent-night); border-color: var(--brand-cube-light);
  color: var(--text-inverse-strong);
}

/* === /assets/css/components/eyebrow.css === */
/* ------------------------------------------------------------
   SURTITRE (eyebrow) — le label de tête de section : petites
   capitales bleu cube précédées du TIRET OR signature. Atome
   récurrent (chaque section de la home et de la PDP en pose un).
   Entré au registre le 08/07 : le tiret or vivait dans le chrome,
   invisible à la planche (trou de vitrine relevé par Julien).

   - Constantes internes de l'atome (géométrie du tiret 26x2, gap,
     rythme, graisse) : elles vivent ici (règle : valeur propre à un
     composant -> son fichier). Le or et le bleu sont des tokens.
   - L'encre sur clair est --eyebrow-ink (F33, 06/08/2026), jeton dédié
     au surtitre : le bleu Cube pur ne tient pas l'AA à 12 px gras sur
     le fond de page. Voir tokens.css pour le motif.
   - Variante nuit : sur un contexte [data-theme="night"] le texte
     passe en cube-light (le bleu cube pur ne porte pas de texte sur
     nuit). Le chrome mappe EN PLUS ses sections sombres .fb-dark au
     même recolor et masque le tiret quand la tête est centrée
     (.sec-head.center) — adaptations de contexte laissées au chrome.
   ------------------------------------------------------------ */
.eyebrow {
  display: inline-flex; align-items: center; gap: 11px;
  font-size: var(--type-micro); font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--eyebrow-ink); margin-bottom: 13px;
}
.eyebrow::before { content: ''; width: 26px; height: 2px; background: var(--brand-gold); }
[data-theme="night"] .eyebrow { color: var(--brand-cube-light); }

/* === /assets/css/components/formmsg.css === */
/* ------------------------------------------------------------
   Messages de formulaire (formmsg) — réponses serveur des
   Advanced Forms Kadence (newsletter, contact) : la carte nuit
   des notices Woo de la PDP généralisée (single-product § notices,
   gate maquette Julien 15/07, É5 temps 2). Succès = filet + coche
   or ; avertissement (rejet honeypot) et erreur d'envoi = filet +
   glyphe alerte. La validation de saisie (case consentement,
   e-mail vide) reste la bulle NATIVE du navigateur : rien ici.
   Sélecteur doublé : la classe de base bat les défauts bleus de
   Kadence (égalité de spécificité sinon, l'ordre déciderait).
   Anatomie : div.kb-adv-form-message.kb-adv-form-{success|warning|error}
   Consommé par : build É4 (toutes les vues à formulaire) ·
   planche de style (spécimens).
   ------------------------------------------------------------ */
.kb-adv-form-message.kb-adv-form-message { display: block; background: var(--brand-night); border: 1px solid var(--brand-night); border-left: 3px solid var(--brand-gold); border-radius: var(--radius-m); color: var(--text-inverse); padding: var(--space-3) var(--space-4); margin: var(--space-4) 0 0; font-family: var(--font-body); font-size: var(--type-caption); font-weight: 400; line-height: 1.55; letter-spacing: normal; text-transform: none; text-align: left; }
.kb-adv-form-message.kb-adv-form-message::before { content: "✓"; color: var(--brand-gold); font-weight: 700; margin-right: var(--space-2); }
.kb-adv-form-message.kb-adv-form-warning, .kb-adv-form-message.kb-adv-form-error { border-left-color: var(--state-alert); }
.kb-adv-form-message.kb-adv-form-warning::before, .kb-adv-form-message.kb-adv-form-error::before { content: "!"; color: var(--state-alert); }
/* Kadence déplace le focus sur le message (a11y, tabindex -1) : le
   comportement reste, l'anneau visuel n'a pas de sens sur une boîte
   non interactive. */
.kb-adv-form-message.kb-adv-form-message:focus { outline: none; box-shadow: none; }
/* Le rejet arrive enveloppé d'un <h2 class="kb-adv-form-error-title">
   (markup Kadence) : sans possession il prend la Bebas des titres et
   pousse le glyphe sur sa propre ligne. Inline, à la voix du message. */
.kb-adv-form-message.kb-adv-form-message .kb-adv-form-error-title { display: inline; font-family: var(--font-body); font-size: var(--type-caption); font-weight: 400; line-height: 1.55; letter-spacing: normal; text-transform: none; color: var(--text-inverse); margin: 0; }

/* === /assets/css/components/pcard.css === */
/* ------------------------------------------------------------
   Carte produit v1.1 — LA CANONIQUE du registre (gate 07/07/2026).
   Fusion : châssis V2 validé (cadre or « sous-cadre du musée »,
   survol levé + bord or, badge, « Voir → » révélé) + anatomie DS
   (grade mono, prix, ligne stock). Toute page consomme CETTE carte.
   La couverture est la seule image de la carte (règle d'usage 8).
   Anatomie : .frame > .cover (+ .keytag posé, + .tag badge) ·
   .pt (titre) · .pg (grade mono) · .row > .pp (prix) + .see (révélé) ·
   .ps (stock, .out = épuisé).
   .cards = la grille standard du catalogue, voyage avec la carte.
   Consomme .keytag : importer après keytag.css.
   ------------------------------------------------------------ */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--space-5); }
/* mobile : 2 colonnes (retour 20 de F-ter-a, 12/07 — le standard
   e-commerce ; la colonne unique de l'auto-fill gaspillait l'écran) */
@media (max-width: 560px) { .cards { grid-template-columns: repeat(2, 1fr); gap: var(--space-3); } }
.pcard {
  background: var(--surface-raised); border: 1px solid var(--border-soft);
  border-radius: var(--radius-m); padding: 10px; display: block; text-decoration: none;
  transition: transform var(--t-soft) var(--ease-cube), box-shadow var(--t-soft) var(--ease-cube), border-color var(--t-soft) var(--ease-cube);
}
.pcard:hover { transform: translateY(-6px); box-shadow: var(--shadow-float); border-color: var(--brand-gold); }
.pcard > span { display: block; }
.pcard .frame { background: var(--brand-gold-soft); border-radius: var(--radius-s); padding: var(--space-2); position: relative; }
.pcard .cover { display: block; aspect-ratio: 2/3; border-radius: calc(var(--radius-s) / 2); overflow: hidden; background: var(--brand-line); position: relative; }
.pcard .cover img { width: 100%; height: 100%; object-fit: cover; }
.pcard .cover .keytag { position: absolute; left: 8px; bottom: 8px; backdrop-filter: blur(3px); background: rgba(255, 253, 245, .92); }
.pcard .tag { position: absolute; left: var(--space-4); top: var(--space-4); z-index: 1; background: var(--accent); color: var(--text-inverse-strong); font-size: var(--type-micro); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; padding: var(--space-1) var(--space-2); border-radius: var(--radius-arc); }
/* titre : caption → body (retour 11 de F-ter-a, 12/07 : « presque pas
   lisible » en boutique) — le nom du comic est l'information n° 1.
   La typo se grave (motif pillar/h4) : l'archive rend le titre en <h3>,
   la recette headings du parent y imposait sa Bebas condensée */
.pcard .pt { font-family: var(--font-body); font-size: var(--type-body); font-weight: 600; color: var(--text-strong); margin: 10px 3px 3px; line-height: 1.35; }
.pcard .pg { font-family: var(--font-data); font-size: var(--type-data); color: var(--data-ink); margin: 0 3px 6px; }
.pcard .pg b { color: var(--data-accent); font-weight: 600; }
.pcard .row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); margin: 0 3px 4px; }
.pcard .pp { font-family: var(--font-display); font-weight: 400; font-size: var(--type-price); color: var(--price-ink); line-height: 1; }
.pcard .see { font-size: var(--type-micro); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--data-accent); opacity: 0; transform: translateX(-6px); transition: opacity var(--t-quick) var(--ease-cube), transform var(--t-quick) var(--ease-cube); }
.pcard:hover .see, .pcard:focus-visible .see { opacity: 1; transform: none; }
.pcard .ps { font-size: var(--type-micro); font-weight: 600; color: var(--stock-in); margin: 0 3px 4px; }
.pcard .ps.out { color: var(--state-alert); }
.pcard .ps .oosline { text-decoration: line-through; color: var(--text-soft); font-weight: 500; }

/* === /assets/css/components/navchip.css === */
/* ------------------------------------------------------------
   Puce éditeur (navigation) — molécule de la home (registre, 07/07/2026).
   Pastille de raccourci vers une série (« Batman 714 ») sous les
   rayons : fond papier, bord filet, compteur mono en .c ; survol →
   bord + texte cube, halo bleu léger. Puce de NAVIGATION : aucun
   rapport avec le composant .chip (comparateur de grade) du registre.
   Vit sur fond clair (le hero utilise .ch-hchip, herochip).
   .ch-chips = la rangée (2e des deux déclarations de .ch-chips :
   importer APRÈS herochip.css).
   consommé par : accueil.html (home)
   ------------------------------------------------------------ */
.ch-chips { display: flex; flex-wrap: wrap; gap: 10px; }
.ch-chip { display: inline-flex; align-items: center; gap: 8px; background: var(--brand-paper); border: 1px solid var(--brand-line); border-radius: 999px; padding: 9px 15px; font-size: var(--type-micro); font-weight: 600; color: var(--brand-ink); transition: .16s; }
.ch-chip .c { font-family: var(--font-data); font-size: var(--type-micro); color: var(--brand-ink-soft); }
.ch-chip:hover { border-color: var(--brand-cube); color: var(--brand-cube-deep); box-shadow: 0 0 0 3px rgba(14,105,255,.1); }

/* Variante .ch-chip-tout — la porte de sortie des archives (gate
   13/07/2026) : pilule PLEINE bleue en tête de rangée, retour vers tout
   le catalogue depuis un rayon, une vitrine, une archive d'attribut ou
   la recherche (jamais sur la boutique : elle EST le catalogue). Voix
   navigation, l'or reste à l'achat (loi des 2 couleurs). Les 3 états
   sont possédés (le a:hover du parent volerait texte et fond).
   consommé par : archive-product.php (contextes hors boutique) */
.ch-chip-tout { background: var(--accent); border-color: var(--accent); color: var(--text-inverse-strong); }
.ch-chip-tout:hover, .ch-chip-tout:focus, .ch-chip-tout:active { background: var(--accent-strong); border-color: var(--accent-strong); color: var(--text-inverse-strong); box-shadow: none; }
.ch-chip-tout:focus-visible { box-shadow: var(--focus-ring); }

/* === /assets/css/components/counter.css === */
/* ------------------------------------------------------------
   Compteur de grade — molécule de la home (registre, 07/07/2026).
   Cartouche d'une fourchette Overstreet : liseré or en tête, note
   en Bebas cube (.g), description en .d. NB : le rail .ch-scale et
   la grille .ch-grade-cards restent hors registre (section grading,
   hors périmètre) — ce fichier ne porte que la carte .ch-gc.
   consommé par : accueil.html (home)
   ------------------------------------------------------------ */
.ch-gc { background: var(--brand-paper); border: 1px solid var(--brand-line); border-top: 3px solid var(--brand-gold); border-radius: 13px; padding: 18px; box-shadow: 0 12px 28px -22px rgba(3,16,47,.32); }
.ch-gc .g { font-family: var(--font-display); font-size: var(--type-price); color: var(--brand-cube); }
.ch-gc .d { font-size: var(--type-micro); color: var(--brand-ink-soft); margin-top: 3px; line-height: 1.45; }

/* === /assets/css/components/crumb.css === */
/* ------------------------------------------------------------
   Fil d'Ariane (crumb) — le chemin de l'arbre catalogue.
   Extrait de fiche-produit.html le 08/07/2026 (gabarit archive).
   Le hero PDP porte data-theme="night" : la BASE est donc le
   contexte clair (--brand-ink-soft / --brand-ink), la variante
   [data-theme="night"] reprend au pixel les valeurs du hero PDP
   (--text-inverse-*). La PDP rebranchée rend à l'identique ;
   l'en-tête clair de l'archive (boutique/rayon/vitrine) consomme
   la base claire sans override.
   Anatomie : .crumb > a (liens) · span (séparateurs) · b (page
   courante). Le margin-bottom appartient au composant (rythme V2
   conservé sous le fil, pixel-identique PDP).
   ------------------------------------------------------------ */
.crumb { font-size: var(--type-micro); letter-spacing: .05em; text-transform: uppercase; color: var(--brand-ink-soft); margin-bottom: 26px; }
.crumb a { color: var(--brand-ink-soft); transition: color var(--t-quick) var(--ease-cube); }
.crumb a:hover { color: var(--brand-ink); }
.crumb span { margin: 0 7px; opacity: .6; }
.crumb b { color: var(--brand-ink); font-weight: 600; }

/* contexte nuit — l'écrin (hero PDP) : valeurs d'origine, rendu identique */
[data-theme="night"] .crumb { color: var(--text-inverse-soft); }
[data-theme="night"] .crumb a { color: var(--text-inverse-soft); }
[data-theme="night"] .crumb a:hover { color: var(--text-inverse-strong); }
[data-theme="night"] .crumb b { color: var(--text-inverse); }

/* === /assets/css/components/grading.css === */
/* ------------------------------------------------------------
   Grading — les molécules de la cote, extraites verbatim
   d'accueil.html le 08/07/2026 (gabarit archive), cascade
   préservée. Deux pièces sœurs de la famille « cote » :
   - .ch-grate : la carte note Google (bloc confiance), gros
     score Bebas or, étoiles, sous-ligne.
   - .ch-scale : le rail sémantique du grading (rampe --scale-grade
     rouge→or→vert, hors loi des 2 couleurs : condition, pas
     interaction) + .ch-grade-cards (grille des cartouches .ch-gc
     du registre, counter.css) + .ch-link (lien « en savoir plus »).
   La section grading est réutilisée verbatim par l'archive
   (boutique) ; la carte note reste consommée par la home.
   Anatomie grate : .ch-grate > .grc-top > b + .grs · .grc-sub (strong).
   Anatomie scale : .ch-scale > .track > .mk · .ticks.
   Consommé par : accueil.html, boutique.html.
   ------------------------------------------------------------ */

/* carte note Google (bloc confiance de la home) */
.ch-grate { display: flex; align-items: center; gap: 16px; background: linear-gradient(160deg, var(--brand-paper), var(--brand-page)); border: 1px solid var(--brand-line); border-radius: var(--radius-l); padding: 22px 26px; box-shadow: var(--shadow-deep); transition: transform .2s, box-shadow .2s; }
.ch-grate:hover { transform: translateY(-3px); box-shadow: var(--shadow-deep); }
.ch-grate .grc-top { display: flex; align-items: baseline; gap: 10px; }
.ch-grate b { font-family: var(--font-display); font-weight: 400; font-size: var(--type-price-hero); line-height: .9; color: var(--brand-gold-deep); }
.ch-grate .grs { color: var(--brand-gold); letter-spacing: 3px; font-size: var(--type-caption); }
.ch-grate .grc-sub { display: block; font-size: var(--type-micro); color: var(--brand-ink-soft); margin-top: 4px; }
.ch-grate .grc-sub strong { color: var(--brand-ink); }

/* rail sémantique de grading (rampe rouge→or→vert : token --scale-grade) */
.ch-scale { margin: 8px 0 26px; max-width: 920px; }
.ch-scale .track { position: relative; height: 13px; border-radius: var(--radius-arc); background: var(--scale-grade); box-shadow: var(--shadow-inset); }
.ch-scale .mk { position: absolute; top: 50%; width: 20px; height: 20px; border-radius: 50%; background: var(--brand-paper); border: 4px solid var(--brand-gold-deep); transform: translate(-50%, -50%); box-shadow: var(--shadow-dot); }
.ch-scale .ticks { display: flex; justify-content: space-between; margin-top: 10px; font-family: var(--font-data); font-size: var(--type-micro); color: var(--brand-ink-soft); letter-spacing: .03em; }
.ch-grade-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; align-items: stretch; }
.ch-link { display: inline-block; margin-top: 24px; color: var(--brand-cube-deep); font-weight: 600; font-size: var(--type-caption); }

@media (max-width: 680px) {
  .ch-grade-cards { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 520px) {
  .ch-grade-cards { grid-template-columns: 1fr; }
}

/* === /assets/css/components/facet.css === */
/* ------------------------------------------------------------
   Facette de filtre (facet) — molécule de l'archive catalogue
   (registre, 08/07/2026 · accordéon 10/07/2026, refonte boutique C).
   Un groupe = un titre de groupe (Inter micro-caps) + une liste
   d'options à vrai <input> (radio ou case) labellisées, chacune avec
   son comptage réel aligné à droite en voix documentaire (mono, comme
   toute donnée chiffrée du DS). Lien « tout afficher » / mention de
   reliquat quand la liste dépasse ~7 entrées.

   ACCORDÉON (parti d'UX gaté 10/07) : le groupe est un <details>
   natif, son titre un <summary> à chevron CSS — zéro JS, clavier et
   lecteurs d'écran servis par la plateforme. L'hôte décide des
   groupes ouverts par défaut (attribut open : Disponibilité et
   Éditeur sur l'archive), le reste replié : la colonne tient sans
   scroll interne, la double barre de défilement est morte avec.
   L'ancienne forme plate (p.facet-t sans details) reste stylée :
   un hôte sans accordéon consomme le composant tel quel.

   État actif = marqueur OR (« vous êtes ici » : voile --brand-gold-soft
   + comptage en or lisible), tandis que le contrôle natif de
   SÉLECTION reste BLEU (accent-color: --accent) : la loi des 2
   couleurs tient (bleu = je choisis), l'or ne fait que baliser le
   filtre appliqué (même famille que le comptage documentaire).

   Contexte : le composant ne change pas selon l'hôte (tiroir
   poussant desktop ou tiroir plein écran mobile : échafaudage de
   page). Anatomie : details.facet[open] > summary.facet-t (titre +
   chevron) · .facet-body > .facet-list > .facet-opt (label) > input +
   .facet-opt-txt + .facet-ct (comptage) · .facet-more (tout afficher).
   ------------------------------------------------------------ */
.facet + .facet { margin-top: var(--space-5); }
.facet-t {
  font-size: var(--type-caption); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-strong); margin-bottom: var(--space-3);
}
/* titre-résumé de l'accordéon : toute la rangée déclenche, chevron CSS */
summary.facet-t {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  cursor: pointer; list-style: none; margin-bottom: 0; padding: var(--space-3) 0;
}
summary.facet-t::-webkit-details-marker { display: none; }
summary.facet-t::after {
  content: ''; flex: 0 0 auto; width: 7px; height: 7px; margin-right: 3px;
  border-right: 2px solid var(--text-soft); border-bottom: 2px solid var(--text-soft);
  transform: rotate(45deg); transition: transform var(--t-quick) var(--ease-cube);
}
details.facet[open] > summary.facet-t::after { transform: rotate(225deg); }
summary.facet-t:hover::after { border-color: var(--text-strong); }
.facet-body { padding: var(--space-1) 0 var(--space-4); }

.facet-list { display: flex; flex-direction: column; gap: var(--space-1); }
.facet-opt {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2); border-radius: var(--radius-s); cursor: pointer;
  font-size: var(--type-caption); color: var(--text-soft);
  transition: color var(--t-quick) var(--ease-cube), background var(--t-quick) var(--ease-cube);
}
.facet-opt input { flex: 0 0 auto; margin: 0; accent-color: var(--accent); cursor: pointer; }
.facet-opt-txt { flex: 1 1 auto; min-width: 0; line-height: 1.3; }
.facet-ct {
  flex: 0 0 auto; font-family: var(--font-data); font-size: var(--type-micro);
  color: var(--data-ink); letter-spacing: .02em; font-variant-numeric: tabular-nums;
}
.facet-opt:hover .facet-opt-txt { color: var(--text-strong); }
.facet-opt:has(input:checked) { background: var(--brand-gold-soft); }
.facet-opt:has(input:checked) .facet-opt-txt { color: var(--text-strong); font-weight: 600; }
.facet-opt:has(input:checked) .facet-ct { color: var(--data-accent); font-weight: 600; }
.facet-more {
  display: inline-block; margin-top: var(--space-2); padding: var(--space-1) var(--space-2);
  background: transparent; border: 0; font-family: inherit; font-size: var(--type-micro);
  color: var(--link); cursor: pointer; text-align: left;
}
.facet-more:hover { text-decoration: underline; }
/* mention de reliquat (« et N autres… ») : même gabarit, ton discret, non cliquable */
.facet-more.is-note { color: var(--text-soft); cursor: default; }
.facet-more.is-note:hover { text-decoration: none; }

/* === /assets/css/components/toolbar.css === */
/* ------------------------------------------------------------
   Barre d'outils de grille (toolbar) — molécule de l'archive
   catalogue (registre, 08/07/2026 · bouton permanent 10/07/2026,
   refonte boutique C). Coiffe la grille produits : bouton
   « Filtres » avec badge du nombre de filtres actifs (ouvre le
   tiroir, desktop comme mobile — parti d'UX gaté : le filtrage
   profond vit dans un tiroir qui pousse, l'étage rapide reste
   toujours visible), compteur de résultats (chiffre en voix
   documentaire mono), select de tri stylé tokens, rangée de chips
   de filtres actifs retirables.

   Anatomie propre — n'emprunte NI .chip (comparateur de grade, PDP)
   NI .ch-chip (puce de série, navchip) : la pastille de filtre actif
   est .tb-chip. Le chip de filtre appliqué et le badge du bouton
   sont des MARQUEURS (voile or + or lisible, même famille que le
   comptage documentaire), pas une sélection bleue ni un CTA : la
   loi des 2 couleurs tient (le bouton lui-même, une commande,
   reste bleu).
   Anatomie : .toolbar > .tb-bar (bouton filtres + compteur + tri) ·
   .tb-chips > .tb-chip (label + bouton × retirable). .tb-filters >
   .tb-fbadge = badge de filtres actifs.
   ------------------------------------------------------------ */
.tb-bar { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.tb-count { font-size: var(--type-caption); color: var(--text-soft); margin-right: auto; }
.tb-count b { font-family: var(--font-data); font-weight: 600; color: var(--text-strong); font-variant-numeric: tabular-nums; }

.tb-sort { display: inline-flex; align-items: center; gap: var(--space-2); }
.tb-sort > span { font-size: var(--type-micro); letter-spacing: .1em; text-transform: uppercase; color: var(--text-soft); }
.tb-sort select {
  font-family: var(--font-body); font-size: var(--type-caption); color: var(--text-body);
  background: var(--surface-raised); border: 1px solid var(--border-soft);
  border-radius: var(--radius-m); padding: var(--space-2) var(--space-3); cursor: pointer;
  transition: border-color var(--t-quick) var(--ease-cube);
}
.tb-sort select:hover { border-color: var(--border-strong); }

.tb-filters {
  display: inline-flex; align-items: center; gap: var(--space-2);
  background: var(--surface-raised); color: var(--accent-strong);
  border: 1px solid var(--accent); border-radius: var(--radius-m);
  padding: var(--space-2) var(--space-3); font-family: inherit; font-size: var(--type-caption);
  font-weight: 600; cursor: pointer; transition: background var(--t-quick) var(--ease-cube);
}
/* tous les états possèdent leur couleur ET leur fond (motif Bloc 4,
   retour de gate C 10/07, :active + ombre généralisés à la passe de
   cohérence 12/07) : le parent Kadence blanchit le texte au survol et
   peint le :focus des boutons en sombre */
.tb-filters:hover, .tb-filters:active { background: var(--veil-accent); color: var(--accent-strong); box-shadow: none; }
.tb-filters:focus { background: var(--surface-raised); color: var(--accent-strong); box-shadow: none; }
.tb-filters:focus-visible { box-shadow: var(--focus-ring); }
.tb-filters[aria-expanded="true"] { background: var(--veil-accent); color: var(--accent-strong); }
.tb-fbadge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px;
  background: var(--brand-gold-soft); color: var(--brand-gold-ink);
  border-radius: var(--radius-arc); font-family: var(--font-data);
  font-size: var(--type-micro); font-weight: 600; font-variant-numeric: tabular-nums;
}

.tb-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.tb-chips:empty { display: none; }
.tb-chip {
  display: inline-flex; align-items: center; gap: var(--space-2);
  background: var(--brand-gold-soft); border: 1px solid var(--border-accent-alt);
  color: var(--brand-gold-ink); border-radius: var(--radius-arc);
  padding: var(--space-1) var(--space-3); font-size: var(--type-micro); font-weight: 600;
}
.tb-chip button {
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 0; padding: 0; margin: 0; cursor: pointer;
  color: inherit; font-size: var(--type-caption); line-height: 1;
  transition: color var(--t-quick) var(--ease-cube);
}
.tb-chip button:hover, .tb-chip button:focus, .tb-chip button:active { color: var(--brand-ink); background: transparent; box-shadow: none; }
.tb-chip button:focus-visible { box-shadow: var(--focus-ring); }

/* === /assets/css/components/news.css === */
/* ------------------------------------------------------------
   Newsletter « Cercle du Cube » (news) — section de conversion de
   fin de page. PROMUE au registre le 10/07/2026 depuis la home
   (échafaudage `.ch-news` V2), valeurs brutes normalisées sur
   l'échelle de tokens. Vit dans une bande claire `fb-gold` (or
   champagne) juste avant le footer : c'est la DERNIÈRE section de
   chaque page (doctrine de fin de page 10/07 : jamais de section
   nuit collée au footer nuit ; l'or clair fait la transition).
   Anatomie : .ch-news (colonne centrée) > .badge · h3 · p · form
   (> input + .cta) · .rgpd. Formulaire réel = Brevo au build É4.
   Consommé par : fiche-pack-cgc.html · service-cgc.html · build É4
   (toutes les vues, doctrine de fin de page ; la maquette home garde
   sa copie locale — sources maquettes figées au jalon B).
   ------------------------------------------------------------ */
.ch-news { text-align: center; max-width: 620px; margin: 0 auto; }
/* badge à la voix de la bande or (retour 16 de F-ter-a, 12/07 : le
   « -5 % » doit parler aussi fort que le « -10 € » de la page service
   — même corps type-title, même boîte que .cgc-remband-badge) */
.ch-news .badge { display: inline-block; background: var(--brand-night); color: var(--brand-gold); font-family: var(--font-display); font-size: var(--type-title); line-height: 1; letter-spacing: .03em; padding: var(--space-3) var(--space-4); border-radius: var(--radius-s); margin-bottom: var(--space-4); box-shadow: var(--shadow-soft); }
.ch-news h3 { font-family: var(--font-display); font-weight: 400; font-size: var(--type-title); margin-bottom: var(--space-2); color: var(--brand-ink); letter-spacing: .02em; }
.ch-news p { color: var(--brand-ink); opacity: .75; font-size: var(--type-caption); margin-bottom: var(--space-5); }
.ch-news form { display: flex; gap: var(--space-3); max-width: 480px; margin: 0 auto; }
.ch-news input { flex: 1; min-width: 0; border: 1px solid var(--brand-gold-deep); background: var(--brand-paper); border-radius: var(--radius-m); padding: var(--space-3) var(--space-4); font-size: var(--type-caption); font-family: inherit; color: var(--brand-ink); }
.ch-news input::placeholder { color: var(--brand-ink-soft); }
.ch-news .rgpd { margin-top: var(--space-3); font-size: var(--type-micro); color: var(--brand-ink-soft); opacity: 1; }
.ch-news .cta { box-shadow: var(--shadow-cta); }

@media (max-width: 560px) { .ch-news form { flex-direction: column; } }

/* === /assets/css/chrome.css === */
/* ============================================================
   CHROME RÉEL DU SITE — Le Cube à Comics (É4 Bloc 2)
   Transporté de maquettes/assets/chrome.css (source unique É3,
   gatée avec home + PDP) le 09/07/2026, puis complété des parties
   que la maquette laissait « PROVISOIRE » pour l'É4 :
   menu WordPress (ul/li), dropdown Comic-Shop, menu mobile plein
   écran, barre de recherche, tiroir panier (fragments Woo).
   Adaptations du transport marquées [É4] en commentaire.
   Charge APRÈS tokens.css + components/cta.css.
   ============================================================ */

/* ---------- socle ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--font-body);
  font-size: var(--type-body);
  line-height: 1.6;
  color: var(--brand-ink);
  background: var(--brand-paper);
  -webkit-font-smoothing: antialiased;
  /* [É4] header fixé : le flux commence sous lui. Les pages à hero
     (bloc 3+) poseront body.ch-has-hero pour repasser dessous.
     --ch-notice-h (É4-f) = hauteur du bandeau promo fixé en haut,
     mesurée par chrome.js (0 sans bandeau) : flux et fixed la suivent. */
  padding-top: calc(var(--ch-head-h) + var(--ch-notice-h, 0px));
}
body.ch-has-hero { padding-top: var(--ch-notice-h, 0px); }
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; }
.wrap { max-width: var(--container); margin: 0 auto; padding: 0 24px; }
.data { font-family: var(--font-data); letter-spacing: .02em; }

/* [2.8 · retouche de gate 30/07] HAUTEUR DE LA BARRE, constante de
   plomberie nommée. Elle valait 64px en dur, recopiée dans 14 fichiers
   (compensations de flux, heros, sticky, scroll-margin) ; le lockup
   empilé officiel du header réclame 90px, et une constante recopiée ne
   se déplace pas d'un seul geste. Un seul foyer désormais :
   --ch-head-h = hauteur de la barre · --ch-logo-h = hauteur du lockup
   dedans (90 − 2×9 d'air optique). Sous 680px, la barre garde ses 64px :
   le montage mobile (cube + wordmark, retour Julien du 14/07) est
   inchangé, seul le desktop porte le lockup empilé.
   Toute déclaration qui dégage le header fixe lit --ch-head-h : pas de
   valeur de repli, une variable absente doit casser visiblement. */
body { --ch-head-h: 90px; --ch-logo-h: 72px; }
@media (max-width: 680px) { body { --ch-head-h: 64px; } }

/* [polissage header 30/07, verdict Julien] Au scroll, la barre s'amincit et la
   marque bascule sur le cube seul (la signature compacte, déjà celle du mobile).
   --ch-bar-h = hauteur VIVANTE de la barre (repli : --ch-head-h). Ne la lisent
   que la barre elle-même et ce qui s'accroche à son bord bas (panneau recherche,
   panneau mobile, toolbar boutique). Les offsets de mise en page (héros,
   scroll-margins, padding du body) restent sur --ch-head-h : le contenu ne
   bouge pas d'un pixel quand la barre respire. */
@media (min-width: 681px) {
  html[data-head='scrolled'] body { --ch-bar-h: 64px; }
}

/* [É4] décalage des éléments fixés quand la barre d'admin WP est là
   (le html est déjà poussé par WP ; seuls les fixed doivent suivre). */
body { --ch-notice-h: 0px; --ch-head-top: var(--ch-notice-h, 0px); }
body.admin-bar { --ch-head-top: calc(32px + var(--ch-notice-h, 0px)); }
@media (max-width: 782px) { body.admin-bar { --ch-head-top: calc(46px + var(--ch-notice-h, 0px)); } }

/* ---------- reveals V2 (« emboîtement ») ---------- */
/* reveal au scroll : via ANIMATION (pas transition) pour ne pas capter le survol
   des composants enfants — .pcard, .ch-ed, .ch-pillar gardent leur propre transition.
   fill: backwards = état caché pendant le delay du stagger, sans verrouiller le
   transform APRÈS l'animation (le hover reste libre). */
.reveal { opacity: 0; }
.reveal.in { opacity: 1; animation: reveal-up .7s ease backwards; }
.stagger > * { opacity: 0; }
.stagger.in > * { opacity: 1; animation: stagger-up .6s ease backwards; }
.stagger.in > *:nth-child(2) { animation-delay: .06s; }
.stagger.in > *:nth-child(3) { animation-delay: .12s; }
.stagger.in > *:nth-child(4) { animation-delay: .18s; }
.stagger.in > *:nth-child(5) { animation-delay: .24s; }
.stagger.in > *:nth-child(6) { animation-delay: .30s; }
.stagger.in > *:nth-child(7) { animation-delay: .36s; }
.stagger.in > *:nth-child(8) { animation-delay: .42s; }
@keyframes reveal-up { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
@keyframes stagger-up { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }

/* ---------- sections + sur-titres V2 ---------- */
.ch-section { padding: 92px 0; position: relative; }
.fb { position: relative; width: 100%; }
.fb-dark { background: linear-gradient(118deg, var(--brand-vault), var(--brand-midnight)); color: var(--brand-glow); }
.fb-dark::before { content: ''; position: absolute; inset: 0; pointer-events: none; background: var(--brand-night-spot); }
.fb-dark::after { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: var(--brand-giltline); opacity: .6; }
.fb-dark.ch-section { padding: 104px 0; }
.fb-paper { background: var(--brand-paper); border-top: 1px solid var(--brand-line); border-bottom: 1px solid var(--brand-line); }
.fb-bg { background: var(--brand-page); border-top: 1px solid var(--brand-line); border-bottom: 1px solid var(--brand-line); }
.fb-gold { background: var(--brand-newsprint); border-top: 1px solid var(--brand-gold-line); }
.fb > .wrap { position: relative; z-index: 1; }
.sec-head { margin-bottom: 42px; }
.sec-head.center { text-align: center; }
/* .eyebrow (surtitre + tiret or) est un composant du registre :
   components/eyebrow.css (transporté au bloc 3 avec sa première page).
   Restent ici ses adaptations de contexte chrome. */
.sec-head.center .eyebrow::before { display: none; }
.fb-dark .eyebrow { color: var(--brand-cube-light); }
h2.sec-t {
  font-family: var(--font-display); font-weight: 400;
  font-size: var(--type-title); letter-spacing: .02em; line-height: 1.02;
  margin-bottom: 10px; color: var(--brand-cube);
}
.fb-dark h2.sec-t { color: var(--text-inverse-strong); }
.sec-lead { font-size: var(--type-caption); color: var(--brand-ink-soft); max-width: 60ch; }
.fb-dark .sec-lead { color: var(--brand-dusk); }
.sec-head.center .sec-lead { margin: 14px auto 0; }

/* ---------- boutons : toute la famille vit au registre (components/cta.css
   pour la conversion, components/btn.css pour le service). Les ex-variantes
   chrome (.btn-ghost-light, .btn-blue, .btn-line) sont mortes à la passe de
   cohérence du 12/07 : .btn-blue est monté au registre, les deux filets ont
   fusionné en .btn-ghost. ---------- */

/* ---------- HEADER (V2 portée au réel) ---------- */
.cube-head { position: fixed; top: var(--ch-head-top); left: 0; right: 0; z-index: 1000; height: var(--ch-bar-h, var(--ch-head-h)); transition: background .28s ease, box-shadow .28s ease, height .28s ease; }
.cube-head::before { content: ''; position: absolute; inset: 0 0 -30px 0; z-index: -1; background: var(--brand-head-scrim); opacity: 1; transition: opacity .28s ease; pointer-events: none; }
.cube-head[data-state='scrolled'] { background: linear-gradient(180deg, var(--brand-night), var(--brand-midnight)); box-shadow: var(--shadow-bar); }
.cube-head[data-state='scrolled']::before { opacity: 0; }
/* [É4] sans hero sous le header (toute page tant que le bloc 3 n'a pas
   livré les pages à hero), le scrim n'a rien à voiler : header solide. */
body:not(.ch-has-hero) .cube-head { background: linear-gradient(180deg, var(--brand-night), var(--brand-midnight)); box-shadow: var(--shadow-bar); }
body:not(.ch-has-hero) .cube-head::before { opacity: 0; }
/* [É4] combinateur enfant : le header contient d'autres .wrap (barre de
   recherche) qui ne doivent pas hériter du flex de la rangée */
.cube-head > .wrap { height: 100%; display: flex; align-items: center; gap: 26px; }
/* [polissage header 30/07] Menu CENTRÉ dans la barre (verdict Julien : le logo
   étroit laissait tout le poids à gauche). Grille 1fr auto 1fr : logo à gauche,
   nav au centre optique de la barre, actions à droite. Mobile garde le flex. */
@media (min-width: 681px) {
  .cube-head > .wrap { display: grid; grid-template-columns: 1fr auto 1fr; }
  .cube-head .ch-logo { justify-self: start; }
  .cube-head .ch-nav { justify-self: center; margin-left: 0; flex: none; }
  .cube-head .ch-head-actions { justify-self: end; }
}
.ch-logo { display: flex; align-items: center; flex: 0 0 auto; }
/* [2.8 · retouche 30/07] le lockup empilé se lit à 72px de haut (mesuré :
   sous 60px les deux mots décrochent) ; sa largeur suit son ratio 0,73:1,
   soit ~53px — le bloc de marque du header est désormais étroit et haut.
   SÉLECTEUR PRÉFIXÉ .cube-head, obligatoire : Kadence charge son
   woocommerce.min.css APRÈS le CSS du child (bundle du combineur en
   position 5, woo en 7 — constaté au navigateur le 30/07), et sa règle
   « .woocommerce img { height: auto } » a la MÊME spécificité que
   « .ch-logo img » : à égalité, la dernière feuille gagne, et le lockup
   repartait à sa taille native (533×728 mesuré sur la PDP) sur toute page
   à classe woocommerce — PDP, boutique, panier, compte. Le dépôt connaît
   déjà le piège (tunnel-woo.css et compte-woo.css contrent pareil pour
   .cko-logo). Les deux règles suivantes sont montées d'un cran ensemble
   pour garder leur ordre interne (l'icône mobile doit rester au-dessus). */
.cube-head .ch-logo img { height: var(--ch-logo-h); width: auto; transition: height .28s ease; }
/* [décision Julien 30/07, définitive] UN SEUL logo dans toutes les barres : le
   lockup empilé officiel du client, à toutes les tailles. Au scroll il rétrécit
   avec la barre (90→64, logo 72→48), il ne cède la place à rien. */
@media (min-width: 681px) {
  .cube-head[data-state='scrolled'] .ch-logo img { height: 48px; }
}
/* wordmark mobile : le cube seul laissait le site anonyme sous 680px
   (retour Julien 14/07) — le nom en Bebas accompagne la marque, motif
   du lockup tunnel (cko-logo). Affiché par le bloc responsive, qui
   resserre aussi boîtes d'action et gouttières pour que le lockup
   nommé + 5 actions tiennent au mm près (budget constaté : 344/347px
   à 390 de viewport). */
/* [É4] la nav est un menu WordPress : le ul remplace la rangée de <a> nus
   de la maquette, mêmes géométrie et styles au niveau 1. */
.ch-nav { display: flex; align-items: center; margin-left: 6px; flex: 1 1 auto; min-width: 0; }
.ch-nav > ul { display: flex; align-items: center; gap: 24px; margin: 0; padding: 0; list-style: none; }
.ch-nav > ul > li { position: relative; display: flex; align-items: center; }
.ch-nav > ul > li > a { font-size: var(--type-caption); font-weight: 600; color: var(--brand-glow); position: relative; padding: 6px 0; white-space: nowrap; text-shadow: var(--shadow-text); transition: color .2s ease; }
.ch-nav > ul > li > a:hover { color: var(--text-inverse-strong); }
/* état actif : items de pages/taxonomies seulement (un item custom dont
   l'URL matche la page se marque aussi : piège gravé au run 1) */
.ch-nav > ul > li:not(.menu-item-type-custom).current-menu-item > a,
.ch-nav > ul > li:not(.menu-item-type-custom).current-menu-ancestor > a,
.ch-nav > ul > li:not(.menu-item-type-custom).current_page_parent > a { color: var(--text-inverse-strong); }
.ch-nav > ul > li:not(.menu-item-type-custom).current-menu-item > a::after,
.ch-nav > ul > li:not(.menu-item-type-custom).current-menu-ancestor > a::after,
.ch-nav > ul > li:not(.menu-item-type-custom).current_page_parent > a::after { content: ''; position: absolute; left: 0; right: 0; bottom: -2px; height: 2px; background: var(--brand-gold); border-radius: 2px; }
/* [É4] point or CGC : la classe vit sur le <li> du menu ; la spécificité
   (0,3,1) remplace les !important de la maquette (interdits au build) */
.ch-nav > ul > li.ch-nav-cgc > a { color: var(--brand-gold); font-weight: 700; display: inline-flex; align-items: center; gap: 6px; }
.ch-nav > ul > li.ch-nav-cgc > a::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--brand-gold); box-shadow: var(--glow-accent); }
.ch-nav > ul > li.ch-nav-cgc > a:hover { color: var(--brand-cube-light); }
.ch-head-actions { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; margin-left: auto; }
.ch-icn { width: 40px; height: 40px; padding: 0; display: flex; align-items: center; justify-content: center; color: var(--brand-glow); background: transparent; border: 0; border-radius: var(--radius-m); cursor: pointer; position: relative; transition: background .2s, color .2s; }
/* verrou des 3 états (passe de cohérence 12/07) : le parent peint les
   button:hover/:focus/:active — les icônes du chrome possèdent les leurs */
.ch-icn:hover, .ch-icn:focus, .ch-icn:active { background: var(--veil-accent-night); color: var(--text-inverse-strong); box-shadow: none; }
.ch-icn:focus-visible { box-shadow: var(--focus-ring); }
/* état actif du ♥ Favoris sur /wishlist/ (dû de gate F-ter-a) : cœur
   plein or, tenu aussi au survol (déclaré après le verrou des 3 états) */
.ch-icn.is-active { color: var(--brand-gold); }
.ch-icn.is-active svg { fill: currentColor; }
.ch-cart-count { position: absolute; top: 2px; right: 2px; min-width: 17px; height: 17px; padding: 0 4px; background: var(--brand-gold); color: var(--brand-midnight); font-size: var(--type-micro); font-weight: 700; line-height: 17px; text-align: center; border-radius: var(--radius-s); }
.ch-burger { display: none; flex-direction: column; gap: 4px; width: 42px; height: 42px; padding: 0; align-items: center; justify-content: center; background: transparent; border: 0; cursor: pointer; }
.ch-burger:hover, .ch-burger:focus, .ch-burger:active { background: transparent; box-shadow: none; }
.ch-burger:focus-visible { box-shadow: var(--focus-ring); }
.ch-burger span { width: 21px; height: 2px; background: var(--brand-glow); border-radius: 2px; transition: transform .25s, opacity .2s; }
.ch-burger[aria-expanded='true'] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.ch-burger[aria-expanded='true'] span:nth-child(2) { opacity: 0; }
.ch-burger[aria-expanded='true'] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* ---------- [É4] DROPDOWN Comic-Shop (desktop) ----------
   Nouveau à l'É4 (le plan de site le prescrit, la maquette one-page ne
   l'avait pas). Panneau nuit sous l'item ; « Autres éditeurs » = colonne 2
   (groupe non cliquable, url vide → <a> sans href, non focalisable).
   Cloisonné desktop : tout ce bloc vit sous min-width 981px, rien ne
   fuit vers le panneau mobile. Déclencheurs : survol + bouton caret
   (clic/clavier, aria-expanded) — le lien parent reste une vraie
   navigation vers /comic-shop/. */
.ch-sub-toggle { display: none; }
@media (min-width: 981px) {
  .ch-sub-toggle { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; padding: 0; margin-left: 2px; background: transparent; border: 0; border-radius: var(--radius-s); color: var(--brand-glow); cursor: pointer; transition: background .2s, color .2s, transform .2s; }
  .ch-sub-toggle:hover { color: var(--text-inverse-strong); background: var(--veil-accent-night); }
  .ch-sub-toggle svg { width: 12px; height: 12px; }
  .ch-sub-toggle[aria-expanded='true'] svg { transform: rotate(180deg); }
  .ch-nav .sub-menu { position: absolute; top: calc(100% + 14px); left: -22px; z-index: 1001; min-width: 230px; padding: 18px 24px 20px; margin: 0; list-style: none; background: linear-gradient(180deg, var(--brand-night), var(--brand-midnight)); border-radius: 0 0 var(--radius-m) var(--radius-m); box-shadow: var(--shadow-bar); opacity: 0; visibility: hidden; transform: translateY(6px); transition: opacity .18s ease, transform .18s ease, visibility .18s; display: grid; grid-template-columns: max-content; }
  .ch-nav .sub-menu::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: var(--brand-giltline); opacity: .6; }
  .ch-nav > ul > li:hover > .sub-menu,
  .ch-nav > ul > li.is-open > .sub-menu,
  .ch-nav > ul > li:focus-within > .sub-menu { opacity: 1; visibility: visible; transform: none; }
  /* pont invisible entre l'item et le panneau : le survol ne tombe pas
     dans le trou des 14px d'écart */
  .ch-nav > ul > li.menu-item-has-children::after { content: ''; position: absolute; left: 0; right: 0; top: 100%; height: 14px; }
  .ch-nav .sub-menu > li { grid-column: 1; }
  .ch-nav .sub-menu a { display: block; padding: 7px 0; font-size: var(--type-caption); font-weight: 500; color: var(--brand-dusk); white-space: nowrap; transition: color .18s, padding-left .18s; }
  .ch-nav .sub-menu a[href]:hover { color: var(--text-inverse-strong); padding-left: 4px; }
  .ch-nav .sub-menu .current-menu-item > a { color: var(--brand-gold); }
  /* l'entrée générale du dropdown (retour de gate F-ter-a, 12/07) : le
     parent cliquable ne se découvre pas — « Tout le catalogue » en tête,
     distinguée des rayons (graisse, encre vive, filet dessous) */
  .ch-nav .sub-menu > li.ch-sub-tout > a { font-weight: 600; color: var(--brand-glow); padding-bottom: 11px; margin-bottom: 6px; border-bottom: 1px solid var(--border-accent-night); }
  /* groupe « Autres éditeurs » : colonne 2 du panneau (span large : les
     entrées de la colonne 1 n'iront jamais au-delà) */
  .ch-nav .sub-menu > li.menu-item-has-children { grid-column: 2; grid-row: 1 / span 12; margin-left: 26px; padding-left: 26px; border-left: 1px solid var(--border-accent-night); }
  .ch-nav .sub-menu > li.menu-item-has-children > a { font-family: var(--font-data); font-size: var(--type-micro); font-weight: 500; letter-spacing: .1em; text-transform: uppercase; color: var(--brand-cube-light); cursor: default; padding-bottom: 9px; }
  /* visibility: inherit, jamais visible : un enfant `visible` dans le
     panneau `hidden` reste survolable (surface fantôme sous le header,
     bug attrapé le 23/07 : le dropdown s'ouvrait depuis la zone H1) */
  .ch-nav .sub-menu .sub-menu { position: static; opacity: 1; visibility: inherit; transform: none; display: block; min-width: 0; padding: 0; background: none; box-shadow: none; border-radius: 0; }
  .ch-nav .sub-menu .sub-menu::before { content: none; }
}

/* ---------- [É4] BARRE DE RECHERCHE (loupe du header) ----------
   V1 : recherche produits native (post_type=product), la mécanique S&F
   se branche à l'É4-e. Bandeau nuit sous le header. */
.ch-search { position: fixed; top: calc(var(--ch-bar-h, var(--ch-head-h)) + var(--ch-head-top)); left: 0; right: 0; z-index: 985; background: linear-gradient(180deg, var(--brand-night), var(--brand-midnight)); box-shadow: var(--shadow-bar); border-top: 1px solid var(--border-accent-night); opacity: 0; visibility: hidden; transform: translateY(-8px); transition: opacity .2s ease, transform .2s ease, visibility 0s linear .2s; }
.ch-search.open { opacity: 1; visibility: visible; transform: none; transition: opacity .2s ease, transform .2s ease, visibility 0s; }
.ch-search form { display: flex; gap: 12px; padding: 16px 0; }
.ch-search input[type='search'] { flex: 1 1 auto; min-width: 0; height: 48px; padding: 0 18px; background: var(--veil-accent-night); border: 1px solid var(--border-accent-night); border-radius: var(--radius-m); color: var(--text-inverse-strong); font-family: var(--font-body); font-size: var(--type-caption); }
.ch-search input[type='search']::placeholder { color: var(--brand-dusk); }
.ch-search input[type='search']:focus-visible { outline: 0; border-color: var(--brand-cube-light); box-shadow: var(--focus-ring); }
/* couleur + curseur épinglés à tous les états ((0,3,1) : le CSS
   dynamique Kadence passe après le child et peut gagner le focus à
   égalité (0,2,1)) ; autofill neutralisé — la saisie reste blanche en
   toute circonstance (retour Julien 14/07 : écriture bleue illisible) */
.ch-search input[type='search'] { caret-color: var(--brand-gold); }
.ch-search input[type='search']:focus, .ch-search input[type='search']:focus-visible { color: var(--text-inverse-strong); caret-color: var(--brand-gold); }
.ch-search input[type='search']:-webkit-autofill { -webkit-text-fill-color: var(--text-inverse-strong); caret-color: var(--brand-gold); transition: background-color 999999s; }
.ch-search .cta--field { height: 48px; }

/* ---------- [É4] MENU MOBILE PLEIN ÉCRAN ----------
   Standard du build (le panneau court de la maquette était provisoire) :
   fond opaque charte, liens aérés, CTA pleine largeur en bas, scroll du
   fond verrouillé (html.ch-nav-open), fermeture au passage desktop (JS). */
html.ch-nav-open { overflow: hidden; }
.ch-mobile { position: fixed; top: calc(var(--ch-bar-h, var(--ch-head-h)) + var(--ch-head-top)); left: 0; right: 0; bottom: 0; z-index: 990; display: none; flex-direction: column; overflow-y: auto; background: linear-gradient(180deg, var(--brand-night), var(--brand-midnight)); border-top: 1px solid var(--border-accent-night); padding: 10px 24px calc(24px + env(safe-area-inset-bottom, 0px)); }
.ch-mobile.open { display: flex; }
.ch-mobile ul { list-style: none; margin: 0; padding: 0; }
.ch-mobile > ul { flex: 1 1 auto; }
.ch-mobile > ul > li { border-bottom: 1px solid var(--border-accent-night); }
.ch-mobile > ul > li:last-child { border-bottom: 0; }
.ch-mobile li { display: block; }
/* lien + caret sur une ligne, sous-menu sur la ligne d'après */
.ch-mobile li.menu-item-has-children { display: flex; flex-wrap: wrap; align-items: center; }
.ch-mobile li.menu-item-has-children > a { flex: 1 1 auto; }
.ch-mobile li.menu-item-has-children > .sub-menu { flex-basis: 100%; }
/* :not(.cta) : le CTA « Tout le catalogue » du pied de menu est un
   composant — la recette générique des liens du menu (block, glow,
   padding 16/0) le dépouillait : texte glow sur or, débordant (retour
   18 de F-ter-a, prouvé au banc 390 le 12/07) */
.ch-mobile a:not(.cta) { display: block; padding: 16px 0; color: var(--brand-glow); font-size: var(--type-caption); font-weight: 600; }
.ch-mobile li.ch-nav-cgc > a { color: var(--brand-gold); font-weight: 700; }
/* accordéon Comic-Shop : bouton caret dédié, le lien navigue */
.ch-mobile .ch-sub-toggle { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 46px; height: 46px; padding: 0; background: transparent; border: 0; border-radius: var(--radius-m); color: var(--brand-glow); cursor: pointer; transition: transform .2s ease; }
.ch-mobile .ch-sub-toggle svg { width: 16px; height: 16px; }
.ch-mobile .ch-sub-toggle[aria-expanded='true'] { transform: rotate(180deg); }
.ch-mobile .sub-menu { display: none; margin: 0 0 12px; padding-left: 16px; border-left: 2px solid var(--border-accent-night); }
.ch-mobile li.is-open > .sub-menu { display: block; }
.ch-mobile .sub-menu a { padding: 11px 0; font-weight: 500; color: var(--brand-dusk); }
.ch-mobile .sub-menu a[href]:hover { color: var(--text-inverse-strong); }
/* groupe « Autres éditeurs » : titre de groupe + enfants toujours visibles */
.ch-mobile .sub-menu li.menu-item-has-children > a { font-family: var(--font-data); font-size: var(--type-micro); font-weight: 500; letter-spacing: .1em; text-transform: uppercase; color: var(--brand-cube-light); padding-bottom: 4px; }
.ch-mobile .sub-menu .sub-menu { display: block; margin: 0; }
.ch-mobile .cta { width: 100%; margin-top: 20px; flex: 0 0 auto; }

/* ---------- [É4] TIROIR PANIER (fragments Woo natifs) ----------
   Remplace le snippet « tiroir AJAX » du site actuel (décision tunnel 6
   du plan de site). Le commerce vit en clair : panneau papier. Le contenu
   est le mini-panier Woo (div.widget_shopping_cart_content, rafraîchi
   par wc-cart-fragments), habillé ici sur les tokens. */
.ch-scrim { position: fixed; inset: 0; z-index: 1100; background: var(--scrim-modal); opacity: 0; visibility: hidden; transition: opacity .24s ease, visibility 0s linear .24s; }
.ch-scrim.open { opacity: 1; visibility: visible; transition: opacity .24s ease, visibility 0s; }
/* top: 0 (pas var(--ch-head-top)) : le tiroir est une couche modale, il
   couvre aussi le bandeau promo — sinon le bandeau reste visible au-dessus,
   assombri par le scrim (bande noire attrapée au constat mobile 14/07) */
.ch-drawer { position: fixed; top: 0; right: 0; bottom: 0; z-index: 1110; width: min(420px, 92vw); display: flex; flex-direction: column; background: var(--brand-paper); box-shadow: var(--shadow-bar); transform: translateX(100%); visibility: hidden; transition: transform .28s var(--ease-cube), visibility 0s linear .28s; }
.ch-drawer.open { transform: none; visibility: visible; transition: transform .28s var(--ease-cube), visibility 0s; }
/* tête recomposée (F-bis 11/07, motif zintense) : titre à l'ENCRE (le
   bleu jurait — loi des 2 couleurs, le tiroir est une zone d'achat),
   compteur en pastille or (écho du badge panier du header), fermeture
   cerclée, respiration élargie */
.ch-drawer-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 20px 24px; border-bottom: 1px solid var(--brand-line); }
.ch-drawer-head h2 { display: flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 400; font-size: var(--type-price); letter-spacing: .04em; text-transform: uppercase; color: var(--brand-ink); }
.ch-drawer-head .ch-drawer-count { display: inline-flex; align-items: center; justify-content: center; min-width: 24px; height: 24px; padding: 0 7px; border-radius: 999px; background: var(--brand-gold); color: var(--brand-night); font-family: var(--font-data); font-size: var(--type-micro); font-weight: 600; letter-spacing: 0; }
/* spécificité 0,2,0 : des styles de bouton englobants (parent/plugins)
   passent après nous dans l'ordre des feuilles */
.ch-drawer .ch-drawer-close { display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; padding: 0; background: transparent; border: 1px solid var(--brand-line); border-radius: 50%; color: var(--brand-ink-soft); cursor: pointer; transition: background .2s, color .2s, border-color .2s; }
.ch-drawer .ch-drawer-close:hover, .ch-drawer .ch-drawer-close:focus, .ch-drawer .ch-drawer-close:active { background: var(--veil-accent); color: var(--brand-ink); border-color: var(--brand-ink-soft); box-shadow: none; }
.ch-drawer .ch-drawer-close:focus-visible { box-shadow: var(--focus-ring); }
/* Le corps ne scrolle plus en bloc (É4-f, référence zintense) : la liste
   d'articles défile seule, la barre de livraison reste en tête, le pied
   (sous-total + Commander) reste ancré en bas quel que soit le panier. */
.ch-drawer-body { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; overflow: hidden; padding: 0; }
.ch-drawer .widget_shopping_cart_content { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
/* barre « livraison offerte » native du child (remplace celle de Kadence
   Pro à l'É4-f, seuil lu de la config transporteur). Réassurance =
   registre or du DS (newsprint + filet or), progression en or. */
/* plus grande et aérée (retour de gate F : elle se lisait comme une
   note de bas de page — c'est un argument de vente, il se voit) */
.ch-drawer .ch-ship { flex: 0 0 auto; display: block; margin: 18px 24px 0; padding: 14px 16px; background: var(--brand-newsprint); border: 1px solid var(--brand-gold-line); border-radius: var(--radius-m); }
.ch-drawer .ch-ship-message { display: block; font-size: var(--type-caption); line-height: 1.5; color: var(--brand-ink); margin-bottom: 10px; }
.ch-drawer .ch-ship-message .woocommerce-Price-amount { font-family: var(--font-data); font-weight: 600; color: var(--price-ink); }
.ch-drawer .ch-ship-message.is-gagnee { color: var(--brand-ink); font-weight: 600; }
.ch-drawer .ch-ship-jauge { display: block; height: 8px; background: var(--brand-line); border-radius: var(--radius-s); overflow: hidden; }
.ch-drawer .ch-ship-avancee { display: block; height: 100%; background: var(--brand-gold); border-radius: var(--radius-s); }

/* habillage du markup mini-panier Woo, sur tokens */
/* paddings élargis à 24 + clairance de la colonne droite (retour de
   gate F : prix et croix collés au bord) */
.ch-drawer ul.woocommerce-mini-cart { list-style: none; flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; margin: 0; padding: 4px 24px 12px; }
.ch-drawer li.woocommerce-mini-cart-item { display: grid; grid-template-columns: 58px 1fr; gap: 14px; align-items: start; padding: 14px 0; margin: 0; border-bottom: 1px solid var(--brand-line); position: relative; }
/* boîte cover FIXE (ratio comic) : une image cassée n'étire jamais la
   rangée — même durcissement que .ch-run-cover.
   Spécificité (0,3,3) NÉCESSAIRE (retour de gate F-bis : « deux paniers
   selon la page ») : sur les gabarits Woo, l'ancêtre .woocommerce arme
   la règle Kadence ul.product_list_widget li img (float:left, 50px) à
   (0,2,3), qui battait la version courte de cette règle — le tiroir
   changeait de visage entre vitrines et boutique/fiche. */
.ch-drawer ul.woocommerce-mini-cart li.woocommerce-mini-cart-item img { display: block; float: none; width: 58px; height: 87px; margin: 0; object-fit: cover; overflow: hidden; border-radius: var(--radius-s); border: 1px solid var(--brand-line); grid-column: 1; grid-row: 1 / span 2; }
.ch-drawer li.woocommerce-mini-cart-item > a:not(.remove) { grid-column: 2; font-size: var(--type-caption); font-weight: 600; color: var(--brand-cube-deep); line-height: 1.35; padding-right: 36px; }
.ch-drawer li.woocommerce-mini-cart-item a.remove { position: absolute; top: 14px; right: 2px; width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; border-radius: 50%; font-size: var(--type-body); line-height: 1; color: var(--brand-ink-soft); border: 1px solid var(--brand-line); transition: color .18s, border-color .18s; }
.ch-drawer li.woocommerce-mini-cart-item a.remove:hover { color: var(--state-alert); border-color: var(--state-alert); }
/* [lot 9-12, 03/09/2026] données de ligne (`wc_get_formatted_cart_item_data`)
   — sur les packs CGC, « CGV service CGC : acceptées ». Woo les sort en
   <dl class="variation"> DIRECTEMENT sous le <li> ; sans placement, la
   grille les rangeait toute seule en COLONNE 1 (la boîte cover, 58px),
   où le <dt> déborde vers la droite et tombe SUR les contrôles de
   quantité (mesuré à 390×820, tiroir ouvert : dt 98→145 px contre bouton
   « − » 112→138 px, chevauchement de 26 px). Elles rejoignent la colonne
   de contenu, sous le nom et au-dessus des quantités, en flex qui
   retourne à la ligne — un libellé long ne recouvre plus rien. */
.ch-drawer li.woocommerce-mini-cart-item > dl.variation { grid-column: 2; display: flex; flex-wrap: wrap; gap: 0 .35em; min-width: 0; margin: 4px 0 0; padding: 0; font-family: var(--font-body); font-size: var(--type-micro); line-height: 1.45; color: var(--brand-ink-soft); overflow-wrap: anywhere; }
.ch-drawer li.woocommerce-mini-cart-item > dl.variation dt { float: none; clear: none; min-width: 0; margin: 0; padding: 0; font-weight: 600; }
.ch-drawer li.woocommerce-mini-cart-item > dl.variation dd { min-width: 0; margin: 0; padding: 0; }
.ch-drawer li.woocommerce-mini-cart-item > dl.variation dd p { margin: 0; }
/* quantités pilotées (filtre child) : − n + à gauche, prix de ligne à
   droite ; une pièce unique s'annonce comme telle, sans steppers */
.ch-drawer .ch-qty, .ch-drawer .ch-qty-fixe { grid-column: 2; display: flex; align-items: center; gap: 10px; font-family: var(--font-data); font-size: var(--type-micro); color: var(--brand-ink-soft); }
.ch-drawer .ch-qty-btn { display: flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; background: transparent; border: 1px solid var(--brand-line); border-radius: 50%; color: var(--brand-ink); font-size: var(--type-caption); line-height: 1; cursor: pointer; transition: border-color .18s, color .18s; }
.ch-drawer .ch-qty-btn:hover:not(:disabled), .ch-drawer .ch-qty-btn:focus:not(:disabled), .ch-drawer .ch-qty-btn:active:not(:disabled) { border-color: var(--accent); color: var(--accent-strong); background: transparent; box-shadow: none; }
.ch-drawer .ch-qty-btn:focus-visible { box-shadow: var(--focus-ring); }
.ch-drawer .ch-qty-btn:disabled { opacity: .35; cursor: default; }
.ch-drawer .ch-qty-n { min-width: 18px; text-align: center; font-size: var(--type-caption); color: var(--brand-ink); }
.ch-drawer .ch-qty-prix { margin-left: auto; font-weight: 600; color: var(--price-ink); }
.ch-drawer .ch-qty-prix .woocommerce-Price-amount { font-family: var(--font-data); }
/* « la suite du run » : l'upsell entre la liste et le sous-total (le
   hook Woo le rend après le total, l'ordre flex le remonte — les
   enfants du flex portent chacun leur ordre explicite ci-dessous) */
.ch-drawer .ch-ship { order: 1; }
.ch-drawer ul.woocommerce-mini-cart { order: 2; }
.ch-drawer .ch-run { order: 3; }
.ch-drawer .woocommerce-mini-cart__total { order: 4; }
.ch-drawer .woocommerce-mini-cart__buttons { order: 5; }
.ch-drawer .ch-drawer-lien-panier { order: 6; }
.ch-drawer .ch-run { flex: 0 0 auto; margin: 12px 24px 0; padding: 12px 14px 6px; background: var(--brand-paper); border: 1px solid var(--brand-line); border-radius: var(--radius-m); }
.ch-drawer .ch-run-titre { margin: 0 0 4px; font-size: var(--type-micro); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--brand-ink-soft); }
.ch-drawer .ch-run ul { list-style: none; margin: 0; padding: 0; }
.ch-drawer .ch-run li { display: grid; grid-template-columns: 34px minmax(0, 1fr) 30px; gap: 10px; align-items: center; padding: 8px 0; }
.ch-drawer .ch-run li + li { border-top: 1px solid var(--brand-line); }
/* boîte cover FIXE (34×51, ratio comic) : une image cassée (banc, 404)
   n'étire jamais la rangée — l'alt reste enfermé dans la boîte */
.ch-drawer .ch-run-cover { display: block; width: 34px; height: 51px; overflow: hidden; border-radius: var(--radius-s); border: 1px solid var(--brand-line); }
.ch-drawer .ch-run-cover img { width: 100%; height: 100%; object-fit: cover; border: 0; }
.ch-drawer .ch-run-infos { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.ch-drawer .ch-run-infos > a { font-size: var(--type-micro); font-weight: 600; color: var(--brand-cube-deep); line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ch-drawer .ch-run-prix { font-family: var(--font-data); font-size: var(--type-micro); font-weight: 600; color: var(--price-ink); }
.ch-drawer .ch-run-add { display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50%; background: var(--cta-bg); color: var(--cta-text); font-size: var(--type-caption); font-weight: 600; line-height: 1; box-shadow: var(--shadow-cta); transition: background var(--t-quick) var(--ease-cube); }
.ch-drawer .ch-run-add:hover { background: var(--cta-bg-hover); }
.ch-drawer .ch-run-add.loading { opacity: .5; pointer-events: none; }
/* [lot 9-12 · décision Julien D1, 03/09/2026] « Complétez votre run » :
   DEUX suggestions sur ordinateur, UNE seule sur mobile (le tiroir n'a
   pas la hauteur à 390 : la seconde poussait le sous-total et le bouton
   Commander sous la ligne de flottaison). Le HTML garde les deux et le
   point de rupture mobile du chrome (680px, celui du header et du pied)
   masque la seconde : le tiroir est servi depuis le cache de page puis
   rafraîchi par les fragments Woo, une détection serveur du mobile y
   serait fausse un chargement sur deux. `display:none` sort aussi la
   rangée de l'ordre de tabulation — pas de lien fantôme au clavier. */
@media (max-width: 680px) {
  .ch-drawer .ch-run li:nth-child(n + 2) { display: none; }
}

/* pied ancré : sous-total + l'adjudication, bordés du filet, toujours
   visibles — le grand vide sous les CTA du Bloc 2 disparaît */
.ch-drawer .woocommerce-mini-cart__total { flex: 0 0 auto; display: flex; justify-content: space-between; align-items: baseline; margin: 0; padding: 16px 24px 0; border-top: 1px solid var(--brand-line); font-size: var(--type-caption); color: var(--brand-ink); }
.ch-drawer .woocommerce-mini-cart__total .woocommerce-Price-amount { font-family: var(--font-data); font-size: var(--type-price-s); font-weight: 600; color: var(--price-ink); }
/* [lot 9-12 · décision Julien D2, 03/09/2026] la mention PayPal « payez
   en 4 fois » sort du TIROIR, et de lui seul : elle reste sur la fiche
   produit, la page panier et la commande (gabarit tunnel, sans tiroir).
   Le réglage natif de l'extension (Pay Later Message → Mini Cart →
   Enabled) est DÉJÀ à « non » des deux côtés, et ne suffit pas : son
   script instancie le message du mini-panier dès que
   `.woocommerce-mini-cart__total` existe dans la page
   (`paylater-messages.js` : `minicartEnabled || document.querySelector(…)`),
   puis, faute d'emplacement configuré, le rend DANS ce sous-total —
   marqueur `data-pp-id` sur le <p>, nœud `span[id^="zoid-paypal-message-"]`
   dedans (constaté sur la prod le 03/09). On masque ce seul nœud. */
.ch-drawer .woocommerce-mini-cart__total > span[id^="zoid-paypal-message-"],
.ch-drawer .wc-ppcp-minicart-msg__container,
.ch-drawer #wc-ppcp-minicart-msg { display: none !important; }
.ch-drawer .woocommerce-mini-cart__buttons { flex: 0 0 auto; display: flex; flex-direction: column; gap: 0; margin: 0; padding: 14px 24px 4px; }
/* un seul geste fort : Commander = l'adjudication (grammaire du .cta) */
.ch-drawer .woocommerce-mini-cart__buttons a.button.checkout { display: inline-flex; align-items: center; justify-content: center; width: 100%; background: var(--cta-bg); color: var(--cta-text); border: 0; border-radius: var(--radius-m); font-family: var(--font-display); font-weight: 400; font-size: var(--type-price-s); letter-spacing: .04em; text-transform: uppercase; box-shadow: var(--shadow-cta); padding: 15px 22px; transition: background var(--t-quick) var(--ease-cube); }
.ch-drawer .woocommerce-mini-cart__buttons a.button.checkout:hover { background: var(--cta-bg-hover); }
.ch-drawer .ch-drawer-lien-panier { display: block; flex: 0 0 auto; text-align: center; padding: 0 24px 18px; font-size: var(--type-micro); color: var(--brand-ink-soft); text-decoration: underline; text-underline-offset: 3px; }
.ch-drawer .ch-drawer-lien-panier:hover { color: var(--brand-cube); }
.ch-drawer .woocommerce-mini-cart__empty-message { padding: 26px 24px; text-align: center; font-size: var(--type-caption); color: var(--brand-ink-soft); }
/* mise à jour en vol : le contenu s'estompe, aucun clic ne double */
.ch-drawer.ch-busy .widget_shopping_cart_content { opacity: .55; pointer-events: none; transition: opacity .15s; }

/* ---------- VERROU DU TIROIR (F-bis 11/07) ---------- */
/* Le tiroir vit dans le footer : sur les gabarits Woo, l'ancêtre
   .woocommerce arme les règles du parent ET de Woo core (croix rouge
   à !important, retraits de product_list_widget), invisibles sur les
   vitrines — d'où « deux paniers selon la page ». Ce bloc scelle les
   propriétés contestées à l'ID (1,x,x) : aucune chaîne de classes ne
   passera au-dessus, le tiroir a UN visage. Les !important répondent
   à ceux de Woo core, ils ne s'étendent pas au-delà. */
#chDrawer ul.woocommerce-mini-cart { list-style: none !important; margin: 0 !important; padding: 12px 24px 12px !important; }
#chDrawer li.woocommerce-mini-cart-item { list-style: none !important; margin: 0 !important; padding: 16px 0 !important; border-bottom: 1px solid var(--brand-line); }
#chDrawer li.woocommerce-mini-cart-item img { float: none !important; width: 58px !important; height: 87px !important; margin: 0 !important; }
#chDrawer li.woocommerce-mini-cart-item a.remove { color: var(--brand-ink-soft) !important; background: transparent !important; width: 26px !important; height: 26px !important; font-size: var(--type-body) !important; line-height: 1 !important; border: 1px solid var(--brand-line) !important; border-radius: 50% !important; }
#chDrawer li.woocommerce-mini-cart-item a.remove:hover { color: var(--state-alert) !important; border-color: var(--state-alert) !important; background: transparent !important; }

/* ---------- BANDEAU PROMO (store notice Woo, É4-f) ---------- */
/* La bande BIENVENUE10 quitte le bas d'écran (elle recouvrait le pied du
   tiroir de filtres mobile et le contenu du checkout) : bandeau fin
   STATIQUE au-dessus du header — rendu au wp_body_open du child —, nuit
   et or, quel que soit le placement réglé côté Kadence (son fixed bottom
   est neutralisé). Retiré du tunnel par le filtre child. */
/* !important assumés : le CSS dynamique Kadence (customizer) passe après
   les feuilles du child et peint position + fond, il faut le gagner.
   Fixé en haut, hauteur mesurée par chrome.js (--ch-notice-h) : le
   header et le flux descendent d'autant, rien n'est recouvert. */
/* spécificité (0,2,1) assumée : la règle « placement bottom » de Kadence
   (.kadence-store-notice-placement-bottom .woocommerce-store-notice)
   porte top:auto !important à (0,2,0), il faut la battre */
/* bande OR, texte NUIT (retour de gate F 10/07 : la version nuit était
   trop discrète et ses deux bleus juraient avec le header — l'or tranche
   net au-dessus de la bande nuit du header, night/gold 10.8:1) */
/* voix de LABEUR imposée (retour de gate F-bis : le bandeau héritait de
   la Bebas condensée du chrome — illisible en petit corps) : Inter 600.
   Corps CAPTION 14 px (retour de gate F-ter-a 12/07 : le 17 px, posé
   quand le problème était la Bebas, criait — en Inter le 14 est net ;
   ne pas remonter, ne pas redescendre : l'illisibilité de F-bis venait
   de la police, pas du corps) ; mobile resserré (padding + Ignorer). */
body .woocommerce-store-notice.demo_store { position: fixed !important; top: 0 !important; left: 0 !important; right: 0 !important; bottom: auto !important; z-index: 1010; display: block; margin: 0; padding: 9px 20px; background: var(--brand-gold) !important; color: var(--brand-night) !important; font-family: var(--font-body); font-size: var(--type-caption); font-weight: 600; letter-spacing: 0; text-transform: none; text-align: center; line-height: 1.45; box-shadow: none; }
body.admin-bar .woocommerce-store-notice.demo_store { top: 32px !important; }
@media (max-width: 782px) { body.admin-bar .woocommerce-store-notice.demo_store { top: 46px !important; } }
body .woocommerce-store-notice.demo_store .woocommerce-store-notice__dismiss-link { color: var(--brand-night) !important; float: none; display: inline-block; margin: 0 0 0 14px; padding: 2px 12px; border: 1px solid var(--brand-night); border-radius: var(--radius-s); font-family: var(--font-body); font-size: var(--type-caption); font-weight: 600; text-transform: none; letter-spacing: 0; text-decoration: none; white-space: nowrap; transition: background .18s; }
@media (max-width: 680px) {
  body .woocommerce-store-notice.demo_store { padding: 7px 14px; line-height: 1.4; }
  /* padding vertical 4px (F34, 06/08/2026) : à 390 le « Ignorer » tombait
     à 23 px de haut, sous le confort au doigt de 24 px. Le bandeau grandit
     de 4 px, rien d'autre ne bouge. */
  body .woocommerce-store-notice.demo_store .woocommerce-store-notice__dismiss-link { font-size: var(--type-micro); padding: 4px 10px; margin-left: 10px; }
}
body .woocommerce-store-notice.demo_store .woocommerce-store-notice__dismiss-link:hover { background: var(--brand-gold-deep); }
body.kadence-store-notice-placement-bottom { padding-bottom: 0; }

/* ---------- notices Woo (message / info / erreur), F-bis ---------- */
/* le bleu brut du thème parent sort du tunnel : chip newsprint à filet
   or (le langage des encarts du DS), l'erreur parle alerte. Le bouton
   embarqué (« Voir le panier ») = secondaire du DS. */
body .woocommerce-message,
body .woocommerce-info { display: flex; align-items: center; justify-content: space-between; gap: 14px; background: var(--brand-newsprint); border: 1px solid var(--brand-line); border-left: 3px solid var(--brand-gold); border-radius: var(--radius-m); color: var(--brand-ink); font-size: var(--type-caption); padding: 12px 16px; margin: 0 0 14px; }
body .woocommerce-error { background: var(--brand-newsprint); border: 1px solid var(--brand-line); border-left: 3px solid var(--state-alert); border-radius: var(--radius-m); color: var(--brand-ink); font-size: var(--type-caption); padding: 12px 16px; margin: 0 0 14px; }
body .woocommerce-error li { margin: 4px 0; }
body .woocommerce-message a.button,
body .woocommerce-info a.button { order: 2; flex: 0 0 auto; background: var(--surface-raised); color: var(--accent-strong); border: 1.5px solid var(--accent); border-radius: var(--radius-m); padding: 8px 16px; font-weight: 600; font-size: var(--type-micro); transition: background var(--t-quick) var(--ease-cube); }
body .woocommerce-message a.button:hover,
body .woocommerce-info a.button:hover { background: var(--veil-accent); }

/* ---------- FOOTER V2 ---------- */
.cube-foot { background: var(--brand-footer-night); color: var(--brand-glow); }
.cf-reassure { border-bottom: 1px solid var(--border-accent-night); }
.cf-reassure .wrap { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; padding-top: 22px; padding-bottom: 22px; }
.cf-re { display: flex; align-items: center; justify-content: center; gap: 10px; font-size: var(--type-micro); color: var(--brand-glow); }
.cf-re svg { color: var(--icon-inverse); flex: 0 0 auto; }
.cf-main { padding: 54px 0 42px; }
.cf-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.4fr; gap: 40px; }
/* [2.8 · retouche de gate 30/07] le footer porte le lockup empilé COMPLET
   (badge CGC intégré, ratio 0,65:1). Le badge CGC autonome qui vivait sous
   la note Google est retiré, sa certification est dans le logo.
   90px de large → ~138px de haut (verdict Julien 30/07 : le 200px servi
   au premier re-gate écrasait la colonne). */
.cf-logo img { width: 90px; max-width: 100%; height: auto; }
.cf-tag { color: var(--brand-dusk); font-size: var(--type-micro); line-height: 1.6; margin: 14px 0 18px; max-width: 36ch; }
.cf-rate { font-size: var(--type-micro); color: var(--brand-glow); }
.cf-rate b { color: var(--brand-gold); font-size: var(--type-caption); }
.cf-rate .stars { color: var(--brand-gold-deep); letter-spacing: 2px; }
.cf-grid h4 { font-family: var(--font-display); font-weight: 400; font-size: var(--type-price-s); letter-spacing: .06em; color: var(--text-inverse-strong); margin-bottom: 16px; text-transform: uppercase; }
/* [É4] les colonnes de liens sont des menus WordPress (ul/li) */
.cf-col ul { list-style: none; margin: 0; padding: 0; }
/* :not(.btn-ico) : les carrés RS vivent dans la colonne adresse — la
   recette générique des liens de colonne (display block, dusk, padding)
   volait le composant (0-1-1 bat 0-1-0, attrapé au banc 12/07) */
.cf-col a:not(.btn-ico) { display: block; color: var(--brand-dusk); font-size: var(--type-caption); padding: 6px 0; transition: color .18s, padding-left .18s; }
.cf-col a:not(.btn-ico):hover { color: var(--text-inverse-strong); padding-left: 4px; }
/* [É4] classe posée sur le <li> du menu : spécificité (0,3,1), plus de !important */
.cf-col li.cf-col-cgc > a { color: var(--brand-gold); font-weight: 700; }
.cf-col li.cf-col-cgc > a:hover { color: var(--brand-cube-light); }
.cf-addr, .cf-hours { font-size: var(--type-micro); line-height: 1.7; color: var(--brand-dusk); margin-bottom: 14px; }
.cf-addr strong { color: var(--text-inverse-strong); }
/* les icônes RS = .btn-ico du registre en contexte nuit (data-theme posé
   au markup) ; le conteneur ne garde que la mise en rang */
.cf-social { display: flex; gap: 10px; margin-top: 6px; }
.cf-legal { border-top: 1px solid var(--border-accent-night); }
.cf-legal .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding-top: 18px; padding-bottom: 18px; flex-wrap: wrap; }
.cf-legal span { font-size: var(--type-micro); color: var(--brand-dusk); }
.cf-legal span a { color: var(--brand-cube-light); }
.cf-legal nav ul { display: flex; gap: 20px; flex-wrap: wrap; list-style: none; margin: 0; padding: 0; }
.cf-legal nav a { font-size: var(--type-micro); color: var(--brand-dusk); transition: color .18s; }
.cf-legal nav a:hover { color: var(--text-inverse-strong); }

.ch-icn svg, .ch-burger svg, .ch-sub-toggle svg, .ch-drawer-close svg { flex: 0 0 auto; }

/* ---------- accessibilité : lien d'évitement ---------- */
.skip-link { position: absolute; top: -100px; left: 16px; z-index: 1200; padding: 12px 18px; background: var(--brand-midnight); color: var(--text-inverse-strong); border-radius: var(--radius-m); font-weight: 600; }
.skip-link:focus { top: calc(12px + var(--ch-head-top)); }

/* ---------- responsive du chrome ---------- */
@media (max-width: 1000px) {
  .cf-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 980px) {
  .ch-nav { display: none; }
  .ch-burger { display: flex; }
}
@media (max-width: 880px) {
  .cf-reassure .wrap { grid-template-columns: 1fr 1fr; gap: 14px; }
}
@media (max-width: 680px) {
  .cf-grid { grid-template-columns: 1fr; gap: 28px; }
  .cf-legal .wrap { flex-direction: column; align-items: flex-start; }
  /* [décision Julien 30/07] mobile aussi : le lockup empilé officiel,
     réduit à la barre de 64px. Cube seul et wordmark retirés du header. */
  .cube-head .ch-logo img { height: 48px; }
  /* place pour le nom : boîtes d'action 36px (pictogramme 20px
     inchangé), gaps et gouttières du wrap au strict — sans quoi le
     burger sortait de l'écran à 390 (constat Playwright 14/07) */
  .cube-head > .wrap { gap: 12px; padding-left: 14px; padding-right: 14px; }
  .cube-head .ch-icn { width: 36px; height: 36px; }
  .cube-head .ch-burger { width: 36px; height: 36px; }
  .cube-head .ch-head-actions { gap: 3px; }
}
@media (max-width: 400px) {
  /* très petits écrans (360-390) : un cran plus serré, constaté 313/317px */
  .cube-head > .wrap { gap: 8px; }
  .cube-head .ch-icn { width: 34px; height: 34px; }
  .cube-head .ch-burger { width: 34px; height: 34px; }
  .cube-head .ch-head-actions { gap: 2px; }
}
@media (max-width: 520px) {
  .cf-reassure .wrap { grid-template-columns: 1fr; }
}

/* === /assets/css/favoris-icone.css === */
/* ------------------------------------------------------------
   [lot 9 · item 7 · séance Bruno 21/08]
   Le cœur des favoris passe de l'icône par défaut du plugin à
   celle de la DA du site.

   CE QUI ÉTAIT LÀ. TI WooCommerce Wishlist 2.11.1 dessine son cœur
   avec une POLICE D'ICÔNES : `tinvwl-webfont`, un glyphe posé en
   `content: "\e909"` sur `.tinvwl-icon-heart-plus::before` (relevé au
   navigateur : `font-family: tinvwl-webfont`, `font-size: 20px`). Un
   cœur bombé, plein, avec un « + » collé — étranger au trait fin et
   régulier des icônes du site.

   CE QUI LE REMPLACE. Le tracé de cœur CANONIQUE du thème, celui aussi
   servi par le header (`header.php`, icône Favoris), le menu du compte
   (`inc/compte.php`, entrée `wishlist`) et la page Favoris vide
   (`inc/wishlist.php`) — même `viewBox 0 0 24 24`, même `fill: none`,
   même trait. Une seule et même main sur tout le site.

   [lot 9 · item 7-bis · retour Bruno via Julien, 26/08] Ce tracé canonique
   a lui-même changé. L'ancien était dessiné à main levée et n'était pas
   symétrique — lobe gauche plus petit et plus bas, échancrure et pointe
   décalées à gauche de l'axe médian (constat 07bis-traces-avant-apres.png,
   axe posé sur les deux tracés). Bruno le trouvait « bizarre et déformé »,
   et il l'était : c'est le cœur Lucide « heart » (licence MIT) qui prend
   sa place, aux QUATRE foyers en même temps, pour que « une seule main »
   reste vrai. `stroke-linejoin='round'` dans les masques n'est pas
   décoratif : en jointure miter, le sommet bas de ce tracé sort en pointe
   acérée (constat 07bis-essai-jointures.png).

   COMMENT. `mask-image` sur un SVG en data-URI, pas `content: url(…)` :
   le masque laisse `background-color: currentColor` peindre l'icône, donc
   elle suit la couleur de son contexte — dont l'or de l'état « déjà en
   favori » que `sections/single-product.css` (l. 130) pose déjà sur
   `.tinvwl-product-in-list`. Un `content: url()` aurait figé la couleur
   dans le fichier et il aurait fallu deux images.

   SPÉCIFICITÉ. La règle du plugin est en (0,3,1)
   (`.tinv-wishlist .tinvwl_add_to_wishlist_button.tinvwl-icon-heart-plus::before`).
   Le sélecteur ci-dessous ajoute le type `a` → (0,3,2) : il gagne même si
   l'ordre des feuilles change (aujourd'hui le paquet du child est en
   position 5, le plugin en 3 — mais Kadence s'imprime encore après, en 7,
   et le dépôt connaît déjà ce piège, cf. chrome.css § .cube-head .ch-logo img).

   ÉTAT « EN FAVORI ». Le cœur devient PLEIN (le même tracé, rempli au
   lieu d'être tracé) : la différence se voit sans dépendre de la seule
   couleur — condition d'accessibilité, et lisible sur la bande nuit.
   ------------------------------------------------------------ */

.tinv-wishlist a.tinvwl_add_to_wishlist_button.tinvwl-icon-heart::before,
.tinv-wishlist a.tinvwl_add_to_wishlist_button.tinvwl-icon-heart-plus::before,
.tinv-wishlist button.tinvwl_add_to_wishlist_button.tinvwl-icon-heart::before,
.tinv-wishlist button.tinvwl_add_to_wishlist_button.tinvwl-icon-heart-plus::before {
  content: '';
  display: inline-block;
  width: 20px;
  height: 20px;
  vertical-align: -4px;
  background-color: currentColor;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z'/%3E%3C/svg%3E");
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
}

/* Déjà en favori : le même cœur, plein. */
.tinv-wishlist a.tinvwl_add_to_wishlist_button.tinvwl-product-in-list::before,
.tinv-wishlist button.tinvwl_add_to_wishlist_button.tinvwl-product-in-list::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z'/%3E%3C/svg%3E");
}

/* === /assets/css/sections/newsletter.css === */
/* ------------------------------------------------------------
   Section newsletter — le cercle du Cube, bande champagne (le fond
   .fb-gold vit dans chrome.css).
   Le TRONC .ch-news vit désormais au registre transporté
   (assets/css/components/news.css, promu le 10/07/2026 — doctrine
   de fin de page : la newsletter clôt toutes les pages, chargée ici
   avec les vagues composants). Cette feuille ne garde que la part
   réelle de SECTION : l'adaptation du formulaire Kadence embarqué
   par ID (.ch-news-form), les mêmes gestes que le formulaire de la
   maquette appliqués au markup du plugin.
   ------------------------------------------------------------ */

/* ------------------------------------------------------------
   Formulaire Kadence embarqué par ID (parties réelles É4) : le bloc
   arrive avec les couleurs de son éditeur (fond noir, bouton bleu)
   et sa grille 3 colonnes ; on le ramène aux gestes de la maquette,
   sur les tokens. Spécificité 0,4,x : les styles générés par bloc
   (kadence_blocks_css inline) et les mods boutons du thème s'impriment
   après le child et montent à 0,3,x (cicatrice run 1 : plugins de
   blocs) — on les bat à la spécificité, jamais au !important.
   ------------------------------------------------------------ */
.ch-news .ch-news-form { max-width: 480px; margin: 0 auto; }
.ch-news .ch-news-form .kb-advanced-form { display: block; max-width: none; }
.ch-news .ch-news-form .kb-advanced-form .kb-row-layout-wrap { padding: 0; }
.ch-news .ch-news-form .kb-advanced-form .kt-row-column-wrap { display: flex; flex-wrap: wrap; gap: 12px; align-items: stretch; padding: 0; }
.ch-news .ch-news-form .kb-advanced-form .wp-block-kadence-column { margin: 0; min-width: 0; }
.ch-news .ch-news-form .kb-advanced-form .wp-block-kadence-column:nth-child(1) { flex: 1 1 220px; }
.ch-news .ch-news-form .kb-advanced-form .wp-block-kadence-column:nth-child(2) { flex: 0 0 auto; }
.ch-news .ch-news-form .kb-advanced-form .wp-block-kadence-column:nth-child(3) { flex: 1 1 100%; }
.ch-news .ch-news-form .kb-advanced-form .kt-inside-inner-col { padding: 0; display: block; }
.ch-news .ch-news-form .kb-advanced-form .kb-adv-form-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* :not(.kb-checkbox-field) : la case de consentement porte AUSSI la
   classe kb-field — sans l'exclusion elle recevait la boîte du champ
   texte (34×37 px mesurés, retour de gate B du 10/07) */
.ch-news .ch-news-form .kb-advanced-form input.kb-field:not(.kb-checkbox-field) { background: var(--brand-paper); border: 1px solid var(--brand-gold-deep); border-radius: var(--radius-m); padding: 14px 16px; font-size: var(--type-caption); font-family: inherit; color: var(--brand-ink); width: 100%; height: 100%; }
.ch-news .ch-news-form .kb-advanced-form input.kb-field:not(.kb-checkbox-field)::placeholder { color: var(--brand-ink-soft); }
/* le formulaire est en labels FLOTTANTS Kadence : le plugin éteint le
   placeholder hors focus (opacity 0, style-blocks-advanced-form.css)
   parce que son label est censé flotter dans le champ — or le nôtre est
   sr-only. On rallume le placeholder (F-bis 11/07, champ muet constaté) */
.ch-news .ch-news-form .kb-adv-form-label-style-float input:placeholder-shown:not(:focus)::placeholder { opacity: 1; }
/* le bouton porte la grammaire .cta du DS (F-bis 11/07 : la règle du
   transport Bloc 3 l'écrasait en labeur 14 px « S'inscrire » — trahison
   de la maquette, dont le bloc éditeur portait déjà Bebas uppercase ;
   retour Julien : la maquette fait foi, « JE M'INSCRIS » display) */
.ch-news .ch-news-form .kb-advanced-form .kb-button { display: inline-flex; align-items: center; justify-content: center; background: var(--cta-bg); color: var(--cta-text); font-family: var(--font-display); font-weight: 400; font-size: var(--type-price-s); line-height: 1; text-transform: uppercase; letter-spacing: .04em; padding: 14px 28px; border: 0; border-radius: var(--radius-m); box-shadow: var(--shadow-cta); height: 100%; transition: background var(--t-quick) var(--ease-cube), transform var(--t-quick) var(--ease-cube); }
/* verrou des 3 états (passe de cohérence 12/07) : le parent peint les
   button:hover/:focus/:active et volerait le halo or au survol */
.ch-news .ch-news-form .kb-advanced-form .kb-button:hover,
.ch-news .ch-news-form .kb-advanced-form .kb-button:focus,
.ch-news .ch-news-form .kb-advanced-form .kb-button:active { background: var(--cta-bg-hover); color: var(--cta-text); box-shadow: var(--shadow-cta); }
.ch-news .ch-news-form .kb-advanced-form .kb-button:hover { transform: translateY(-1px); }
.ch-news .ch-news-form .kb-advanced-form .kb-button:focus-visible { box-shadow: var(--focus-ring), var(--shadow-cta); }
/* Consentement : le form vit sur fond noir sur le site actuel (labels
   blancs) ; sur la bande champagne ils repassent à l'encre douce. Le
   label de l'e-mail reste masqué au-dessus (sr-only), celui de la case
   doit se voir. Markup réel du bloc accept (constaté au DOM, gate B) :
   fieldset .kb-radio-check-item-wrap > .kb-radio-check-item >
   input.kb-checkbox-field + label — les .kb-checkbox-item du transport
   Bloc 3 n'existaient pas dans ce DOM, règles réécrites. Case redessinée
   à l'échelle de la mention : 16 px, native (appearance auto), contrôle
   de sélection BLEU (loi des 2 couleurs), calée sur la première ligne ;
   rangée centrée sous le formulaire, texte à gauche dans son bloc. */
.ch-news .ch-news-form .kb-advanced-form .kb-radio-check-item-wrap { border: 0; margin: 0; padding: 0; }
/* BLOC LÉGAL UNIFIÉ (retour 10 de F-ter-a, 12/07 : le consentement
   ragged-left et la mention centrée créaient un déséquilibre ; centrer
   le texte du consentement orphelinait la case). La composition : un
   seul bloc légal de la largeur du formulaire (480), tout le texte
   aligné à GAUCHE — consentement sur la case, mention calée sous le
   texte du consentement (même bord) — et le bloc entier centré en
   masse par le conteneur. La case est DESSINÉE en entier — le plugin
   la peint en sombre via appearance:none + fond, un accent-color seul
   laissait une case noire décochée : paper + bordure or décochée (le
   langage du champ e-mail), bleu cube + coche cochée (loi des 2
   couleurs), on assume appearance:none nous-mêmes. */
.ch-news .ch-news-form .kb-advanced-form .kb-radio-check-item { display: flex; align-items: flex-start; justify-content: flex-start; gap: var(--space-2); text-align: left; }
/* --news-case : le côté de la case, constante LOCALE du bloc — la mention
   légale s'aligne dessus (retrait = case + gap), les deux ne peuvent plus
   dériver l'une de l'autre. Portée de 17 à 24 px le 06/08/2026 (F34) : à
   390 la case était la cible la plus coûteuse du site (17×17, elle bloque
   une inscription si on la manque). La coche suit à l'échelle. */
.ch-news { --news-case: 24px; }
.ch-news .ch-news-form .kb-advanced-form input.kb-field.kb-checkbox-field { flex: 0 0 auto; width: var(--news-case); height: var(--news-case); margin: -2px 0 0; padding: 0; appearance: none; -webkit-appearance: none; background: var(--brand-paper); border: 1px solid var(--brand-gold-deep); border-radius: calc(var(--radius-s) / 2); cursor: pointer; }
.ch-news .ch-news-form .kb-advanced-form input.kb-field.kb-checkbox-field:checked { background: var(--brand-cube) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 12.8 9.7 18 19.5 6.5'/%3E%3C/svg%3E") center / 16px 16px no-repeat; border-color: var(--brand-cube); }
.ch-news .ch-news-form .kb-advanced-form .kb-radio-check-item label,
.ch-news .ch-news-form .kb-advanced-form .kb-field-help,
.ch-news .ch-news-form .kb-advanced-form .kb-form-field-description { font-size: var(--type-micro); color: var(--brand-ink-soft); }
/* le texte du consentement se cale CONTRE la case (retour Julien F-bis
   11/07 : « case orpheline ») : le label shrink-to-fit gardait son texte
   centré dans sa propre boîte (455 px), la première ligne démarrait à
   ~50 px de la case — aligné à gauche, la paire case+texte reste centrée
   en bloc par la rangée */
.ch-news .ch-news-form .kb-advanced-form .kb-radio-check-item label { text-align: left; }
.ch-news .ch-news-form .kb-advanced-form .wp-block-kadence-column:nth-child(3) label { color: var(--brand-ink-soft); font-size: var(--type-micro); }
/* la mention (« Désinscription en un clic… ») rejoint le bloc légal :
   même largeur que le formulaire, texte calé sous celui du consentement
   (retrait = case 17px + gap) — plus de ligne centrée sous un bloc
   gauche (retour 10) */
.ch-news .rgpd { max-width: 480px; margin-left: auto; margin-right: auto; text-align: left; padding-left: calc(var(--news-case) + var(--space-2)); }

@media (max-width: 680px) {
  .ch-news .ch-news-form .kb-advanced-form .kt-row-column-wrap { flex-direction: column; }
  .ch-news .ch-news-form .kb-advanced-form .wp-block-kadence-column:nth-child(1),
  .ch-news .ch-news-form .kb-advanced-form .wp-block-kadence-column:nth-child(2) { flex: 1 1 auto; }
  /* empilé, le CTA prend toute la largeur (motif maquette : colonne =
     champ puis bouton pleine largeur). Le réglage « alignement bas » du
     bloc colonne devient align-self:flex-end en direction colonne : il
     poussait le bouton à droite, rétréci à son contenu — on restitue le
     stretch aux colonnes empilées (F-bis 11/07) */
  .ch-news .ch-news-form .kb-advanced-form .wp-block-kadence-column { align-self: stretch; width: 100%; }
  .ch-news .ch-news-form .kb-advanced-form .kb-button { width: 100%; }
}

/* === /assets/css/sections/archive.css === */
/* Gabarit archive « Les rayons du musée » — échafaudage de page .arch-.
   Socle transporté du <style> de maquettes/boutique.html (É3, gate fermé
   09/07), REFONDU le 10/07 (session C, parti d'UX gaté par Julien) :
   - En-tête de page en NUIT (data-theme="night" posé par le template :
     crumb, eyebrow et compteurs remappent seuls) + recherche à CTA soudé
     (grammaire du hero home, .cta--field).
   - Le filtrage vit dans un TIROIR GAUCHE QUI POUSSE : fermé par défaut
     (la grille accueille en 4 colonnes pleine largeur), ouvert il prend
     sa colonne et la grille repasse à 3 — pas de voile, les résultats
     dynamiques S&F se réorganisent en pleine lumière. Mobile < 900 px :
     même tiroir en recouvrement plein écran (comportement du jalon B).
   - Plus AUCUN scroll interne de colonne en desktop (la double barre de
     défilement du jalon B est morte) : accordéons du composant facet +
     colonne qui défile avec la page. Le seul défilement interne restant
     est celui du tiroir mobile (recouvrement = unique contexte de scroll).
   Composants consommés (facet, toolbar, crumb, navchip, pcard, grading,
   cta) : registre transporté, jamais redéfini ici — seules leurs
   compositions de contexte (rythme du tiroir, colonnes de la grille)
   vivent dans cet échafaudage.

   Écarts documentés (parties réelles É4) :
   - .arch-head : la compensation de hauteur du header (--ch-head-h) saute —
     le body du child la porte déjà (chrome.css, padding-top --ch-head-h des pages
     sans hero) ; la maquette n'avait pas ce padding de body.
   - § pagination (fin de fichier) : pagination native Woo stylée tokens.
   - .arch-search-box input : sélecteur renforcé en input[type="search"]
     (0,1,2) — le global.min.css du parent Kadence pose un padding sur
     input[type="search"] à spécificité égale et volait le retrait de
     l'icône (prouvé au scan CSSOM, même motif que le a:hover du Bloc 4). */

/* ---------- en-tête de page (nuit : l'écrin, remap par data-theme) ---------- */
.arch-head { background: var(--surface-page); padding: var(--space-6) 0; }
.arch-head[data-theme="night"] { background-image: var(--brand-night-spot); }
.arch-h1 { font-family: var(--font-display); font-weight: 400; font-size: var(--type-display); line-height: .98; letter-spacing: .01em; color: var(--text-strong); margin-bottom: var(--space-3); }
.arch-lead { font-size: var(--type-lead); line-height: 1.5; color: var(--text-body); max-width: 66ch; margin-bottom: var(--space-5); }
.arch-lead strong { color: var(--text-strong); }
.arch-num { font-family: var(--font-data); font-variant-numeric: tabular-nums; letter-spacing: .01em; }

/* recherche à CTA soudé : champ nuit du hero home (ch-hero-search), bouton .cta--field */
.arch-search { display: flex; gap: 10px; max-width: 560px; }
.arch-search-box { position: relative; flex: 1 1 auto; min-width: 0; }
.arch-search-box svg { position: absolute; left: var(--space-4); top: 50%; transform: translateY(-50%); color: var(--text-soft); pointer-events: none; }
.arch-search-box input[type="search"] { width: 100%; border: 1px solid var(--border-soft); background: var(--surface-raised); border-radius: var(--radius-m); padding: var(--space-3) var(--space-4) var(--space-3) var(--space-8); font-family: inherit; font-size: var(--type-body); color: var(--text-body); }
.arch-search-box input::placeholder { color: var(--text-soft); }
.arch-head[data-theme="night"] .arch-search-box input[type="search"] { border-color: var(--border-night-strong); background: var(--surface-night-raised); color: var(--text-inverse-strong); }
.arch-head[data-theme="night"] .arch-search-box input::placeholder { color: var(--brand-dusk); }
.arch-head[data-theme="night"] .arch-search-box svg { color: var(--brand-dusk); }
@media (max-width: 680px) {
  .arch-search { flex-direction: column; }
}

/* ---------- rangée de rayons (navchip) ---------- */
.arch-rayons { padding: var(--space-6) 0 0; }

/* ---------- méta-run de la vitrine (verbatim vitrine-asm-1963.html) ---------- */
.arch-meta { font-size: var(--type-body); color: var(--text-body); margin: 0 0 var(--space-5); }

/* ---------- layout : tiroir poussant + main ----------
   Fermé : piste aside à 0 (sans gouttière), grille pleine largeur x4.
   Ouvert : piste à 300px, gouttière, grille x3. Les pistes de grille
   s'animent (le contenu du tiroir garde sa largeur par min-width, la
   piste le découvre en glissant).
   L'ÉTAT est projeté en body.arch-drawer-open par archive.js, qui le
   ré-arme après chaque filtre : les résultats dynamiques S&F
   réassignent en bloc les classes du conteneur ET du body depuis la
   page recherchée (prouvé au MutationObserver, 10/07 : les nœuds
   survivent, toute classe posée par JS saute). Ne jamais faire
   dépendre cet échafaudage d'une classe posée par JS sans son
   ré-armement côté archive.js. */
.arch-layout { padding: var(--space-6) 0 var(--space-8); }
.arch-grid {
  display: grid; grid-template-columns: 0px minmax(0, 1fr);
  column-gap: 0; align-items: start;
  transition: grid-template-columns var(--t-soft) var(--ease-cube), column-gap var(--t-soft) var(--ease-cube);
}
body.arch-drawer-open .arch-grid { grid-template-columns: 300px minmax(0, 1fr); column-gap: var(--space-7); }
.arch-aside {
  overflow: hidden; opacity: 0; visibility: hidden;
  transition: opacity var(--t-soft) var(--ease-cube), visibility var(--t-soft) var(--ease-cube);
}
body.arch-drawer-open .arch-aside { opacity: 1; visibility: visible; }
.arch-aside > * { min-width: 300px; }
.arch-main { min-width: 0; }

/* tête du tiroir : titre, réinitialiser, fermer */
.arch-aside-head { display: flex; align-items: center; gap: var(--space-3); padding-bottom: var(--space-3); border-bottom: 1px solid var(--border-soft); }
.arch-aside-head .t { font-family: var(--font-display); font-weight: 400; font-size: var(--type-subtitle); letter-spacing: .02em; color: var(--text-strong); margin-right: auto; }
/* padding vertical 3px : la zone de touche passe de 19 à 25 px de haut
   (F34, 06/08/2026 — confort au doigt à 390). Le lien est un item de la
   rangée flex centrée : sa boîte grandit, sa position ne bouge pas. */
.arch-reset { background: transparent; border: 0; padding: 3px 0; font-family: inherit; font-size: var(--type-micro); color: var(--link); cursor: pointer; text-decoration: underline; }
.arch-reset:hover { color: var(--accent); }
/* padding: 0 obligatoire — le style bouton global du parent Kadence (7,2px 18px)
   écraserait le X à 0 px de large dans la boîte de 36px */
.arch-aside-close { width: 36px; height: 36px; padding: 0; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; background: transparent; border: 1px solid var(--border-soft); border-radius: var(--radius-m); color: var(--text-body); cursor: pointer; }
/* tous les états possédés (motif Bloc 4) : le parent Kadence peint sinon
   le :focus des boutons en disque sombre (vu au constat mobile 10/07) */
.arch-aside-close:hover, .arch-aside-close:focus, .arch-aside-close:active { background: transparent; border-color: var(--border-strong); color: var(--text-strong); box-shadow: none; }
.arch-aside-close:focus-visible { box-shadow: var(--focus-ring); }

/* la question posée (lot 2.3, servie sur TOUS les contextes au lot 2.9) :
   le champ de recherche ouvre le tiroir, hors accordéons — une recherche
   ne se replie pas. Rythme aligné sur les groupes de facettes (rangée
   bordée) */
.arch-aside-search { padding: var(--space-4) 0; border-bottom: 1px solid var(--border-soft); }
.arch-aside-search .facet-t { margin-bottom: var(--space-2); }

/* LA BOÎTE DE RECHERCHE DU TIROIR (lot 2.9, retour de gate Julien du
   04/08 : « champ quasi brut, loupe grise presque invisible »).
   Déclinaison COMPACTE de la recherche du hero (.arch-search-box
   ci-dessus, elle-même dérivée du champ nuit de la home) : même boîte
   (bord, rayon, surface surélevée), même loupe calée à gauche, à
   l'échelle du tiroir (corps type-caption, cible tactile 44px). Ce qui
   change par rapport au hero, et seulement cela : le CTA soudé tombe
   (le véhicule S&F du contexte recherche ne peut pas en porter, et deux
   rendus divergents pour un même objet seraient pires que l'absence de
   bouton — Entrée soumet des deux côtés) ; la loupe passe de
   --text-soft à --text-strong, sans quoi elle disparaît sur fond
   surélevé ; le focus prend l'anneau du DS (--focus-ring), en plus du
   bord accent.
   UN objet, DEUX véhicules, UNE recette : le formulaire GET du child
   hors recherche (.arch-aside-search-box) et le champ Search & Filter
   en contexte recherche (markup du plugin ; ses réparations de
   structure restent dans facet-sf.css, qui charge après ce fichier). */
.arch-aside-search-box,
.arch-aside-search .search-filter-input-text {
  display: flex; align-items: center; gap: var(--space-2);
  min-height: 44px; padding: 0 var(--space-3);
  border: 1px solid var(--border-soft); border-radius: var(--radius-m);
  background: var(--surface-raised);
  transition: border-color var(--t-quick) var(--ease-cube), box-shadow var(--t-quick) var(--ease-cube);
}
.arch-aside-search-box:hover,
.arch-aside-search .search-filter-input-text:hover { border-color: var(--border-strong); }
.arch-aside-search-box:focus-within,
.arch-aside-search .search-filter-input-text:focus-within { border-color: var(--accent); box-shadow: var(--focus-ring); }

/* la loupe : lisible au repos (le « gris fantôme » #bbbbbb du plugin
   était le retour de gate), accent quand le champ prend la main. Une
   seule couleur pour les deux véhicules : le glyphe du plugin est
   reteint en currentColor par facet-sf.css, qui lui pose NOTRE tracé. */
.arch-aside-search-box > svg,
.arch-aside-search .search-filter-input-text__icon {
  flex: 0 0 auto; width: 18px; height: 18px; color: var(--text-strong);
  transition: color var(--t-quick) var(--ease-cube);
}
.arch-aside-search-box:focus-within > svg,
.arch-aside-search .search-filter-input-text:focus-within .search-filter-input-text__icon { color: var(--accent); }

/* le champ : la BOÎTE porte le cadre, jamais l'input — le style global
   de champ du parent Kadence peindrait sinon un cadre dans le cadre
   (motif .arch-aside-close). Sélecteur à type pour battre son
   input[type="search"] à spécificité égale (motif .arch-search-box). */
.arch-aside-search-box input[type="search"],
.arch-aside-search .search-filter-input-text__input {
  flex: 1 1 auto; min-width: 0; width: 100%;
  padding: var(--space-3) 0; margin: 0; border: 0; background: transparent;
  font-family: var(--font-body); font-size: var(--type-caption); color: var(--text-body);
}
.arch-aside-search-box input[type="search"]:focus,
.arch-aside-search-box input[type="search"]:focus-visible,
.arch-aside-search .search-filter-input-text__input:focus,
.arch-aside-search .search-filter-input-text__input:focus-visible { outline: 0; box-shadow: none; }
.arch-aside-search-box input[type="search"]::placeholder,
.arch-aside-search .search-filter-input-text__input::placeholder { color: var(--text-soft); }

/* groupes de facettes : rangées bordées, rythme du tiroir (le composant
   facet garde son anatomie, l'hôte pose les séparations) */
.arch-facets .facet { border-bottom: 1px solid var(--border-soft); }
.arch-facets .facet + .facet { margin-top: 0; }

/* pied du tiroir : « Voir les N pièces » (nuit/or, ferme le tiroir) */
.arch-aside-foot { margin-top: var(--space-5); }
.arch-aside-voir {
  display: flex; width: 100%; align-items: center; justify-content: center; gap: 6px;
  background: var(--brand-night); color: var(--brand-gold); border: 0; cursor: pointer;
  border-radius: var(--radius-m); padding: 14px 20px;
  font-family: var(--font-display); font-weight: 400; font-size: var(--type-price-s);
  letter-spacing: .04em; text-transform: uppercase;
  transition: background var(--t-quick) var(--ease-cube);
}
.arch-aside-voir:hover, .arch-aside-voir:focus, .arch-aside-voir:active { background: var(--brand-midnight); color: var(--brand-gold); box-shadow: none; }
.arch-aside-voir:focus-visible { box-shadow: var(--focus-ring); }
.arch-aside-voir b { font-family: var(--font-data); font-weight: 600; font-variant-numeric: tabular-nums; }

/* mention de démonstration (registre « meta » de la mention avis home) */
.arch-demo { font-size: var(--type-micro); color: var(--text-soft); border: 1px dashed var(--border-soft); border-radius: var(--radius-m); padding: var(--space-3) var(--space-4); margin: var(--space-5) 0; }

/* ---------- toolbar : l'étage rapide, toujours sous la main ----------
   Sticky sous le header fixe (--ch-head-h, écart documenté en tête) : le
   bouton Filtres, les chips actifs et le tri suivent le scroll.
   [30/07] + var(--ch-head-top) : le header est décalé du bandeau promo
   (et de la barre d'admin), l'offset sticky doit suivre le même décalage,
   sinon la toolbar défile SOUS le header — 44px de recouvrement mesurés au
   navigateur, bandeau promo affiché. Motif déjà en place dans compte.css
   et contact.css ; seule cette toolbar l'ignorait. */
.arch-main .toolbar { position: sticky; top: calc(var(--ch-bar-h, var(--ch-head-h)) + var(--ch-head-top, 0px)); z-index: 40; background: var(--surface-page); padding: var(--space-3) 0; border-bottom: 1px solid var(--border-soft); margin-bottom: var(--space-5); }

/* grille : consomme .cards/.pcard du registre — ici seules les COLONNES
   du contexte (x4 pleine largeur, x3 tiroir ouvert ; x5/x4 en très
   large). Sous 900 px le composant garde son auto-fill. */
@media (min-width: 901px) {
  .arch-main .cards { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  body.arch-drawer-open .arch-main .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1780px) {
  .arch-main .cards { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  body.arch-drawer-open .arch-main .cards { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.arch-more { text-align: center; margin-top: var(--space-7); }
.arch-empty { text-align: center; padding: var(--space-8) var(--space-4); }
.arch-empty p { font-size: var(--type-body); color: var(--text-soft); margin-bottom: var(--space-3); }
.arch-empty .arch-reset { font-size: var(--type-caption); }
/* titre de région, réservé aux lecteurs d'écran (donne un parent h2 aux vignettes h3) */
.arch-vh { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* liens de maillage sous la grille (verbatim rayon-marvel.html) */
.arch-mesh { margin-top: var(--space-7); font-size: var(--type-caption); color: var(--text-soft); }
.arch-mesh a { color: var(--link); text-decoration: underline; }
.arch-mesh a:hover { color: var(--accent); }

/* scrim : réservé au recouvrement mobile */
.arch-scrim { display: none; }

@media (max-width: 900px) {
  .arch-grid, body.arch-drawer-open .arch-grid { grid-template-columns: 1fr; column-gap: 0; }
  /* le tiroir redevient un recouvrement plein écran hors-champ ; seul
     contexte de scroll interne restant (la page derrière est voilée) */
  .arch-aside {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 1200;
    width: min(340px, 88vw); height: 100%;
    background: var(--surface-raised); box-shadow: var(--shadow-float);
    padding: var(--space-4) var(--space-5);
    display: flex; flex-direction: column;
    overflow: visible; opacity: 1; visibility: visible;
    transform: translateX(-100%);
    transition: transform var(--t-soft) var(--ease-cube);
  }
  body.arch-drawer-open .arch-aside { transform: none; }
  .arch-aside > * { min-width: 0; }
  .arch-facets { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
  /* la piste de scroll du tiroir s'efface (vrai mobile : Android peint
     une barre grise permanente le long des facettes, invisible en
     émulation bureau — retour Julien 14/07) ; le défilement reste */
  .arch-facets { scrollbar-width: none; }
  .arch-facets::-webkit-scrollbar { display: none; width: 0; }
  .arch-aside-foot { margin-top: var(--space-4); }
  .arch-main .toolbar { top: calc(var(--ch-bar-h, var(--ch-head-h)) + var(--ch-head-top, 0px)); }
  .arch-scrim { display: block; position: fixed; inset: 0; z-index: 1100; background: var(--veil-night); opacity: 0; visibility: hidden; transition: opacity var(--t-soft) var(--ease-cube), visibility var(--t-soft) var(--ease-cube); }
  body.arch-drawer-open .arch-scrim { opacity: 1; visibility: visible; }
}
@media (prefers-reduced-motion: reduce) {
  .arch-grid, .arch-aside, .arch-scrim { transition: none; }
}

/* ---------- pagination native Woo (partie réelle É4, hors maquette) ---------- */
.arch-pages { margin-top: var(--space-7); display: flex; justify-content: center; }
.arch-pages .page-numbers { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; list-style: none; margin: 0; padding: 0; }
.arch-pages .page-numbers li { margin: 0; }
.arch-pages a.page-numbers, .arch-pages span.page-numbers { display: inline-flex; align-items: center; justify-content: center; min-width: 40px; height: 40px; padding: 0 var(--space-2); border: 1px solid var(--border-soft); border-radius: var(--radius-m); background: var(--surface-raised); font-family: var(--font-data); font-variant-numeric: tabular-nums; font-size: var(--type-caption); color: var(--text-body); text-decoration: none; }
.arch-pages a.page-numbers:hover { border-color: var(--border-strong); color: var(--text-strong); }
.arch-pages span.page-numbers.current { background: var(--brand-night); border-color: var(--brand-night); color: var(--text-inverse-strong); }
.arch-pages span.page-numbers.dots { border: 0; background: transparent; }

/* === /assets/css/facet-sf.css === */
/* ------------------------------------------------------------
   Adaptateur Search & Filter (jalon B, É4-e) — CHILD SEULEMENT.
   Applique la grammaire visuelle du composant registre facet.css
   au markup réel des champs Search & Filter (rendu React du
   plugin) : rangées d'options aux vrais inputs, comptages en voix
   documentaire (mono, à droite), état actif au voile or (« vous
   êtes ici »), contrôle de sélection bleu (--accent) — la loi des
   2 couleurs tient. Curseurs (année, prix) et combobox à
   autocomplétion (série, auteurs) au même langage.

   Ce fichier N'EST PAS un composant du registre : il habille un
   markup tiers (celui du plugin), il vit donc dans le child, à
   côté de chrome.css. La référence visuelle canonique reste
   design-system/components/facet.css (transporté byte-identique).
   Si le plugin change son markup à une mise à jour, c'est ICI
   qu'on répare, jamais dans le registre.

   Portée : .arch-aside (aside du gabarit archive) + le popup de
   combobox, que le plugin téléporte en fin de body (hors aside) +
   l'état de chargement des résultats dynamiques (dernière section :
   body.arch-sf-chargement, posé par archive.js pendant le fetch S&F).
   ------------------------------------------------------------ */

/* ---------- squelette du champ ---------- */
.arch-aside .search-filter-field { font-size: var(--type-caption); }

/* ---------- rangées d'options : radios et cases ---------- */
.arch-aside .search-filter-input-radio,
.arch-aside .search-filter-input-checkbox {
  border-radius: var(--radius-s);
  transition: background var(--t-quick) var(--ease-cube);
}
.arch-aside .search-filter-input-radio__container,
.arch-aside .search-filter-input-checkbox__container {
  display: flex; align-items: center; gap: var(--space-2);
  margin: 0; padding: var(--space-2); cursor: pointer;
}
/* le contrôle dessiné du plugin (svg) : gris au repos, bleu choisi */
.arch-aside .search-filter-input-radio__control,
.arch-aside .search-filter-input-checkbox__control {
  width: 16px; height: 16px; flex: 0 0 auto;
  color: var(--border-strong);
}
.arch-aside .search-filter-input-radio__control svg,
.arch-aside .search-filter-input-checkbox__control svg { width: 100%; height: 100%; display: block; }
.arch-aside .search-filter-input-radio--is-active .search-filter-input-radio__control,
.arch-aside .search-filter-input-checkbox--is-active .search-filter-input-checkbox__control { color: var(--accent); }

/* libellé à gauche, comptage mono à droite (anatomie .facet-opt) */
.arch-aside .search-filter-input-radio__label,
.arch-aside .search-filter-input-checkbox__label {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: baseline; gap: var(--space-2);
  font-size: var(--type-caption); color: var(--text-soft); line-height: 1.3;
  transition: color var(--t-quick) var(--ease-cube);
}
.arch-aside .search-filter-input-radio__count,
.arch-aside .search-filter-input-checkbox__count {
  margin-left: auto; flex: 0 0 auto;
  font-family: var(--font-data); font-size: var(--type-micro);
  color: var(--data-ink); letter-spacing: .02em; font-variant-numeric: tabular-nums;
}

/* survol : le texte s'affirme, comme facet.css */
.arch-aside .search-filter-input-radio:hover .search-filter-input-radio__label,
.arch-aside .search-filter-input-checkbox:hover .search-filter-input-checkbox__label { color: var(--text-strong); }

/* état actif : voile or « vous êtes ici », donnée en or lisible */
.arch-aside .search-filter-input-radio--is-active,
.arch-aside .search-filter-input-checkbox--is-active { background: var(--brand-gold-soft); }
.arch-aside .search-filter-input-radio--is-active .search-filter-input-radio__label,
.arch-aside .search-filter-input-checkbox--is-active .search-filter-input-checkbox__label { color: var(--text-strong); font-weight: 600; }
.arch-aside .search-filter-input-radio--is-active .search-filter-input-radio__count,
.arch-aside .search-filter-input-checkbox--is-active .search-filter-input-checkbox__count { color: var(--data-accent); font-weight: 600; }

/* ---------- curseurs (année de parution, prix) ---------- */
.arch-aside .search-filter-component-range-slider__range-text {
  display: flex; justify-content: space-between;
  font-family: var(--font-data); font-size: var(--type-micro);
  color: var(--data-ink); letter-spacing: .02em; font-variant-numeric: tabular-nums;
  margin-bottom: var(--space-2);
}
.arch-aside .search-filter-component-range-slider__range-input-bar {
  background: var(--border-soft); border-radius: var(--radius-arc);
}
.arch-aside .search-filter-component-range-slider__range-input-progress {
  background: var(--accent); border-radius: var(--radius-arc);
}
.arch-aside .search-filter-component-range-slider__range-input::-webkit-slider-thumb {
  background: var(--surface-raised); border: 2px solid var(--accent);
}
.arch-aside .search-filter-component-range-slider__range-input::-moz-range-thumb {
  background: var(--surface-raised); border: 2px solid var(--accent);
}

/* ---------- combobox à autocomplétion (série, auteurs) ---------- */
.arch-aside .search-filter-component-combobox {
  border: 1px solid var(--border-soft); border-radius: var(--radius-m);
  background: var(--surface-raised);
  transition: border-color var(--t-quick) var(--ease-cube);
}
.arch-aside .search-filter-component-combobox:hover { border-color: var(--border-strong); }
.arch-aside .search-filter-component-combobox:focus-within { border-color: var(--accent); }
.arch-aside .search-filter-component-combobox input[type="text"] {
  font-family: var(--font-body); font-size: var(--type-caption); color: var(--text-body);
  background: transparent; border: 0;
}
.arch-aside .search-filter-component-combobox input[type="text"]::placeholder { color: var(--text-soft); }

/* ---------- champ Recherche du panneau (lot 2.3, revu au lot 2.9) ----------
   Le terme de la recherche est un champ S&F comme les autres, mais ce
   n'est pas une facette : il vit en tête du tiroir, hors accordéons.
   LA RECETTE VISUELLE DE LA BOÎTE N'EST PLUS ICI (lot 2.9) : elle vit
   dans sections/archive.css, § « la boîte de recherche du tiroir », avec
   celle du formulaire GET du child qui sert les contextes hors
   recherche — un seul objet visuel, une seule recette, deux véhicules.
   Ce fichier ne garde que ce qui n'existe QUE dans le markup du plugin :
   la mise en boîte de ses glyphes, et la croix « effacer », que le
   formulaire du child n'a pas.
   Réparation mesurée au constat du 04/08 (lot 2.9) : le plugin pose un
   padding de 3,5 px sur le span de l'icône ET dimensionne son svg en
   border-box — la loupe se rétrécissait donc à 11 px dans une boîte de
   18, quelle que soit la taille demandée à la boîte. Padding remis à
   zéro : le glyphe remplit sa boîte, et le rythme reste celui du gap.
   Et sa loupe est un glyphe PLEIN, teint par une variable maison, là où
   la grammaire du site trace une loupe au filet (cercle + manche,
   1,8 px — celle du hero, reprise à l'identique par le formulaire du
   child) : deux véhicules d'un même champ ne peuvent pas montrer deux
   loupes. Le glyphe du plugin est donc masqué, et son span porte NOTRE
   tracé en masque — teinté par currentColor, donc piloté par la seule
   recette de sections/archive.css, repos comme focus. */
.arch-aside .search-filter-input-text__icon,
.arch-aside .search-filter-input-text__clear-button { padding: 0; }
.arch-aside .search-filter-input-text__icon {
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E") center / contain no-repeat;
}
.arch-aside .search-filter-input-text__icon svg { display: none; }
.arch-aside .search-filter-input-text__clear-button {
  flex: 0 0 auto; width: 16px; height: 16px; cursor: pointer;
  /* la croix reste discrète : elle ne dispute pas la loupe */
  --search-filter-input-icon-color: var(--text-soft);
}
.arch-aside .search-filter-input-text__clear-button:hover { --search-filter-input-icon-color: var(--accent); }
.arch-aside .search-filter-input-text__clear-button svg { width: 100%; height: 100%; display: block; }
.arch-aside .search-filter-input-text__clear-button:focus-visible { box-shadow: var(--focus-ring); border-radius: var(--radius-s); }

/* le popup d'options est téléporté en fin de body : hors .arch-aside */
ul.search-filter-component-popup.search-filter-component-combobox-base__listbox {
  background: var(--surface-raised); border: 1px solid var(--border-soft);
  border-radius: var(--radius-m); box-shadow: var(--shadow-float);
  padding: var(--space-1); margin: 0; list-style: none;
  font-size: var(--type-caption); color: var(--text-body);
  z-index: 1300; /* au-dessus du tiroir mobile (1200) et du scrim (1100) */
}
ul.search-filter-component-popup .search-filter-component-combobox-base__listbox-option {
  padding: var(--space-2); border-radius: var(--radius-s);
  cursor: pointer; list-style: none; line-height: 1.3;
}
ul.search-filter-component-popup .search-filter-component-combobox-base__listbox-option:hover {
  background: var(--brand-gold-soft); color: var(--text-strong);
}
ul.search-filter-component-popup .search-filter-component-combobox-base__listbox-option--selected {
  background: var(--brand-gold-soft); color: var(--text-strong); font-weight: 600;
}

/* ---------- état de chargement des résultats dynamiques ----------
   Posé par archive.js (body.arch-sf-chargement) pendant le fetch S&F
   (…search-filter-api=frontend) et jusqu'au remplacement effectif du
   bloc de résultats. Une combinaison de filtres jamais calculée coûte
   7-10 s de serveur (banc du 14/07) : le voile dit « je travaille ».
   Les combinaisons déjà vues re-rendent sans réseau : la classe n'est
   jamais posée, zéro flash. Apparitions différées de ~.2 s : un
   serveur chaud (~1 s) montre à peine le voile. */

/* le voile : résultats et pagination en attente (liens actifs, l'état
   est un signal, pas un verrou) */
body.arch-sf-chargement .arch-main .cards,
body.arch-sf-chargement .arch-main .arch-pages,
body.arch-sf-chargement .arch-main .arch-empty {
  opacity: .45;
  transition: opacity var(--t-quick) var(--ease-cube) .2s;
}
body.arch-sf-chargement .tb-count b,
body.arch-sf-chargement .arch-aside-voir b { opacity: .35; transition: opacity var(--t-quick) var(--ease-cube) .2s; }

/* l'anneau de travail : compteur de la toolbar (accent sur page) et
   pied du tiroir (or sur nuit). Pseudo créé avec la classe : les
   transitions n'y mordent pas, l'apparition différée passe par une
   animation à remplissage (invisible pendant .2 s, puis fondu). */
body.arch-sf-chargement .tb-count::after,
body.arch-sf-chargement .arch-aside-voir::after {
  content: ""; display: inline-block; vertical-align: -2px;
  width: 12px; height: 12px; margin-left: var(--space-2);
  border: 2px solid var(--border-strong); border-top-color: var(--accent);
  border-radius: 50%;
  animation:
    arch-sf-apparait var(--t-quick) var(--ease-cube) .2s both,
    arch-sf-tourne .7s linear infinite;
}
body.arch-sf-chargement .arch-aside-voir::after {
  border-color: rgb(255 255 255 / .25); border-top-color: var(--brand-gold);
}
@keyframes arch-sf-apparait { from { opacity: 0; } to { opacity: 1; } }
@keyframes arch-sf-tourne { to { transform: rotate(360deg); } }

/* mouvement réduit : le fondu reste, la rotation meurt — l'anneau
   entamé immobile suffit comme signal */
@media (prefers-reduced-motion: reduce) {
  body.arch-sf-chargement .tb-count::after,
  body.arch-sf-chargement .arch-aside-voir::after { animation: arch-sf-apparait var(--t-quick) var(--ease-cube) .2s both; }
}

