/*
Theme Name: Press Start Cards 2026
Theme URI: https://press-start-cards.fr/
Author: Press Start Cards
Author URI: https://press-start-cards.fr/
Description: Theme bloc (FSE) pour l'impression a la demande de jeux de cartes, notices, plateaux et boites. Editable integralement depuis l'editeur de site, accessible (RGAA / WCAG 2.2 AA), sans JavaScript en front, polices auto-hebergees.
Version: 2.6.0
Requires at least: 6.5
Tested up to: 7.0
Requires PHP: 8.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: psc2026
Tags: full-site-editing, block-patterns, block-styles, style-variations, accessibility-ready, e-commerce, translation-ready
*/

/* Polices de repli a metriques ajustees : le texte ne bouge plus (CLS) quand
   la police auto-hebergee remplace le repli. Valeurs calculees depuis les
   fichiers .woff2 (largeur moyenne ponderee + hhea) face a Arial. Si un
   .woff2 change, recalculer. local() absent (ex. Android) : sans effet, la
   pile passe simplement a system-ui. */
@font-face{font-family:"IBM Plex Sans Fallback";font-weight:400;src:local("Arial"),local("ArialMT"),local("Liberation Sans");size-adjust:101.8%;ascent-override:100.6%;descent-override:27%;line-gap-override:0%}
@font-face{font-family:"IBM Plex Sans Fallback";font-weight:600;src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold");size-adjust:97.3%;ascent-override:105.3%;descent-override:28.3%;line-gap-override:0%}
@font-face{font-family:"Chakra Petch Fallback";font-weight:600;src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold");size-adjust:99.3%;ascent-override:99.9%;descent-override:31%;line-gap-override:0%}
@font-face{font-family:"Chakra Petch Fallback";font-weight:700;src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold");size-adjust:100.9%;ascent-override:98.3%;descent-override:30.5%;line-gap-override:0%}


/* ============================================================================
   Feuille unique du theme. Tout ce qui est exprimable en theme.json y reste :
   ce fichier ne contient que ce que theme.json ne sait pas dire (pseudo-classes
   de focus, requetes de media, impression). Objectif : rester sous 10 Ko, non
   minifie, pour ne pas peser sur le premier rendu.

   AUCUNE ANIMATION DECORATIVE ICI. Le bandeau defilant et la carte 3D vivent
   dans le plugin press-start-ui, qui porte les mecanismes de pause exiges par
   le RGAA 13.8. Les dupliquer dans le theme aurait cree deux implementations
   a maintenir, dont une non conforme.
   ========================================================================= */


/* ---------------------------------------------------------------- 1. SOCLE */

*,
*::before,
*::after { box-sizing: border-box; }

/* La marge de 8 px que les navigateurs posent par defaut sur <body> est deja
   remise a zero par le noyau (wp-includes/css/dist/block-library/common.css).
   On la redit ici parce qu'un optimiseur — LiteSpeed et son « retirer le CSS
   inutilise » en premier — peut retirer cette feuille : la marge reviendrait,
   et avec elle 16 px d'ecart sur toutes les largeurs calculees en pourcentage
   (voir la regle des 80 % en 6.0). Une ligne pour ne pas dependre de ca. */
body { margin: 0; }

img,
video { max-width: 100%; height: auto; }

/* CESURE DES TITRES — indispensable en francais.
   Mesure : « Imprimez votre jeu de cartes personnalise » en Chakra Petch a la
   taille hero (34 px au minimum de la plage fluide) debordait de 14 px a
   320 px de large, parce qu'aucun navigateur ne coupe un mot de son propre
   chef. Le francais aligne les mots longs — personnalise, degressifs,
   configurateur — et un titre en capitales les rend encore plus larges.
   `overflow-wrap` autorise la coupure en dernier recours, `hyphens` la rend
   propre avec un trait d'union (la page declare lang="fr", sans quoi la
   cesure automatique ne s'applique pas). */
:is(h1, h2, h3, h4, h5, h6),
.wp-block-post-title,
.wp-block-site-title {
  overflow-wrap: break-word;
  hyphens: auto;
}
/* Meme filet sur le corps de texte : une URL ou une reference produit sans
   espace deborderait de la meme facon.
   NE PAS le poser sur `body` : la propriete est heritee, et dans une interface
   ou un conteneur se retrouve tres etroit, `break-word` affiche le texte a
   raison d'une lettre par ligne — ce qui est PIRE qu'un debordement, parce que
   ca ressemble a un bug d'affichage sans en donner la cause. On la limite donc
   aux contenus redactionnels. */
:where(p, li, dd, dt, figcaption, blockquote, td, th, .wp-block-post-excerpt) {
  overflow-wrap: break-word;
}

/* Les ancres ne doivent pas se retrouver sous l'en-tete collant : sans ca, un
   lien vers #faq amene le titre hors ecran. --psc-sticky est la hauteur
   reservee ; elle suit la taille de l'en-tete. */
html {
  --psc-sticky: 76px;
  scroll-padding-top: calc(var(--psc-sticky) + 12px);
}
:target { scroll-margin-top: calc(var(--psc-sticky) + 12px); }


/* --------------------------------------------- 2. ACCESSIBILITE : LE SOCLE */

/* Lien d'evitement du COEUR, style par le theme.
   Depuis WordPress 6.8, `_block_template_add_skip_link()` l'insere cote
   serveur dans le HTML du gabarit — plus par un script — et reutilise l'id du
   <main> s'il en a un, donc #psc-main. Le theme n'en rend donc plus un second.
   Verifie sur 7.0 : le coeur n'imprime AUCUN CSS pour ce lien, c'est donc au
   theme de le rendre visible au focus.

   A L'ETAT MASQUE, ON NE TOUCHE A RIEN : la classe `screen-reader-text` du
   coeur masque en 1x1 px avec clip-path, ce qui ne cree aucun debordement.
   Une premiere version le repositionnait a `left:-9999px` — la vieille
   technique — et ca ajoutait 6 px de defilement horizontal a la page sur
   320 px de large. Mesure, puis corrige : seul l'etat :focus est redefini. */
.skip-link:focus {
  /* `fixed` et non `absolute` : le lien se pose PAR-DESSUS la page au lieu de
     pousser le contenu, donc aucun decalage de mise en page. */
  position: fixed !important;
  left: 8px;
  top: 8px;
  z-index: 999;
  width: auto !important;
  height: auto !important;
  margin: 0 !important;
  overflow: visible !important;
  clip: auto !important;
  clip-path: none !important;
  white-space: nowrap;
  background: var(--wp--preset--color--ink);
  color: var(--wp--preset--color--cream);
  padding: 14px 20px;
  font-family: var(--wp--preset--font-family--display);
  font-weight: 700;
  text-decoration: none;
  border: 3px solid var(--wp--preset--color--yellow);
}

/* La cible du lien d'evitement recoit tabindex="-1" (pose en PHP) : sans lui,
   certains navigateurs deplacent le defilement sans deplacer le focus. */
#psc-main:focus { outline: none; }

/* Texte reserve aux lecteurs d'ecran. Jamais display:none, qui le retirerait
   aussi de la vocalisation. */
.screen-reader-text {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
/* `:not(.skip-link)` est necessaire : le lien d'evitement du coeur porte les
   DEUX classes, et cette regle le remettrait dans le flux — donc decalerait
   tout le contenu vers le bas a la premiere tabulation. Il a son propre
   traitement juste en dessous. */
.screen-reader-text:focus:not(.skip-link) {
  position: static !important;
  width: auto; height: auto;
  margin: 0; padding: 12px 18px;
  clip-path: none;
  white-space: normal;
}

/* Focus visible, WCAG 2.4.7 et 1.4.11 (le contour doit lui-meme contraster).
   Mesure : bleu #3D5AFE contre creme 4,78:1, papier 5,13:1, encre 3,60:1,
   jaune 3,71:1 — au-dessus des 3:1 requis sur tous les fonds du theme.
   Un double liseré (bleu + encre) garantit la visibilite sur fond bleu. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--wp--preset--color--blue);
  outline-offset: 2px;
  box-shadow: 0 0 0 6px var(--wp--preset--color--ink);
}
/* Sur fond encre, on inverse : le liseré exterieur passe en creme. */
.has-ink-background-color :where(a, button, summary):focus-visible {
  box-shadow: 0 0 0 6px var(--wp--preset--color--cream);
}

/* Cible tactile de 44 px, WCAG 2.5.5 / 2.5.8. S'applique aux liens de
   navigation, boutons de pagination et champs de formulaire. */
.wp-block-navigation a,
.wp-block-query-pagination a,
.wp-block-query-pagination span,
.wp-block-search__button {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}


/* ------------------------------------------- 2 bis. MENUS (bloc « Menu WordPress »)
   Le balisage vient de wp_nav_menu(), donc les classes sont celles de
   WordPress : .sub-menu, .menu-item-has-children, .current-menu-item. On les
   habille plutot que de les reecrire, pour que les menus deja composes dans
   Apparence > Menus s'affichent sans rien retoucher. */

.psc-menu__list,
.psc-menu .sub-menu {
  list-style: none;
  margin: 0;
  padding: 0;
}
.psc-menu__list {
  display: flex;
  flex-wrap: wrap;
  gap: 2px var(--wp--preset--spacing--40);
  align-items: center;
}
.psc-menu--vertical .psc-menu__list {
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
}
.psc-menu a {
  display: inline-flex;
  align-items: center;
  /* Cible de 44 px (WCAG 2.5.5) : la zone cliquable ne se limite pas a la
     hauteur du texte, premiere cause de clics rates sur mobile. */
  min-height: 44px;
  padding: 0 2px;
  font-family: var(--wp--preset--font-family--display);
  font-weight: 600;
  text-transform: uppercase;
  text-decoration: none;
  color: inherit;
}
.psc-menu a:hover { text-decoration: underline; text-decoration-thickness: 2px; }

/* La page courante n'est pas signalee par la seule couleur (RGAA 3.1) :
   un soulignement epais la distingue aussi en niveaux de gris. */
.psc-menu .current-menu-item > a,
.psc-menu .current_page_item > a {
  text-decoration: underline;
  text-decoration-thickness: 3px;
  text-underline-offset: 4px;
}

/* ---- sous-menus deroulants ---- */
.psc-menu--dropdown .menu-item-has-children { position: relative; }
.psc-menu--dropdown .sub-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 40;
  display: none;
  min-width: 15rem;
  flex-direction: column;
  padding: 6px 10px;
  background: var(--wp--preset--color--cream);
  border: 3px solid var(--wp--preset--color--ink);
  box-shadow: 6px 6px 0 var(--wp--preset--color--ink);
}
.psc-menu--dropdown .menu-item-has-children.is-open > .sub-menu { display: flex; }

/* Repli sans JavaScript : le sous-menu s'ouvre a la tabulation. La classe
   .psc-menu--js est posee par le script ; on cible donc son ABSENCE, sinon les
   deux mecanismes se contrediraient — apres Echap le focus reste sur le bouton,
   donc dans le parent, et le panneau se rouvrirait aussitot. */
.psc-menu--dropdown:not(.psc-menu--js) .menu-item-has-children:focus-within > .sub-menu { display: flex; }

.psc-menu__toggle {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
}
/* Chevron dessine en CSS : aucune image, aucune police d'icones. */
.psc-menu__chevron {
  display: block;
  width: 9px;
  height: 9px;
  border-right: 3px solid currentColor;
  border-bottom: 3px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
}
.is-open > .psc-menu__toggle .psc-menu__chevron { transform: rotate(225deg) translateY(-2px); }

/* ---- niveaux 3 et plus, dans un panneau deroulant ----
   Un seul bouton par entree de premier niveau : les niveaux inferieurs sont
   affiches DEPLIES dans le panneau, en retrait. Pas de sous-panneau en
   cascade (fly-out) : difficile a viser a la souris, impossible au toucher,
   et un bouton imbrique cassait la ligne du libelle parent. La hierarchie
   reste lisible sans la couleur (retrait + filet + casse), RGAA 3.1 / 9.1. */
.psc-menu--dropdown .sub-menu { width: max-content; max-width: min(22rem, 90vw); }
.psc-menu--dropdown .sub-menu .sub-menu {
  position: static;
  display: flex;
  flex-basis: 100%;
  width: auto;
  min-width: 0;
  max-width: none;
  margin: 0 0 6px 4px;
  padding: 0 0 0 var(--wp--preset--spacing--30, 12px);
  background: transparent;
  border: 0;
  border-left: 3px solid currentColor;
  box-shadow: none;
}
.psc-menu--dropdown .sub-menu .sub-menu a { font-weight: 400; text-transform: none; }

/* ---- sous-menus toujours deplies (pied de page) ---- */
.psc-menu--expanded .sub-menu {
  display: flex;
  flex-direction: column;
  padding-left: var(--wp--preset--spacing--40);
  border-left: 3px solid currentColor;
  margin-left: 4px;
}
.psc-menu--expanded .sub-menu a { font-weight: 400; text-transform: none; }

/* ---- petit ecran ----
   Un panneau en position absolue deborderait de l'ecran : sous 48 rem, le
   sous-menu revient dans le flux et pousse le contenu, comme un accordeon. */
@media (max-width: 48rem) {
  .psc-menu--dropdown .psc-menu__list { flex-direction: column; align-items: stretch; gap: 0; }
  .psc-menu--dropdown .menu-item-has-children { display: flex; flex-wrap: wrap; align-items: center; }
  .psc-menu--dropdown .menu-item-has-children > a { flex: 1 1 auto; }
  .psc-menu--dropdown .sub-menu {
    position: static;
    flex-basis: 100%;
    min-width: 0;
    box-shadow: none;
    border-width: 0 0 0 3px;
    margin: 0 0 6px var(--wp--preset--spacing--30);
  }
}

/* ---- bouton « Menu » (burger) ----
   Rendu `hidden` par le serveur, revele par menu.js : sans script, il n'existe
   pas et la liste reste depliee. Masque sur grand ecran dans tous les cas. */
.psc-menu__burger { display: none; }
@media (max-width: 48rem) {
  .psc-menu--burger .psc-menu__burger:not([hidden]) {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    position: absolute;
    top: 12px;
    right: var(--wp--style--root--padding-right, 16px);
    min-height: 44px;
    padding: 0 12px;
    font-family: var(--wp--preset--font-family--display);
    font-weight: 700;
    font-size: 16px;
    text-transform: uppercase;
    color: var(--wp--preset--color--ink);
    background: var(--wp--preset--color--paper);
    border: 3px solid var(--wp--preset--color--ink);
    cursor: pointer;
  }
  .psc-menu__burger:focus-visible { outline: 3px solid var(--wp--preset--color--blue-deep); outline-offset: 2px; }
  /* Trois barres dessinees en CSS : aucune image, aucune police d'icones. */
  .psc-menu__bars, .psc-menu__bars::before, .psc-menu__bars::after {
    display: block; width: 18px; height: 3px; background: currentColor; content: "";
  }
  .psc-menu__bars { position: relative; }
  .psc-menu__bars::before { position: absolute; top: -6px; }
  .psc-menu__bars::after  { position: absolute; top: 6px; }
  /* Ouvert : les barres deviennent une croix. L'etat est aussi porte par
     aria-expanded, lu par les lecteurs d'ecran (jamais la forme seule). */
  .psc-menu--burger.is-open .psc-menu__bars { background: transparent; }
  .psc-menu--burger.is-open .psc-menu__bars::before { top: 0; transform: rotate(45deg); }
  .psc-menu--burger.is-open .psc-menu__bars::after  { top: 0; transform: rotate(-45deg); }

  .psc-menu--burger .psc-menu__list { display: none; }
  .psc-menu--burger.is-open .psc-menu__list {
    display: flex;
    padding: 4px 0 8px;
    border-bottom: 3px solid var(--wp--preset--color--ink);
  }
}

/* Bandeau de reassurance : les emplacements d'image sont vides dans la
   composition, donc `img` sans `src`. On leur reserve une hauteur pour que la
   mise en page ne saute pas quand les logos seront choisis (pas de CLS). */
.psc-reassurance .psc-reassurance__logo img { max-height: 44px; width: auto; object-fit: contain; }
.psc-reassurance .psc-reassurance__logo { min-height: 44px; margin: 0; }
@media (max-width: 781px) {
  .psc-reassurance { flex-direction: row !important; flex-wrap: wrap !important; }
  .psc-reassurance > .wp-block-column { flex-basis: 45% !important; }
}

.psc-menu__vide {
  padding: 10px 12px;
  border: 2px dashed currentColor;
  opacity: .7;
  font-size: var(--wp--preset--font-size--s);
}

/* ------------------------------------------------- 3. SIGNATURE VISUELLE */

/* Bordure + ombre dure. Utilisable depuis l'editeur via les styles de bloc
   « Encadre » et « Encadre fin » declares dans functions.php. */
.psc-hard {
  border: 3px solid var(--wp--preset--color--ink);
  box-shadow: 7px 7px 0 var(--wp--preset--color--ink);
}
.psc-hard--sm { box-shadow: 4px 4px 0 var(--wp--preset--color--ink); }

/* OU VIT LA CLASSE SUR UN BOUTON, ET POURQUOI CES SELECTEURS ONT CHANGE.
   Le bloc `core/button` met son `className` sur le <div> conteneur, jamais
   sur le <a> : verifie dans la fonction `save` de wp-includes/js/dist/
   block-library.min.js, ou seules `wp-block-button__link`, les classes de
   couleur, de bordure, de typographie et `has-custom-font-size` sont
   assemblees pour le lien. Mon balisage ecrivait `psc-hard` sur les DEUX,
   et l'editeur affichait « Le bloc contient du contenu invalide » avec une
   proposition de recuperation — sur les six boutons du theme, pas seulement
   celui de l'en-tete.

   Le balisage est donc revenu au canon, et le CSS doit suivre : la classe
   est sur le conteneur, l'habillage doit rester sur le lien, qui est le seul
   element visible. On neutralise donc `.psc-hard` sur le conteneur et on
   pose l'ombre sur le lien.

   La BORDURE, elle, n'est pas reprise ici : elle vient deja de
   theme.json (`styles.elements.button.border`, 3 px ink) pour tous les
   boutons. `.psc-hard` n'ajoute que l'ombre dure. */
.wp-block-button.psc-hard {
  border: 0;
  box-shadow: none;
}
.wp-block-button.psc-hard > .wp-block-button__link {
  box-shadow: 7px 7px 0 var(--wp--preset--color--ink);
  /* Le bouton s'enfonce au survol. Transformation uniquement : pas de
     reflow, donc aucun impact CLS. */
  transition: transform .12s ease, box-shadow .12s ease;
}
.wp-block-button.psc-hard > .wp-block-button__link:hover,
.wp-block-button.psc-hard > .wp-block-button__link:focus-visible {
  transform: translate(4px, 4px);
  box-shadow: 2px 2px 0 var(--wp--preset--color--ink);
}

/* Badge d'accroche : un paragraphe qui ne prend que la largeur de son texte. */
/* « LIRE LA SUITE » DES CARTES D'ARTICLES.
   Un lien de texte, pas un bouton : il y a douze cartes par page, douze
   boutons pleins noieraient le titre, qui reste le lien principal. Gras et
   souligne pour qu'il se lise comme une action sans dependre de la couleur
   (WCAG 1.4.1). Le rembourrage vertical porte la zone cliquable a 24 px au
   moins (WCAG 2.5.8) sans changer l'aspect. Le titre de l'article est ajoute
   en texte masque par functions.php, pour les lecteurs d'ecran. */
.wp-block-post-excerpt__more-text { margin-top: 10px; }
.wp-block-post-excerpt__more-link {
  display: inline-block;
  padding-block: 4px;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* TAILLE DU BOUTON « DEVIS INSTANTANE ». Elle etait ecrite en style en ligne
   dans parts/header.html, ce qui obligeait a reproduire a la main la
   serialisation exacte de core/button — la source meme du bloc invalide.
   Elle vit maintenant ici : un gabarit de thème ne contient plus que du
   balisage canonique, et la moindre retouche de l'editeur ne peut plus le
   faire diverger. Les valeurs sont celles d'avant (11/18 px, 16 px), qui
   resserrent le bouton par rapport aux 15/26 px de theme.json pour qu'il
   tienne sur une seule ligne d'en-tete. */
header.wp-block-group .wp-block-button__link {
  padding: 11px 18px;
  font-size: 16px;
}

.psc-badge {
  display: inline-block;
  padding: 6px 12px;
  letter-spacing: .08em;
}

/* Lien d'action d'une carte produit. Un lien de 20 px de haut dans un
   paragraphe reste sous les 24 px demandes par WCAG 2.5.8 ; l'exception des
   liens « en ligne dans une phrase » ne s'applique pas ici, puisque celui-ci
   est seul dans son paragraphe et joue le role d'un bouton. On lui donne donc
   une vraie hauteur de cible, sans le deguiser en bouton. */
.psc-cta-link a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  text-underline-offset: 3px;
}

/* Reserve visuelle en attendant les photos produit. La proportion est
   explicite : la place est prise avant le chargement, donc pas de CLS.
   (L'ancienne regle aspect-ratio:attr(width)/attr(height) ne fonctionnait
   dans aucun navigateur : attr() n'est pas utilisable hors de content.) */
.psc-slot {
  aspect-ratio: var(--psc-slot-ratio, 63 / 88);
  background-color: #EDEAE1;
  background-image: repeating-linear-gradient(45deg, #DCD8CD 0 10px, #EDEAE1 10px 20px);
}


/* --------------------------------------------------- 4. LISTES ET TABLEAUX */

/* Liste de garanties : une vraie <ul> (la structure est annoncee : « liste de
   4 elements »), mais sans puces ni retrait, en ligne sur grand ecran. */
.psc-inline-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 10px var(--wp--preset--spacing--50);
}
.psc-inline-list > li { margin: 0; }

/* Liste de liens empiles — pied de page, sommaires. Chaque lien occupe toute
   la largeur et 44 px de haut : la cible est confortable au doigt (WCAG 2.5.8)
   et la zone cliquable ne se limite plus a la hauteur du texte, ce qui est la
   premiere cause de clics rates sur mobile. */
.psc-link-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.psc-link-list > li { margin: 0; }
.psc-link-list a {
  display: flex;
  align-items: center;
  min-height: 44px;
  text-underline-offset: 3px;
}

/* Un tableau large doit pouvoir defiler horizontalement sans que la PAGE
   defile (WCAG 1.4.10). role="region" + tabindex sont poses en PHP pour que
   la zone soit atteignable au clavier. */
.wp-block-table {
  overflow-x: auto;
  max-width: 100%;
}
.wp-block-table table { border-collapse: collapse; width: 100%; }
.wp-block-table :is(th, td) {
  border: 1px solid var(--wp--preset--color--ink);
  padding: 10px 12px;
  text-align: left;
}
.wp-block-table thead th {
  background: var(--wp--preset--color--ink);
  color: var(--wp--preset--color--cream);
  font-family: var(--wp--preset--font-family--display);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.wp-block-table caption {
  caption-side: top;
  text-align: left;
  padding: 0 0 8px;
  font-weight: 600;
}
.wp-block-table[data-psc-scroll]:focus-visible { outline-offset: 0; }


/* --------------------------- 4 bis. BOUTONS QUI NE VIENNENT PAS DE GUTENBERG

   theme.json ne style que `wp-element-button`, c'est-a-dire les boutons du
   contenu. Les boutons rendus par les plugins n'ont donc RIEN : ils sortaient
   avec l'apparence par defaut du navigateur — un petit rectangle gris, ce qui
   n'est ni lisible ni engageant sur une page d'achat.

   PORTEE VOLONTAIREMENT ETROITE. On nomme les classes une par une au lieu de
   styler `button`, parce que le configurateur (`.psp`) utilise des boutons
   comme TUILES DE CHOIX — format, papier, finition. Leur donner l'apparence
   d'un bouton d'action rendrait l'ecran illisible : on ne saurait plus ce qui
   valide et ce qui selectionne. */
.psc-sumup-btn,
.wpcf7-submit,
.wpcf7 input[type="submit"],
.psc-btn--primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 52px;
  padding: 14px 26px;
  font-family: var(--wp--preset--font-family--display);
  font-size: var(--wp--preset--font-size--l);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1.2;
  text-decoration: none;
  color: var(--wp--preset--color--on-accent);
  background: var(--wp--preset--color--blue);
  border: 3px solid var(--wp--preset--color--ink);
  border-radius: 0;
  box-shadow: 7px 7px 0 var(--wp--preset--color--ink);
  cursor: pointer;
  transition: transform .12s ease, box-shadow .12s ease, background-color .12s ease;
}
.psc-sumup-btn:hover,
.wpcf7-submit:hover,
.wpcf7 input[type="submit"]:hover,
.psc-btn--primary:hover,
.psc-sumup-btn:focus-visible,
.wpcf7-submit:focus-visible,
.psc-btn--primary:focus-visible {
  background: var(--wp--preset--color--blue-deep);
  transform: translate(4px, 4px);
  box-shadow: 2px 2px 0 var(--wp--preset--color--ink);
}
/* Un bouton d'achat merite toute la largeur de sa carte : c'est la cible la
   plus importante de la page, la chercher des yeux est du temps perdu.
   Plafonne tout de meme : mesure a 1 440 px, sans `max-width` il atteignait
   1 380 px de large, ce qui ne ressemble plus a un bouton. */
.psc-sumup-btn { width: 100%; max-width: 420px; }

/* Bouton secondaire du plugin (retour, annuler) : meme forme, moins d'appel. */
.psc-btn:not(.psc-btn--primary),
.psc-back {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 12px 20px;
  font-family: var(--wp--preset--font-family--display);
  font-weight: 700;
  text-transform: uppercase;
  color: var(--wp--preset--color--ink);
  background: var(--wp--preset--color--paper);
  border: 3px solid var(--wp--preset--color--ink);
  border-radius: 0;
  cursor: pointer;
}

@media (prefers-reduced-motion: reduce) {
  .psc-sumup-btn, .wpcf7-submit, .psc-btn--primary { transition: none; }
  .psc-sumup-btn:hover, .wpcf7-submit:hover, .psc-btn--primary:hover { transform: none; }
}


/* ----------------------------------- 4 ter. LIEN PANIER (press-start-commerce)
   Le plugin fournit `[psc_cart_link]` : un lien avec une pastille de comptage
   ecrite par le navigateur. Le theme lui donne l'apparence d'un bouton
   secondaire. La pastille n'est PAS le seul porteur de l'information — le lien
   dit « Panier, 2 articles » en texte — donc rien ne repose sur la couleur
   seule (RGAA 3.1). */
.psc-cart-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 8px 14px;
  font-family: var(--wp--preset--font-family--display);
  font-weight: 700;
  font-size: 16px;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--wp--preset--color--ink);
  background: var(--wp--preset--color--paper);
  border: 3px solid var(--wp--preset--color--ink);
}
.psc-cart-link:hover { background: var(--wp--preset--color--yellow); }
.psc-cart-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 24px;
  padding: 0 6px;
  font-size: 13px;
  color: var(--wp--preset--color--on-accent);
  background: var(--wp--preset--color--red);
  border: 2px solid var(--wp--preset--color--ink);
}
.psc-cart-badge[hidden] { display: none; }

/* Lien de compte `[psc_account_link]` : « Se connecter » ou « Mon compte ».
   Action secondaire, donc sans cadre : meme police et meme cible tactile de
   44 px que le panier, mais il ne lui dispute pas l'attention. Soulignement
   permanent : un lien doit se reconnaitre autrement que par la couleur. */
.psc-account-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 6px;
  font-family: var(--wp--preset--font-family--display);
  font-weight: 700;
  font-size: 16px;
  text-transform: uppercase;
  color: var(--wp--preset--color--ink);
  text-decoration: underline;
  text-underline-offset: 4px;
}
.psc-account-link:hover { text-decoration-thickness: 3px; }


/* ------------------------------------------ 4 quater. LARGEUR DU CONFIGURATEUR
   Le configurateur se cale sur `max-width: 1120px` dans son propre CSS. Sur le
   gabarit « Configurateur d'impression », qui n'impose aucune contrainte, on
   lui laisse toute la largeur utile du theme : ses deux colonnes (choix a
   gauche, recapitulatif a droite) respirent nettement mieux. */
/* Ce gabarit est en layout « par defaut » (aucune contrainte de largeur), il
   ne recoit donc pas `has-global-padding` de WordPress. On lui applique les
   MEMES gouttieres, pour qu'il suive la regle des 80 % comme le reste du
   site : le configurateur avait sinon une gouttiere fixe de 22 px, soit une
   largeur differente de toutes les autres pages sur telephone. */
.psc-full {
  padding-inline: var(--wp--style--root-padding-left, var(--wp--preset--spacing--40));
}
.psc-full .psp { max-width: 1520px; margin-inline: auto; }

/* Mais le TEXTE tape directement dans la page, lui, garde sa colonne de
   lecture : sans cette regle, un paragraphe du gabarit pleine largeur
   s'etirait sur 5076 px sur un ecran 32:9 (mesure). On ne cible que les
   enfants DIRECTS du contenu : le configurateur est insere par un bloc
   « Code court », dont la sortie (`div.psp`) est elle aussi un enfant direct
   mais n'est pas dans cette liste — il conserve donc toute la largeur. Un
   bloc que tu grouperais toi-meme n'est pas touche non plus. */
.psc-full .wp-block-post-content > :where(p, h2, h3, h4, h5, h6, ul, ol, dl, blockquote) {
  max-width: var(--wp--style--global--content-size, 860px);
  margin-inline: auto;
}
/* Et on annule l'heritage de coupure de mots dans cette interface. */
.psp, .psp * { overflow-wrap: normal; hyphens: manual; }


/* ------------------------------------------------------- 5. FORMULAIRES */

/* Contact Form 7 et le champ de recherche : bordure visible, hauteur de cible
   suffisante, et surtout un libelle toujours associe — un champ sans libelle
   visible est un echec RGAA 11.1 que le CSS ne peut pas reparer. */
input:not([type="submit"]):not([type="checkbox"]):not([type="radio"]),
select,
textarea {
  font: inherit;
  color: var(--wp--preset--color--ink);
  background: var(--wp--preset--color--paper);
  border: 3px solid var(--wp--preset--color--ink);
  border-radius: 0;
  padding: 11px 13px;
  min-height: 44px;
  width: 100%;
  max-width: 100%;
}
input[type="checkbox"],
input[type="radio"] { width: 22px; height: 22px; accent-color: var(--wp--preset--color--blue); }

/* ---- Contact Form 7 ----
   CF7 ne fournit presque aucun style : sans ca, le formulaire sort en
   paragraphes colles avec un bouton d'envoi gris du systeme. */
.wpcf7-form { max-width: 620px; }
.wpcf7-form p { margin: 0 0 18px; }
.wpcf7-form label {
  display: block;
  font-weight: 600;
  margin-bottom: 6px;
}
/* CF7 place le champ DANS le label, separe par un <br>. On retire ce saut de
   ligne au profit d'un espacement reel : un <br> ne se regle pas. */
.wpcf7-form label br { display: none; }
.wpcf7-form-control-wrap { display: block; }
.wpcf7-form textarea { min-height: 180px; resize: vertical; }

/* Champ obligatoire : signale par le texte du libelle, pas par une couleur.
   CF7 n'ajoute pas d'asterisque automatiquement — a mettre dans le libelle du
   champ cote back-office, et a expliquer une fois en haut du formulaire. */
.wpcf7-form .psc-form-note { font-size: var(--wp--preset--font-size--s); }

/* Retour apres envoi. `aria-live` est pose par CF7 ; on ajoute un liseré
   epais pour que le message ne soit pas identifiable a sa seule couleur
   (RGAA 3.1) et une marge pour qu'il ne colle pas au bouton. */
.wpcf7-response-output {
  margin: 18px 0 0 !important;
  padding: 14px 16px !important;
  border: 3px solid var(--wp--preset--color--ink) !important;
  border-left-width: 8px !important;
  background: var(--wp--preset--color--paper);
  font-weight: 600;
}
.wpcf7 form.sent .wpcf7-response-output { border-left-color: var(--wp--preset--color--green); }
.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.unaccepted .wpcf7-response-output,
.wpcf7 form.failed .wpcf7-response-output { border-left-color: var(--wp--preset--color--red); }
.wpcf7-spinner { margin: 0 0 0 12px; }

/* Un champ en erreur ne doit pas l'indiquer par la seule couleur
   (RGAA 3.1 / WCAG 1.4.1) : d'ou le liseré epais ET le message texte de CF7. */
.wpcf7-not-valid { border-color: var(--wp--preset--color--red); border-width: 4px; }
.wpcf7-not-valid-tip { font-weight: 600; color: var(--wp--preset--color--red); }

/* Le pied de page inverse ses couleurs : un survol qui change la TEINTE y
   serait juste pour une variante et faux pour l'autre. On epaissit le
   soulignement — lisible quel que soit le fond, et ce n'est pas un signal
   porte par la seule couleur (RGAA 3.1). */
.wp-block-template-part footer a:hover,
.wp-block-template-part footer a:focus-visible {
  text-decoration-thickness: 3px;
  text-underline-offset: 3px;
}

.wp-block-search__input { border-right-width: 0; }
.wp-block-search__button {
  font-family: var(--wp--preset--font-family--display);
  font-weight: 700;
  text-transform: uppercase;
  background: var(--wp--preset--color--blue);
  color: var(--wp--preset--color--paper);
  border: 3px solid var(--wp--preset--color--ink);
  padding: 0 20px;
  cursor: pointer;
}


/* ----------------------------------------------------------- 6. ADAPTATIF */

/* ---- 6.0 GOUTTIERES : LE CONTENU A 80 % DE LA LARGEUR D'ECRAN ----------
   Demande : sur telephone et tablette, tout s'empile en occupant 80 % de la
   largeur d'ecran. Comme `useRootPaddingAwareAlignments` est actif, il suffit
   de redefinir les deux proprietes de gouttiere : WordPress les applique
   lui-meme a tous les blocs en layout contraint (`.has-global-padding`) et
   remet a zero celles des blocs imbriques. Une seule regle suffit donc, sans
   toucher un seul gabarit ni une seule composition.

   POURQUOI UN `min()` ET PAS UN SIMPLE `10%`. A 80 % de large, un ecran de
   320 px ne laisse que 256 px de contenu : moins que la largeur de reference
   du critere WCAG 1.4.10 (reflow a 320 px), et trop peu pour un tableau ou
   pour deux cibles tactiles de 44 px cote a cote. `50% - 144px` borne la
   gouttiere de sorte que le contenu ne descende jamais sous 288 px :

     largeur ecran   gouttiere retenue         contenu
       320 px        min(32, 16)  =  16 px      288 px  (plancher)
       360 px        min(36, 36)  =  36 px      288 px  (bascule)
       390 px        min(39, 51)  =  39 px      312 px  (= 80 %)
       768 px        min(77, 240) =  77 px      614 px  (= 80 %)
      1024 px        min(102,368) = 102 px      819 px  (= 80 %)

   La regle des 80 % est donc respectee partout ou elle laisse la place, et
   degrade proprement en dessous — jamais l'inverse. Si tu preferes 80 %
   strict jusqu'en bas, il suffit de retirer le `min()` : deux valeurs a
   remplacer par `10%`, rien d'autre.

   A NOTER : un pourcentage se resout sur la largeur du bloc racine, c'est-a-
   dire la fenetre MOINS la barre de defilement quand elle occupe de la place
   (bureau). Sur telephone et tablette, ou la barre est en surimpression, la
   largeur du contenu vaut donc exactement 80 % de l'ecran ; sur un
   navigateur de bureau redimensionne, 80 % de la zone reellement disponible.
   C'est le comportement voulu, pas un ecart.

   La seconde condition sur le pointeur est expliquee en 6.1. */
@media (max-width: 1199.98px), (hover: none) and (pointer: coarse) and (max-width: 1400px) {
  :root {
    --wp--style--root-padding-right: min(10%, 50% - 144px);
    --wp--style--root-padding-left:  min(10%, 50% - 144px);
  }
}

/* ---- 6.1 EMPILEMENT SUR TABLETTE --------------------------------------
   WordPress empile les colonnes sous 782 px, c'est-a-dire en portrait
   seulement : une tablette en paysage (1024 x 768) gardait deux ou trois
   colonnes de 250 px. La demande est que tablette ET telephone empilent : on
   remonte le seuil a 1024 px. Meme mecanique que le noyau (`flex-wrap` +
   `flex-basis`), y compris le respect de l'option « Ne pas empiler sur
   mobile » de l'editeur, qui reste prioritaire.

   POURQUOI UNE SECONDE CONDITION SUR LE POINTEUR. Une largeur seule ne
   permet pas de distinguer un iPad Pro en paysage (1194 ou 1366 px) d'un
   ordinateur portable 1366 x 768 : ce sont les memes pixels CSS. La
   condition `(hover: none) and (pointer: coarse)` identifie un ecran
   tactile sans survol — telephone ou tablette. Resultat : toute tablette
   empile jusqu'a 1400 px, et le portable 1366 px garde ses colonnes. C'est
   la seule facon de tenir la demande sans penaliser les PC. */
@media (max-width: 1024.98px), (hover: none) and (pointer: coarse) and (max-width: 1400px) {
  .wp-block-columns:not(.is-not-stacked-on-mobile) { flex-wrap: wrap !important; }
  .wp-block-columns:not(.is-not-stacked-on-mobile) > .wp-block-column {
    flex-basis: 100% !important;
  }
  /* Les grilles a colonnes du theme suivent le meme sort : la liste de liens
     du pied de page, et la grille d'articles de la boucle de requete — celle-
     ci n'est pas un bloc « Colonnes », la regle ci-dessus ne l'atteint pas.
     Mesure avant correction : 3 colonnes de 355 px sur tablette a 1024 px, et
     de 246 px sur un ecran 1280. */
  .psc-link-list { grid-template-columns: 1fr; }
  .wp-block-post-template.is-layout-grid { grid-template-columns: 1fr !important; }
}

/* ---- 6.2 ECRANS TRES LARGES : QHD, 4K, 21:9, 29:9, 32:9 ---------------
   Le texte reste en colonne de lecture (860 px, environ 96 caracteres) : le
   deployer davantage degrade la lecture, ce n'est pas un gain. En revanche
   les surfaces d'OUTIL — configurateur, grilles de catalogue, tableaux de
   tarifs — gagnent reellement de la largeur. On leve leur borne de facon
   progressive, avec un plafond a 2200 px : au-dela, suivre une ligne d'un
   bord a l'autre d'un ecran 32:9 (5120 px) demande un mouvement de tete.
   `88vw` garde une marge visuelle sur les resolutions intermediaires. */
@media (min-width: 1800px) {
  .psc-full .psp,
  .psc-full .wp-block-group.alignwide,
  .psc-full .wp-block-columns.alignwide,
  .psc-full .wp-block-table.alignwide { max-width: min(2200px, 88vw); }
}


/* En paysage sur telephone, un en-tete collant mange le peu de hauteur
   disponible : on le decolle sous 520 px de haut. */
@media (max-height: 520px) {
  .wp-block-template-part > header.wp-block-group { position: static !important; }
  html { --psc-sticky: 0px; }
}

/* En-tete sur telephone : titre sur une ligne, puis menu, puis les deux
   actions en pleine largeur. Empile, les elements gardaient leur largeur
   naturelle et le bouton « Devis » se retrouvait seul a gauche, minuscule au
   milieu du vide. */
@media (max-width: 48rem) {
  /* Le bouton « Menu » se place en haut a droite de l'en-tete : l'en-tete
     devient son repere. Replie, l'en-tete tient en deux lignes (titre, puis
     les actions) : il n'est plus collant, pour ne pas manger l'ecran. */
  .wp-block-template-part > header.wp-block-group,
  header.wp-block-group { position: relative !important; top: auto !important; }
  header.wp-block-group .wp-block-site-title { padding-right: 120px; min-height: 44px; display: flex; align-items: center; }
  header.wp-block-group > .wp-block-group { align-items: stretch; }
  header.wp-block-group .wp-block-group { row-gap: 10px; }
  header.wp-block-group .wp-block-buttons,
  header.wp-block-group .wp-block-button,
  header.wp-block-group .wp-block-button__link,
  header.wp-block-group .psc-cart-link { width: 100%; }
  header.wp-block-group .wp-block-button__link,
  header.wp-block-group .psc-cart-link,
  header.wp-block-group .psc-account-link { justify-content: center; }
  header.wp-block-group .psc-account-link { width: 100%; }
  /* L'ombre dure de 7 px depasse a droite sur un bouton pleine largeur. */
  header.wp-block-group .wp-block-button.psc-hard > .wp-block-button__link {
    box-shadow: 4px 4px 0 var(--wp--preset--color--ink);
  }
}

@media (max-width: 781px) {
  html { --psc-sticky: 64px; }
}
@media (max-width: 48rem) {
  html { --psc-sticky: 0px; }   /* en-tete non collant sur telephone */
}
@media (max-width: 781px) {
  /* Les colonnes du pied de page s'empilent : on resserre l'interligne. */
  .psc-inline-list { gap: 8px var(--wp--preset--spacing--40); }
}


/* -------------------------------------------------- 7. MOUVEMENT REDUIT */

/* Cible uniquement les animations DU THEME. L'ancienne regle
   *{animation:none!important} coupait aussi les transitions legitimes des
   plugins — bandeau de consentement, retours du configurateur — et retirait
   des retours visuels utiles. */
@media (prefers-reduced-motion: reduce) {
  .wp-block-button.psc-hard > .wp-block-button__link { transition: none; }
  .wp-block-button.psc-hard > .wp-block-button__link:hover,
  .wp-block-button.psc-hard > .wp-block-button__link:focus-visible { transform: none; }
  html { scroll-behavior: auto; }
}


/* --------------------------------------------------------- 8. IMPRESSION */

/* Une boutique d'impression dont les pages s'impriment mal, c'est dommage.
   On retire les fonds sombres et les ombres, on developpe les FAQ, et on
   expose les URL des liens. */
@media print {
  .skip-link,
  .wp-block-navigation,
  .wp-block-search,
  .psu-marquee { display: none !important; }
  .psc-hard, .psc-hard--sm { box-shadow: none !important; }
  .has-ink-background-color { background: none !important; color: #000 !important; }
  details { display: block; }
  details > *:not(summary) { display: block !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .85em; }
  body { background: #fff; color: #000; }
}
