/**
 * Butterfly Pixel – Restaurant Menu
 * Styles front.
 *
 * Volontairement MINIMAL et NEUTRE : aucune couleur de marque, aucune
 * typographie imposée. Le menu hérite du thème (Laurent / Elementor), qui
 * surcharge ensuite librement. La seule couleur utilisée est `currentColor`
 * pour les pointillés, afin qu'ils suivent automatiquement la couleur du
 * texte définie par le thème.
 */

/* -------------------------------------------------------------------------
 * 1. Grille de colonnes
 * ---------------------------------------------------------------------- */

.bp-menu__grid {
	display: grid;
	grid-template-columns: 1fr; /* Défaut : 1 colonne (= .bp-menu--cols-1). */
	gap: 2.5em 3em;             /* row-gap / column-gap. */
}

.bp-menu--cols-2 .bp-menu__grid {
	grid-template-columns: repeat(2, 1fr);
}

.bp-menu--cols-3 .bp-menu__grid {
	grid-template-columns: repeat(3, 1fr);
}

.bp-menu--cols-4 .bp-menu__grid {
	grid-template-columns: repeat(4, 1fr);
}

/**
 * Un élément de grille a `min-width: auto` par défaut : sa largeur minimale
 * est celle de son contenu min-content. Sans `min-width: 0`, un titre
 * contenant un mot très long ferait déborder la colonne au lieu de le couper.
 *
 * `overflow-wrap: break-word` est hérité par le titre et la description : il
 * autorise la coupure d'un mot trop long pour la colonne (noms de plats
 * composés, courants en LU/DE). Sans lui, `min-width: 0` réduit bien la boîte
 * mais les caractères continuent de déborder visuellement — vérifié en
 * navigateur : mot de 25 caractères dans une colonne de 170px, débordement de
 * 86px avec `min-width: 0` seul, 0 avec la paire.
 *
 * Note : sans effet sur le prix, qui est en `white-space: nowrap` (aucune
 * opportunité de coupure) — il reste donc toujours insécable.
 */
.bp-menu__item {
	min-width: 0;
	overflow-wrap: break-word;
}

/* -------------------------------------------------------------------------
 * 2. Ligne de menu : titre … prix
 * ---------------------------------------------------------------------- */

/**
 * EXIGENCE CLÉ — le prix doit basculer à la ligne suivante quand le titre est
 * trop long, en restant aligné à droite.
 *
 * Comment le flexbox produit ce comportement :
 *
 * L'algorithme de flexbox décide des retours à la ligne AVANT de distribuer
 * l'espace (avant flex-grow / flex-shrink), en se basant sur la « taille de
 * base hypothétique » de chaque élément. Ici :
 *
 *   - .bp-menu__title  → base = largeur de son contenu (flex-basis: auto)
 *   - .bp-menu__leader → base = 2em (flex-basis: 2em, verrouillée par min-width)
 *   - .bp-menu__price  → base = largeur du prix (indivisible : white-space: nowrap)
 *
 * Trois cas se présentent :
 *
 *   a) titre + 2em + prix TIENNENT sur une ligne
 *      → tout reste sur une ligne, le leader absorbe l'espace restant
 *        (flex-grow: 1) et pousse le prix contre le bord droit. C'est le
 *        rendu classique « Titre ......... 14,50 € ».
 *
 *   b) titre + 2em tiennent, mais pas le prix
 *      → ligne 1 : titre + pointillés (le leader s'étire jusqu'au bord droit)
 *        ligne 2 : le prix seul. Sur cette ligne il n'y a plus d'élément
 *        flex-grow, donc `margin-left: auto` absorbe tout l'espace libre et
 *        aligne le prix à droite. ✔
 *
 *   c) le titre seul dépasse la largeur disponible
 *      → ligne 1 : le titre seul. Comme flex-shrink vaut 1 et que sa largeur
 *        minimale est min-content, il se réduit à la largeur du conteneur et
 *        son texte passe sur plusieurs lignes.
 *        ligne 2 : pointillés + prix, prix à droite. ✔
 *
 * Note sur `margin-left: auto` : les marges auto ne consomment l'espace libre
 * QU'APRÈS résolution des tailles flexibles. Sur une ligne où le leader est
 * présent, flex-grow a déjà tout absorbé → la marge auto ne fait rien (elle
 * est inoffensive). Elle ne sert que dans le cas (b), exactement là où on en
 * a besoin.
 *
 * Les trois cas ont été vérifiés en navigateur (Chromium) sur des conteneurs
 * de 640px / 300px / 170px :
 *   a) 640px → prix sur la même ligne, collé à droite (écart 0px)
 *   b) 300px → prix basculé ligne 2, collé à droite (écart 0px)
 *   c) 170px → titre seul ligne 1, pointillés + prix ligne 2, écart 0px
 * Dans les trois cas les pointillés se posent à 4px au-dessus du bas de la
 * boîte du titre, soit au niveau de sa ligne de base.
 */
.bp-menu__main {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline; /* Les pointillés s'alignent sur la ligne de base du titre. */
	gap: 0 0.5em;          /* Respiration entre titre/pointillés/prix. */
}

.bp-menu__title {
	flex: 0 1 auto; /* Taille = contenu, mais peut se réduire (cas c). */
	margin: 0;      /* Neutralise la marge des <h3> du thème. */
	/**
	 * Indispensable : un élément flex a `min-width: auto`, sa largeur minimale
	 * est donc sa taille min-content (= le mot le plus long). Sans ce
	 * `min-width: 0`, flex-shrink ne peut pas réduire le titre sous cette
	 * limite et un nom de plat contenant un mot long déborde de la colonne.
	 * Fonctionne de pair avec l'`overflow-wrap` hérité de .bp-menu__item.
	 */
	min-width: 0;
}

/**
 * La « queue » : pointillés + prix réunis.
 *
 * C'est LA pièce maîtresse du retour à la ligne. En réunissant les pointillés
 * et le prix dans un seul élément flex, les deux basculent ENSEMBLE sur la
 * ligne suivante quand le titre est trop long. Auparavant, le prix partait
 * seul et les pointillés restaient coincés au bout de la ligne 1, laissant le
 * montant orphelin à droite.
 *
 * `flex: 1 1 auto` + `min-width: auto` (implicite) : la queue ne peut pas se
 * réduire sous sa taille min-content (pointillés 2em + prix insécable), donc
 * elle passe à la ligne au lieu d'écraser le prix. Une fois seule sur sa
 * ligne, elle occupe toute la largeur et les pointillés s'étirent jusqu'au
 * prix, resté calé à droite.
 */
.bp-menu__tail {
	flex: 1 1 auto;
	display: flex;
	align-items: baseline;
	gap: 0 0.5em;
}

/**
 * Les pointillés de liaison.
 *
 * Span vide : sa hauteur de contenu est nulle, seule la bordure basse est
 * peinte — c'est ce qui dessine la ligne pointillée. En alignement baseline,
 * un élément flex sans contenu synthétise sa ligne de base depuis le bas de
 * sa boîte de bordure : les points se posent donc au niveau de la ligne de
 * base du titre.
 */
.bp-menu__leader {
	flex: 1 1 2em;
	min-width: 2em;
	border-bottom: 1px dotted currentColor;
	align-self: baseline;
}

.bp-menu__price {
	flex: 0 0 auto;      /* Jamais réduit : un prix ne se coupe pas. */
	margin-left: auto;   /* Colle le prix à droite. */
	white-space: nowrap; /* « 14,50 € » reste insécable. */
}

/* -------------------------------------------------------------------------
 * 3. Description
 * ---------------------------------------------------------------------- */

.bp-menu__desc {
	margin: 0.25em 0 0;
}

/* -------------------------------------------------------------------------
 * 4. Infobulle
 *
 * Reprise du rendu de Stylish Price List, dont les valeurs ont été relevées
 * dans `stylish-price-list/assets/css/frontend-style.css` (règle
 * `.df-spl-tooltip-container`, ligne 2275) :
 *
 *   fond #000 · texte #fff · rayon 5px · padding 15px · max-width 425px
 *   ombre 0 30px 90px -20px rgba(0,0,0,.3) · fondu 0,2 s linéaire
 *   titre en <h5>, marge 0 0 5px 0
 *
 * DEUX ÉCARTS ASSUMÉS avec l'original :
 *
 * 1. SPL positionnait la bulle aux coordonnées du curseur, en JavaScript, dans
 *    un conteneur unique placé en fin de <body>. Ici elle est ancrée au bouton.
 *    C'est ce qui permet de se passer de JavaScript, et surtout d'exister au
 *    tactile et au clavier — où il n'y a pas de curseur à suivre.
 *
 * 2. SPL imposait `font-size: 25px` au conteneur, dont le paragraphe héritait.
 *    C'est un reliquat de son thème par défaut, pas une intention de design :
 *    25px pour une précision secondaire écrase la ligne de menu elle-même. La
 *    taille est donc héritée du thème et le titre légèrement appuyé. Pour
 *    revenir au rendu SPL à l'identique, poser `font-size: 25px` sur
 *    `.bp-menu__tip`.
 * ---------------------------------------------------------------------- */

.bp-menu__info {
	position: relative;
	display: inline-block;
	vertical-align: baseline;
}

/**
 * Le déclencheur.
 *
 * Un <button> et non un <span> : c'est ce qui le rend atteignable au clavier
 * (Tab) et au tactile (le tap donne le focus), sans une ligne de JavaScript.
 * Les styles de bouton du thème sont neutralisés un par un — `all: unset`
 * ferait disparaître le rôle bouton de certains lecteurs d'écran.
 */
/**
 * Dimensions : `box-sizing: content-box` + `width`/`height: 1em` + `padding`.
 *
 * La boîte de contenu vaut 1em, soit très exactement la taille du glyphe : sans
 * padding, le « i » touche le cercle. C'est le padding — et lui seul — qui crée
 * l'anneau d'air autour de la lettre ET agrandit le cercle, le tout en restant
 * proportionnel à la taille du titre puisque tout est exprimé en em.
 *
 * Diamètre obtenu = (1em + 2 × padding) × font-size + 2px de bordure, soit sur
 * un titre à 28px : (1 + 0,64) × 15,4 + 2 ≈ 27px. Ne pas passer en border-box
 * sans revoir ces valeurs : le padding rognerait alors le contenu au lieu de
 * s'ajouter autour, et on retomberait sur un « i » collé au trait.
 */
.bp-menu__info-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-sizing: content-box;
	width: 1em;
	height: 1em;
	padding: 0.32em;
	margin: 0 0 0 0.5em;
	border: 1px solid currentColor;
	border-radius: 50%;
	background: none;
	color: inherit;
	font-family: inherit;
	font-size: 0.55em;
	font-style: italic;
	font-weight: 700;
	line-height: 1;
	text-transform: none;
	cursor: help;
	opacity: 0.65;
	transition: opacity 0.2s linear;
}

.bp-menu__info-btn:hover,
.bp-menu__info-btn:focus-visible {
	opacity: 1;
}

/* Texte réservé aux lecteurs d'écran (le « i » seul ne dit rien). */
.bp-menu__sr {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/**
 * La bulle.
 *
 * Masquée par `opacity` seule, jamais par `visibility: hidden` ni
 * `display: none` : ces deux propriétés retirent l'élément de l'arbre
 * d'accessibilité, et le `aria-describedby` du bouton ne renverrait plus rien.
 * `pointer-events: none` empêche la bulle invisible d'intercepter la souris.
 */
.bp-menu__tip {
	position: absolute;
	z-index: 100;
	top: calc(100% + 0.5em);
	left: 50%;
	transform: translateX(-50%);
	box-sizing: border-box;
	width: max-content;
	/* 425px comme SPL, mais jamais plus large que l'écran. */
	max-width: min(425px, calc(100vw - 2rem));
	padding: 15px;
	border-radius: 5px;
	background-color: #000;
	color: #fff;
	font-size: 0.85rem;
	font-style: normal;
	font-weight: 400;
	line-height: 1.45;
	text-align: left;
	white-space: normal;
	word-wrap: break-word;
	box-shadow: 0 30px 90px -20px rgba(0, 0, 0, 0.3);
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.2s linear;
}

.bp-menu__info:hover .bp-menu__tip,
.bp-menu__info:focus-within .bp-menu__tip {
	opacity: 1;
	pointer-events: auto;
}

.bp-menu__tip-title {
	display: block;
	margin: 0 0 5px 0; /* Marge du <h5> de SPL. */
	font-weight: 700;
}

.bp-menu__tip-desc {
	display: block;
	margin: 0;
}

/**
 * Sur les écrans étroits, une bulle centrée sur le bouton déborde dès que le
 * plat est en fin de ligne. Elle est donc calée sur le bord gauche de la ligne
 * de menu, dont la largeur est déjà celle de la colonne.
 */
@media (max-width: 767px) {

	.bp-menu__info {
		position: static;
	}

	.bp-menu__item {
		position: relative;
	}

	.bp-menu__tip {
		left: 0;
		max-width: 100%;
		transform: none;
	}
}

/* Respect du réglage système « réduire les animations ». */
@media (prefers-reduced-motion: reduce) {

	.bp-menu__info-btn,
	.bp-menu__tip {
		transition: none;
	}
}

/* -------------------------------------------------------------------------
 * 5. Responsive
 * ---------------------------------------------------------------------- */

/**
 * Sous 768px, toutes les variantes repassent sur une seule colonne : deux
 * colonnes de menu sur mobile ne laissent pas assez de place au couple
 * titre/prix, qui se briserait à chaque ligne.
 */
@media (max-width: 767px) {

	.bp-menu--cols-2 .bp-menu__grid,
	.bp-menu--cols-3 .bp-menu__grid,
	.bp-menu--cols-4 .bp-menu__grid {
		grid-template-columns: 1fr;
	}
}
