/* ==================================================================
   Panier flottant Glassora — pastille, feuille, loupe du bon a graver
   ==================================================================

   POURQUOI CETTE FEUILLE EXISTE
   La pastille et la feuille du panier vivaient dans l'atelier, et leur
   habillage dans les feuilles de l'atelier (configurator-glassora.css,
   -mobile.css, -desktop.css), chargees sur cette seule page. Le balisage est
   desormais imprime sur tout le site (Glassora_Cart::print_mini_cart) : il lui
   faut un habillage qui voyage avec lui.

   REGLE DE COHABITATION
   Cette feuille est chargee AUSSI sur la page de l'atelier — la loupe du bon a
   graver est nouvelle et n'existe dans aucune autre feuille. Les regles
   reprises de configurator-glassora.css le sont donc a l'IDENTIQUE, valeur
   pour valeur : quel que soit l'ordre de chargement, le rendu est le meme.
   Les couches de l'atelier (html.gm / html.gd) gardent la main partout, leur
   specificite etant superieure (`html.gm .gm__bar .gl-cart-pill`).
   Les doublons sont assumes et listes dans le compte rendu du lot.

   JETONS : ceux du socle du theme (assets/css/base.css), qui est charge sur
   toutes les pages. --gold-ink est le SEUL or admis pour du texte sur fond
   clair ; --gold reste aux filets, aux ornements et aux fonds sombres.
   ================================================================== */

/* --- Utilitaire ---------------------------------------------------
   La classe d'accessibilite de l'atelier (`bg-configurator__sr-only`)
   n'existe que dans ses feuilles : hors de lui, les libelles reserves aux
   lecteurs d'ecran s'afficheraient en clair dans la pastille. */

.gl-sr-only {
	position: absolute !important;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect( 0 0 0 0 );
	clip-path: inset( 50% );
	white-space: nowrap;
	border: 0;
}

/* ==================================================================
   1. Pastille (recopie de configurator-glassora.css §44)
   ================================================================== */

.gl-cart-pill {
	display: flex;
	width: max-content;
	max-width: 100%;
	align-items: center;
	gap: 8px;
	min-height: 40px;
	padding: 0 14px 0 11px;
	border: 1px solid var( --line, #ECEBE7 );
	border-radius: 999px;
	background: rgba( 255, 255, 255, .88 );
	-webkit-backdrop-filter: blur( 18px ) saturate( 180% );
	backdrop-filter: blur( 18px ) saturate( 180% );
	box-shadow: var( --shadow-soft, 0 10px 30px rgba( 0, 0, 0, .06 ) );
	color: var( --ink, #111827 );
	font-family: var( --head, 'Manrope', sans-serif );
	font-size: .8rem;
	font-weight: 700;
	letter-spacing: .01em;
	line-height: 1;
	text-decoration: none;
	white-space: nowrap;
	transition: transform .2s var( --ease, ease ), box-shadow .2s var( --ease, ease ), border-color .2s var( --ease, ease );
}

/* `hidden` doit gagner : sans cela le `display:flex` ci-dessus ecrase le
   `display:none` de l'agent utilisateur. */
.gl-cart-pill[hidden] { display: none !important; }

.gl-cart-pill:hover,
.gl-cart-pill:focus-visible {
	border-color: var( --gold, #C8A96A );
	box-shadow: 0 12px 30px rgba( 17, 24, 39, .12 );
	transform: translateY( -1px );
}

.gl-cart-pill:focus-visible {
	outline: 2px solid var( --gold-ink, #7A6224 );
	outline-offset: 2px;
}

.gl-cart-pill__icon {
	display: grid;
	place-items: center;
	width: 18px;
	height: 18px;
	color: var( --muted, #5F6470 );
}

.gl-cart-pill__icon svg { display: block; }

.gl-cart-pill__count {
	min-width: 20px;
	height: 20px;
	padding: 0 6px;
	display: grid;
	place-items: center;
	border-radius: 999px;
	background: linear-gradient( 120deg, var( --gold, #C8A96A ), var( --champ, #E6D4A3 ) );
	color: var( --lux, #0B1220 );
	font-size: .72rem;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

.gl-cart-pill__total {
	color: var( --gold-ink, #7A6224 );
	font-variant-numeric: tabular-nums;
}

/* Panier vide : le COMPTE et le TOTAL s'effacent, la pastille RESTE. Elle est
   la porte d'entree du panier — la retirer quand il est vide revient a retirer
   la commande, et se lit comme une panne. L'attribut plutot qu'un
   `:has(:empty)` : les moteurs ne reevaluent pas toujours `:has()` quand seul
   le TEXTE d'un descendant change. */
.gl-cart-pill__count:empty,
.gl-cart-pill__total:empty,
.gl-cart-pill[data-vide] .gl-cart-pill__count,
.gl-cart-pill[data-vide] .gl-cart-pill__total {
	display: none !important;
}

/* --- HORS DES COQUES DE L'ATELIER : PAS DE PASTILLE ---------------
   Elle flottait en bas a droite de chaque page. Or l'icone panier de
   l'en-tete ouvre exactement la meme feuille (cf. le clic sur `.nav-cart`
   dans glassora-cart.js) : deux portes visibles en meme temps pour une seule
   piece. Le PHP ne l'imprime donc plus que sur la page de l'atelier.

   Cette regle couvre ce que le PHP ne peut pas voir : dans l'atelier, entre
   721 et 1180 px, aucune coque ne se monte (ni `.gm` ni `.gd`), la pastille
   resterait dans le flux du pied de page. Or a cette largeur l'en-tete du
   theme est bien la, avec son icone panier — la pastille n'a rien a y faire.

   Elle reste donc visible dans le SEUL cas ou elle sert : sous une coque,
   rangee dans `.gm__bar` / `.gd-topbar`, la ou l'en-tete du site est masque.
   Et la regle porte sur `body > ` : une fois rangee dans la barre, la
   pastille n'est plus un enfant direct du body, rien ne peut la masquer. */
html:not( .gm ):not( .gd ) body > .gl-cart-pill {
	display: none;
}

/* Le temps que la coque de l'atelier se monte et que le JS y range la
   pastille. `visibility` et non `display` : la mesure de placement reste
   possible. Toujours retiree ensuite, meme si le placement echoue — cf.
   `retenirPastille()` dans glassora-cart.js. */
.gl-cart-pill--en-attente { visibility: hidden; }

/* ==================================================================
   2. Feuille du panier (recopie de configurator-glassora.css §46)
   ================================================================== */

.gl-cart-sheet {
	position: fixed;
	inset: 0;
	z-index: 9500;
	display: flex;
	align-items: flex-end;
	justify-content: center;
}

.gl-cart-sheet[hidden] { display: none !important; }

.gl-cart-sheet__voile {
	position: absolute;
	inset: 0;
	background: rgba( 11, 18, 32, .38 );
	backdrop-filter: blur( 2px );
	-webkit-backdrop-filter: blur( 2px );
}

.gl-cart-sheet__panel {
	position: relative;
	display: flex;
	flex-direction: column;
	width: 100%;
	max-width: 520px;
	max-height: 82vh;
	background: var( --surface, #FFFFFF );
	border-radius: var( --r-card, 20px ) var( --r-card, 20px ) 0 0;
	box-shadow: 0 -12px 40px rgba( 17, 24, 39, .18 );
	/* PAS de `both` : le mode de remplissage figeait le panneau 14 px sous
	   l'ecran et rognait le bouton de commande. */
	transform: none;
	animation: gl-cart-sheet-monte .22s var( --ease, ease );
}

@keyframes gl-cart-sheet-monte {
	from { transform: translateY( 14px ); opacity: 0; }
	to   { transform: none; opacity: 1; }
}

/* --- GRAND ECRAN : la feuille se pose SOUS son declencheur ----------
   En bas de l'ecran, pleine largeur, coins arrondis vers le haut : c'est le
   geste du telephone, ou le pouce vit en bas et ou l'ecran est trop etroit
   pour autre chose. Sur un 1440, la meme feuille partait se coller a 900 px
   de l'icone qu'on venait de cliquer, tout en bas — le lien entre le geste
   et sa reponse etait rompu, et le regard devait traverser la page.

   Elle s'ancre donc sous ce qu'on a clique. Les deux variables sont posees
   en JS a l'ouverture (`ancrerFeuille`), a partir de la mesure reelle du
   declencheur : l'en-tete du site et la barre de l'atelier ne sont ni a la
   meme hauteur ni a la meme marge. Les valeurs de repli ci-dessous ne
   servent que si la mesure echoue.

   Le voile reste celui du mobile — sombre et flou, a la demande. Il porte
   le clic hors de la feuille, qui la ferme. */
@media ( min-width: 721px ) {
	.gl-cart-sheet {
		align-items: flex-start;
		justify-content: flex-end;
	}

	.gl-cart-sheet__panel {
		width: min( 420px, calc( 100vw - 24px ) );
		max-width: none;
		margin: var( --gl-sheet-haut, 118px ) var( --gl-sheet-droite, 24px ) 0 0;
		/* Ce qui reste sous le declencheur, moins une respiration en bas. Le
		   contenu defile a l'interieur : le panneau ne pousse jamais son
		   bouton de commande hors de l'ecran. */
		max-height: calc( 100vh - var( --gl-sheet-haut, 118px ) - 24px );
		border-radius: var( --r-card, 20px );
		/* L'ombre descend, puisque le panneau descend. */
		box-shadow: 0 24px 60px rgba( 17, 24, 39, .18 );
		animation: gl-cart-sheet-descend .18s var( --ease, ease );
	}

	@keyframes gl-cart-sheet-descend {
		from { transform: translateY( -10px ); opacity: 0; }
		to   { transform: none; opacity: 1; }
	}
}

.gl-cart-sheet__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 12px 18px 10px;
	border-bottom: 1px solid var( --line, rgba( 17, 24, 39, .1 ) );
}

.gl-cart-sheet__title {
	margin: 0;
	color: var( --ink, #111827 );
	font-family: var( --head, inherit );
	font-size: 1rem;
	font-weight: 700;
	letter-spacing: .01em;
}

.gl-cart-sheet__close {
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	background: transparent;
	border: 0;
	border-radius: 999px;
	color: var( --muted, #5F6470 );
	cursor: pointer;
}

.gl-cart-sheet__close:hover { background: var( --off, rgba( 17, 24, 39, .05 ) ); }

.gl-cart-sheet__lines {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: 6px 18px;
}

.gl-cart-sheet__vide {
	margin: 22px 0;
	color: var( --muted, #5F6470 );
	font-size: .9rem;
	text-align: center;
}

.gl-cart-line {
	display: grid;
	grid-template-columns: 58px 1fr;
	gap: 12px;
	padding: 14px 0;
	border-bottom: 1px solid var( --line, rgba( 17, 24, 39, .08 ) );
}

.gl-cart-line:last-child { border-bottom: 0; }

.gl-cart-line__img {
	width: 58px;
	height: 74px;
	object-fit: contain;
	background: var( --off, rgba( 17, 24, 39, .03 ) );
	border-radius: var( --r-btn, 12px );
}

/* La boutique, la fiche produit et la page panier portent la classe
   `.woocommerce`, et WooCommerce y declare `.woocommerce img { height: auto }`
   — deux classes contre une : sa regle gagne. La vignette perdait donc sa
   hauteur reservee la ou la feuille sert le plus. Mesure sur la boutique :
   0 px tant que l'image n'est pas arrivee, 87 ensuite ; la ligne sautait sous
   les yeux du client. On qualifie le selecteur au lieu d'imposer un
   `!important` qu'il faudrait ensuite battre a son tour. */
.gl-cart-sheet .gl-cart-line__img {
	height: 74px;
}

/* UNE PILE, UN SEUL ECART. Les rangs posaient chacun sa marge — 2, 4, 6, 8 px
   selon le bloc — et l'ensemble respirait de travers. Le corps tient
   desormais l'espacement, les rangs n'en portent plus aucun. */
.gl-cart-line__corps {
	display: flex;
	flex-direction: column;
	gap: 7px;
	min-width: 0;
}

/* Le nom et le prix se lisent ensemble, sur le meme rang : le prix — ce que
   le client cherche en premier — se perdait trois rangs plus bas, entre la
   gravure et le bon a graver. */
.gl-cart-line__entete {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 10px;
}

.gl-cart-line__prix {
	margin: 0;
	color: var( --ink, #111827 );
	font-family: var( --head, inherit );
	font-size: .92rem;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

/* Quantite a gauche, actions a droite : deux commandes courtes qui occupaient
   deux rangs entiers. Le repli garde le rang habitable sur un tres petit
   ecran plutot que de le laisser deborder. */
.gl-cart-line__pied {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	flex-wrap: wrap;
}

.gl-cart-line__nom {
	margin: 0;
	color: var( --ink, #111827 );
	font-family: var( --head, inherit );
	font-size: .92rem;
	font-weight: 700;
}

.gl-cart-line__gravure {
	/* DEUX LIGNES AU PLUS. Une gravure de six prenoms poussait le bouton de
	   validation hors de la feuille ; l'apercu en grand la montre entiere. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	margin: 0;
	color: var( --muted, #5F6470 );
	font-size: .8rem;
	line-height: 1.35;
	overflow-wrap: anywhere;
}

.gl-cart-line__bat {
	margin: 0;
	color: var( --gold-ink, #7A6224 );
	font-size: .75rem;
	font-weight: 700;
}

.gl-cart-line__actions {
	display: flex;
	gap: 14px;
	margin: 0;
}

.gl-cart-line__edit,
.gl-cart-line__remove {
	/* Cible tactile : le texte fait 12 px, la zone touchable doit faire 44.
	   On l'obtient par le rembourrage vertical, sans grossir la typographie. */
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	font-size: .78rem;
	font-weight: 600;
	text-decoration: none;
}

.gl-cart-line__edit { color: var( --gold-ink, #7A6224 ); }
.gl-cart-line__remove { color: var( --muted, #5F6470 ); }
.gl-cart-line__edit:hover,
.gl-cart-line__remove:hover { text-decoration: underline; }

.gl-cart-line__edit:focus-visible,
.gl-cart-line__remove:focus-visible {
	outline: 2px solid var( --gold-ink, #7A6224 );
	outline-offset: 2px;
}

/* LE PIED NE DOIT PAS PESER PLUS QUE LE PANIER QU'IL RESUME. Mesure a
   375 px : 237 px de pied pour 287 px de contenu — le total, trois facons de
   dire la meme attente, quatre boutons. Il tient desormais l'espacement pour
   ses rangs, qui ne portent plus aucune marge, et chacun a ete resserre. */
.gl-cart-sheet__foot {
	flex: 0 0 auto;
	display: flex;
	flex-direction: column;
	gap: 9px;
	padding: 11px 18px calc( 14px + env( safe-area-inset-bottom, 0px ) );
	border-top: 1px solid var( --line, rgba( 17, 24, 39, .1 ) );
}

.gl-cart-sheet__total {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	margin: 0;
	color: var( --muted, #5F6470 );
	font-size: .85rem;
}

.gl-cart-sheet__total strong {
	color: var( --gold-ink, #7A6224 );
	font-family: var( --head, inherit );
	font-size: 1.05rem;
	font-variant-numeric: tabular-nums;
}

.gl-cart-sheet__actions {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 8px;
}

.gl-cart-sheet__continue,
.gl-cart-sheet__voir,
.gl-cart-sheet__checkout {
	display: grid;
	place-items: center;
	min-height: 44px;
	padding: 0 12px;
	border-radius: var( --r-btn, 14px );
	font-family: var( --head, inherit );
	/* « Continuer mes achats » passait a la ligne dans sa moitie de rang :
	   le rang des deux sorties mesurait 102 px au lieu de 44. */
	font-size: .82rem;
	font-weight: 700;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
}

.gl-cart-sheet__continue,
.gl-cart-sheet__voir {
	background: transparent;
	border: 1px solid var( --line, rgba( 17, 24, 39, .14 ) );
	color: var( --ink, #111827 );
}

/* TROIS ACTIONS, DEUX RANGS. « Continuer » et « Voir le panier » sont deux
   sorties neutres : elles se partagent le premier rang. La caisse est un
   ENGAGEMENT — elle passe seule en dessous, pleine largeur, pour qu on ne la
   choisisse pas par erreur en visant sa voisine. */
.gl-cart-sheet__checkout {
	grid-column: 1 / -1;
}

.gl-cart-sheet__checkout {
	min-height: 48px;
	font-size: .88rem;
	background: linear-gradient( 180deg, var( --champ, #E9D9B6 ), var( --gold, #C9A44C ) );
	border: 0;
	color: var( --lux, #0B1220 );
}

.gl-cart-sheet__continue:focus-visible,
.gl-cart-sheet__checkout:focus-visible {
	outline: 2px solid var( --gold-ink, #7A6224 );
	outline-offset: 2px;
}

/* Le fond ne defile pas pendant que la feuille est ouverte. */
html.gl-cart-sheet-ouverte,
html.gl-cart-sheet-ouverte body { overflow: hidden; }

/* ==================================================================
   3. Bon a graver DANS la feuille — nouveautes de ce lot
   ================================================================== */

/* --- Ce qui manque avant de commander ----------------------------
   Pose entre le total et les boutons : c'est exactement le chemin du regard
   avant d'appuyer. Un ton d'attente (or lisible sur fond clair), jamais le
   rouge d'une erreur — le client n'a rien fait de mal, il lui reste une
   etape. */
.gl-cart-sheet__alerte {
	display: flex;
	align-items: flex-start;
	gap: 8px;
	margin: 0;
	padding: 8px 11px;
	border: 1px solid rgba( 200, 169, 106, .45 );
	border-radius: var( --r-field, 12px );
	background: rgba( 200, 169, 106, .1 );
	color: var( --gold-ink, #7A6224 );
	font-family: var( --head, inherit );
	font-size: .78rem;
	font-weight: 600;
	line-height: 1.35;
}

.gl-cart-sheet__alerte[hidden] { display: none !important; }

.gl-cart-sheet__alerte::before {
	content: '\2726'; /* meme signe que le sceau du panier */
	flex: 0 0 auto;
	line-height: 1.4;
}

/* --- La vignette devient un bouton d'agrandissement ---------------
   58 px de large : on n'y relit ni une date ni deux prenoms. Elle n'est donc
   pas une illustration mais l'ACCES a l'apercu en grand, et elle le dit par
   une petite loupe posee dans son coin. */
.gl-cart-line__loupe {
	position: relative;
	display: block;
	width: 58px;
	/* Le bouton est une case de la grille : sans cela il s'etire sur toute la
	   hauteur de la ligne — mesure : 169 px pour une image de 74. Le repere
	   « 2 faces », ancre sur son BAS, se retrouvait alors decroche loin sous
	   la vignette, et la loupe visait le vide. */
	align-self: start;
	padding: 0;
	border: 0;
	background: transparent;
	cursor: zoom-in;
	border-radius: var( --r-btn, 12px );
}

.gl-cart-line__loupe:focus-visible {
	outline: 2px solid var( --gold-ink, #7A6224 );
	outline-offset: 2px;
}

.gl-cart-line__loupe-marque {
	position: absolute;
	right: -6px;
	bottom: -6px;
	display: grid;
	place-items: center;
	width: 26px;
	height: 26px;
	border-radius: 999px;
	border: 1px solid var( --line, #ECEBE7 );
	background: #FFFFFF;
	color: var( --gold-ink, #7A6224 );
	box-shadow: 0 4px 12px rgba( 17, 24, 39, .14 );
}

.gl-cart-line__loupe:hover .gl-cart-line__loupe-marque {
	border-color: var( --gold, #C8A96A );
}

/* --- Sceau d'une ligne validee ------------------------------------
   Meme signe et meme phrase que sur la page panier (render_bat_block) : c'est
   un engagement date, pas une case cochee. Sur fond clair l'or passe
   obligatoirement par --gold-ink. */
.gl-cart-line__sceau {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	/* Dans une pile en colonne, un inline-flex s'etire sur toute la largeur :
	   la pastille cesserait d'etre une pastille. */
	align-self: flex-start;
	margin: 0;
	padding: 5px 10px;
	border: 1px solid rgba( 200, 169, 106, .5 );
	border-radius: 999px;
	background: rgba( 200, 169, 106, .12 );
	color: var( --gold-ink, #7A6224 );
	font-family: var( --head, inherit );
	font-size: .74rem;
	font-weight: 700;
	letter-spacing: .01em;
}

.gl-cart-line__sceau-marque { font-size: .9em; }

/* --- Bouton « Voir et valider » de la ligne ------------------------ */
.gl-cart-line__valider {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 44px;
	margin: 0;
	padding: 0 14px;
	border: 1px solid var( --gold, #C8A96A );
	border-radius: var( --r-btn, 14px );
	background: transparent;
	color: var( --gold-ink, #7A6224 );
	font-family: var( --head, inherit );
	font-size: .78rem;
	font-weight: 700;
	cursor: pointer;
	transition: background .18s var( --ease, ease );
}

.gl-cart-line__valider:hover { background: rgba( 200, 169, 106, .12 ); }

.gl-cart-line__valider:focus-visible {
	outline: 2px solid var( --gold-ink, #7A6224 );
	outline-offset: 2px;
}

/* ==================================================================
   4. Loupe du bon a graver
   ==================================================================
   Le seul endroit d'ou l'on peut valider. L'image occupe la plus grande part
   de l'ecran, le bouton est juste dessous : impossible d'approuver sans avoir
   eu la gravure sous les yeux. Posee sur la feuille, pas dedans — le panneau
   defile et l'aurait rognee. */

.gl-bat-loupe {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	/* 12 px et non 16 sur telephone : ces 8 px de marge autour du panneau sont
	   8 px de moins pour l'apercu et le bouton. Le grand ecran, lui, garde ses
	   24 px (media ci-dessous) — la place n'y manque pas. */
	padding: 12px;
}

.gl-bat-loupe[hidden] { display: none !important; }

.gl-bat-loupe__voile {
	position: absolute;
	inset: 0;
	background: rgba( 11, 18, 32, .62 );
}

.gl-bat-loupe__panel {
	position: relative;
	display: flex;
	flex-direction: column;
	width: 100%;
	max-width: 560px;
	max-height: 100%;
	background: var( --surface, #FFFFFF );
	border-radius: var( --r-card, 20px );
	box-shadow: 0 22px 60px rgba( 17, 24, 39, .3 );
	animation: gl-bat-loupe-in .2s var( --ease, ease );
}

@keyframes gl-bat-loupe-in {
	from { transform: scale( .97 ); opacity: 0; }
	to   { transform: none; opacity: 1; }
}

.gl-bat-loupe__corps {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: 12px 18px;
	text-align: center;
}

/* --- Les faces gravees ----------------------------------------------------
   UNE face, ou DEUX. Une gravure recto/verso n'en montrait qu'une : le client
   validait la moitie de sa commande.

   La grille est a UNE colonne par defaut — c'est-a-dire que la gravure recto
   seul retrouve exactement l'encombrement d'avant, au pixel pres : meme
   largeur, meme hauteur d'image, et pas de legende (il n'y a rien a
   distinguer). Le second cas ajoute une colonne, pas une rangee : cote a
   cote, deux verres tiennent dans la hauteur ; empiles, jamais. */
.gl-bat-loupe__faces {
	display: grid;
	grid-template-columns: 1fr;
	gap: 10px;
}

.gl-bat-loupe__faces--duo { grid-template-columns: 1fr 1fr; }

.gl-bat-loupe__face {
	display: grid;
	gap: 4px;
	margin: 0;
	min-width: 0;
}

/* L'image prend TOUTE la place disponible : c'est elle que le client est venu
   regarder. Le damier clair evite qu'un fond blanc de gravure disparaisse
   dans le panneau. En duo, le plafond descend : deux verres cote a cote sont
   deja deux fois moins larges, les laisser a 46vh les ferait deborder du
   corps et ramenerait le defilement qu'on vient de supprimer. */
/* 38vh et non 46 : a 46vh, mesure sur 375 x 667, la fenetre d'une gravure
   recto seul demandait encore 33 px de defilement — le bouton d'engagement
   restait sous le pli. 38vh laisse 253 px d'apercu (contre 58 px sur la
   vignette du panier), ramene le defilement a zero et garde ~29 px d'avance,
   de quoi encaisser une ligne de texte grave de plus sans replonger sous le
   pli. La gravure recto seul ne gagne donc AUCUN encombrement : elle en perd. */
.gl-bat-loupe__img {
	display: block;
	width: 100%;
	max-height: 38vh;
	margin: 0 auto;
	object-fit: contain;
	border: 1px solid var( --line, #ECEBE7 );
	border-radius: var( --r-field, 12px );
	background: var( --off, #FAFAF8 );
}

.gl-bat-loupe__faces--duo .gl-bat-loupe__img { max-height: 30vh; }

/* Deux images sans legende ne valent rien sur un document d'engagement : on
   ne sait pas laquelle on approuve. Petite, mais jamais absente quand il y a
   deux faces. */
.gl-bat-loupe__legende {
	/* Meme axe que le verre : l'image est centree dans sa colonne, la
	   legende doit l'etre aussi, sinon RECTO et VERSO tombent a cote de ce
	   qu'ils nomment. */
	text-align: center;
	color: var( --muted, #5F6470 );
	font-family: var( --head, inherit );
	font-size: .68rem;
	font-weight: 700;
	letter-spacing: .09em;
	text-transform: uppercase;
}

.gl-bat-loupe__faces[hidden],
.gl-bat-loupe__img[hidden],
.gl-bat-loupe__sans-image[hidden],
.gl-bat-loupe__valider[hidden],
.gl-bat-loupe__modifier[hidden] { display: none !important; }

.gl-bat-loupe__sans-image {
	margin: 0;
	padding: 14px;
	border: 1px dashed var( --line, #ECEBE7 );
	border-radius: var( --r-field, 12px );
	color: var( --muted, #5F6470 );
	font-size: .84rem;
	line-height: 1.45;
}

.gl-bat-loupe__gravure {
	margin: 10px 0 0;
	color: var( --ink, #111827 );
	font-family: var( --head, inherit );
	font-size: .88rem;
	font-weight: 600;
	line-height: 1.45;
	overflow-wrap: anywhere;
}

/* LE PIED NE DEFILE PAS — c'est toute sa raison d'etre. Tout ce qu'on y pose
   est pris sur l'apercu : il ne porte donc que la cote du marquage, une
   phrase, et les deux chemins (valider / modifier). */
.gl-bat-loupe__foot {
	flex: 0 0 auto;
	display: grid;
	gap: 7px;
	padding: 10px 18px calc( 12px + env( safe-area-inset-bottom, 0px ) );
	border-top: 1px solid var( --line, rgba( 17, 24, 39, .1 ) );
	text-align: center;
}

.gl-bat-loupe__note {
	margin: 0;
	color: var( --muted, #5F6470 );
	font-size: .78rem;
	line-height: 1.4;
}

/* L'engagement : meme or que le bouton d'achat de l'atelier. Le geste est de
   meme nature — on s'engage sur une piece qui sera gravee a l'identique. */
.gl-bat-loupe__valider {
	display: grid;
	place-items: center;
	min-height: 50px;
	padding: 0 16px;
	border: 0;
	border-radius: var( --r-btn, 14px );
	background: linear-gradient( 180deg, var( --champ, #E9D9B6 ), var( --gold, #C9A44C ) );
	color: var( --lux, #0B1220 );
	font-family: var( --head, inherit );
	font-size: .92rem;
	font-weight: 700;
	cursor: pointer;
	transition: transform .18s var( --ease, ease );
}

.gl-bat-loupe__valider:active { transform: scale( .985 ); }

.gl-bat-loupe__valider:disabled {
	opacity: .6;
	cursor: default;
}

/* Regarder son bon a graver, c'est aussi y trouver la faute de frappe : le
   chemin de correction est a cote du chemin de validation, en retrait. */
.gl-bat-loupe__modifier {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	color: var( --muted, #5F6470 );
	font-family: var( --head, inherit );
	font-size: .8rem;
	font-weight: 600;
	text-decoration: underline;
}

.gl-bat-loupe__valider:focus-visible,
.gl-bat-loupe__modifier:focus-visible {
	outline: 2px solid var( --gold-ink, #7A6224 );
	outline-offset: 2px;
}

/* Grand ecran : la loupe couvre la fenetre entiere et non le seul panneau
   ancre en haut a droite (couche desktop de l'atelier), sans quoi l'apercu
   « agrandi » tiendrait dans 400 px. */
@media ( min-width: 721px ) {
	.gl-bat-loupe {
		position: fixed;
		padding: 24px;
	}

	.gl-bat-loupe__img { max-height: 58vh; }

	/* Le panneau va jusqu'a 560 px : deux faces y ont largement la place de
	   rester grandes. */
	.gl-bat-loupe__faces--duo .gl-bat-loupe__img { max-height: 46vh; }

	.gl-bat-loupe__foot {
		grid-template-columns: 1fr auto;
		align-items: center;
		gap: 14px;
		text-align: left;
	}

	.gl-bat-loupe__note { grid-column: 1 / -1; }
}

/* ==================================================================
   5. Mouvement reduit
   ==================================================================
   Les regles de l'atelier ne couvrent que `.bg-configurator *` et ses
   couches : hors atelier, elles ne s'appliquent a rien. */
@media ( prefers-reduced-motion: reduce ) {
	.gl-cart-pill,
	.gl-cart-line__valider,
	.gl-bat-loupe__valider {
		transition: none !important;
	}

	.gl-cart-pill:hover,
	.gl-cart-pill:focus-visible { transform: none; }

	.gl-cart-sheet__panel,
	.gl-bat-loupe__panel { animation: none !important; }
}

/* --- Caracteristiques du bon a graver -------------------------------------
   L'apercu montre la COMPOSITION, jamais l'ECHELLE : sur une image, une
   gravure de 12 mm et une de 58 mm se ressemblent trait pour trait. Ces
   lignes sont donc ce qui rend la validation mesurable.

   Une liste de definitions (dl/dt/dd) et non un tableau : ce sont des paires
   intitule/valeur, pas des donnees croisees — et un lecteur d'ecran les
   annonce comme telles.
   -------------------------------------------------------------------------- */
/* DEUX COLONNES, et c'est la moitie du gain de place de ce lot. Ces paires
   sont courtes (« Verre / INAO 22 cl », « Quantite / 6 verres ») : une par
   rangee pleine laissait la moitie droite vide et poussait le bouton hors de
   l'ecran. Trois paires tiennent desormais sur deux rangees.

   La cote du marquage, elle, n'est PAS dans cette liste : elle vit dans le
   pied, qui ne defile jamais. */
.gl-bat-loupe__specs {
	margin: 10px 0 0;
	padding: 10px 0 0;
	border-top: 1px solid var( --line, rgba( 17, 24, 39, .1 ) );
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 6px 16px;
	text-align: left;
}

/* Sous 340 px, deux colonnes couperaient les valeurs en tranches de deux
   mots : on rend la pleine largeur plutot que d'obtenir une bouillie. */
@media ( max-width: 340px ) {
	.gl-bat-loupe__specs { grid-template-columns: 1fr; }
}

.gl-bat-loupe__specs[hidden] { display: none !important; }

.gl-bat-loupe__spec {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 10px;
	min-width: 0;
	font-size: .78rem;
	line-height: 1.35;
}

.gl-bat-loupe__spec dt {
	flex: 0 1 auto;
	margin: 0;
	color: var( --muted, #5F6470 );
}

.gl-bat-loupe__spec dd {
	flex: 0 1 auto;
	margin: 0;
	color: var( --ink, #111827 );
	font-weight: 600;
	text-align: right;
	/* Les cotes s'alignent sur leurs chiffres : « 45,2 × 58,4 mm » au-dessus
	   de « 47 × 60 mm » doit se comparer d'un coup d'oeil. */
	font-variant-numeric: tabular-nums;
	overflow-wrap: anywhere;
}

/* Les regles `.gl-bat-loupe__spec--fort` ont ete RETIREES avec le doublon
   qu'elles habillaient : la taille du marquage ne se peint plus dans cette
   liste, elle vit dans le pied (`.gl-bat-loupe__cote`), qui ne defile jamais.
   Laisser une mise en forme sans balisage aurait fait croire au prochain
   lecteur que la cote peut encore apparaitre ici. (La page panier, elle, a
   ses propres regles dans glassora-bat.css et garde la ligne mise en
   evidence : elle n'a pas de pied fixe.) */

/* La cote, rappelee dans le pied qui ne defile pas. Encre or et chiffres de
   meme chasse : c'est le chiffre sur lequel le client s'engage, il doit se
   lire d'un coup d'oeil juste au-dessus du bouton. */
.gl-bat-loupe__cote {
	margin: 0;
	color: var( --gold-ink, #7A6224 );
	font-family: var( --head, inherit );
	font-size: .9rem;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	line-height: 1.35;
}

.gl-bat-loupe__cote[hidden] { display: none !important; }

/* Repere « 2 faces » sur la vignette d'une gravure recto/verso : la vignette
   n'en montre qu'une, et sans ce signal le client peut croire avoir tout vu. */
.gl-cart-line__faces {
	position: absolute;
	left: 3px;
	bottom: 3px;
	padding: 1px 5px;
	border-radius: 999px;
	background: var( --lux, #0B1220 );
	color: #fff;
	font-size: .58rem;
	font-weight: 700;
	letter-spacing: .03em;
	line-height: 1.5;
	pointer-events: none;
}

/* Pas-a-pas de quantite sur une ligne de la feuille.
   Le client qui ajoute depuis la boutique recevait UNE boite sans pouvoir en
   demander deux : le choix se fait ici, la ou la ligne s affiche. Affiche en
   BOITES quand le produit se vend par boite — l unite dans laquelle on achete. */
.gl-cart-line__qty {
	display: inline-flex;
	align-items: center;
	gap: 2px;
	margin: 0;
	border: 1px solid var( --line, rgba( 17, 24, 39, .14 ) );
	border-radius: var( --r-field, 12px );
	background: #fff;
	overflow: hidden;
}
.gl-cart-line__qty.is-occupe { opacity: .5; pointer-events: none; }
.gl-cart-line__qty-btn {
	display: grid;
	place-items: center;
	width: 32px;
	height: 34px;
	padding: 0;
	border: 0;
	background: none;
	color: var( --ink, #111827 );
	font-size: 15px;
	line-height: 1;
	cursor: pointer;
}
.gl-cart-line__qty-btn:disabled { opacity: .3; cursor: default; }
.gl-cart-line__qty-btn:hover:not(:disabled) { background: rgba( 17, 24, 39, .05 ); }
.gl-cart-line__qty-val {
	min-width: 62px;
	padding: 0 4px;
	text-align: center;
	font-family: var( --head, inherit );
	font-size: .78rem;
	font-weight: 700;
	color: var( --ink, #111827 );
}

