/*
 * Champs de formulaire — utilisés par includes/forms.php (input_text, input_select, ...).
 */

.ag-field {
	margin-bottom: var(--ag-space-4);
}

.ag-field__label {
	display: block;
	margin-bottom: var(--ag-space-2);
	font-size: var(--ag-font-size-sm);
	font-weight: var(--ag-font-weight-medium);
	color: var(--ag-color-text);
}

.ag-field__required {
	color: var(--ag-color-danger);
}

/* Liste à sélection multiple + icône "Sélectionner tout" (input_select(...,
   $multiple=true), includes/forms.php) : affichés côte à côte plutôt que
   l'icône passant à la ligne sous le champ. Choices.js (ag-core.js) enrichit
   le <select> en place, donc .choices hérite de flex:1 au même titre. */
.ag-select-row {
	display: flex;
	align-items: flex-start;
	gap: var(--ag-space-2);
}

.ag-select-row select,
.ag-select-row .choices {
	flex: 1;
	min-width: 0;
}

.ag-select-row .ag-btn-icon {
	flex-shrink: 0;
	margin-top: 2px;
}

.ag-input,
.ag-select,
.ag-textarea {
	display: block;
	width: 100%;
	padding: var(--ag-space-2) var(--ag-space-3);
	border: 1px solid var(--ag-color-border-strong);
	border-radius: var(--ag-radius-sm);
	background: var(--ag-color-surface);
	font-size: var(--ag-font-size-base);
	color: var(--ag-color-text);
	transition: border-color var(--ag-transition-fast), box-shadow var(--ag-transition-fast);
}

.ag-input:focus,
.ag-select:focus,
.ag-textarea:focus {
	outline: none;
	border-color: var(--ag-color-primary);
	box-shadow: 0 0 0 3px var(--ag-color-primary-soft);
}

/*
 * Champ obligatoire non renseigné à la tentative de soumission — retour
 * utilisateur du 22/08/2026 (ecole_suivi_evaluations.php, "Mode d'affichage
 * des résultats" resté sur "—" : clic sur "Valider" sans aucun retour
 * visible). Cause : le navigateur bloque bien nativement la soumission d'un
 * <select required> vide (comportement HTML5 correct, inchangé), mais
 * n'affiche sa bulle d'erreur native que si le champ est visible/focusable —
 * or Choices.js masque le <select> d'origine (attribut hidden) derrière son
 * propre widget, donc cette bulle ne s'affiche jamais pour un select
 * enrichi : la personne ne voit alors aucune indication de ce qui bloque.
 * Classe posée par JS (assets/js/ag-core.js, écouteur global sur
 * l'évènement "invalid") sur le conteneur .ag-field englobant, quel que
 * soit le type de champ (input/select brut ou select Choices.js) — remplace
 * l'ancienne règle .ag-input--touched/.ag-select--touched, jamais posée par
 * aucun script, donc sans aucun effet visuel jusqu'ici.
 */
.ag-field--invalid .ag-input,
.ag-field--invalid .ag-select,
.ag-field--invalid .ag-textarea,
.ag-field--invalid .choices__inner,
.ag-field--invalid .ql-toolbar,
.ag-field--invalid .ql-container {
	border-color: var(--ag-color-danger);
	box-shadow: 0 0 0 3px var(--ag-color-danger-soft);
}

/*
 * Même règle appliquée à un champ Description/Devoir/Progression enrichi
 * par Quill.js (assets/js/ag-wysiwyg.js, 23/08/2026) : le <textarea>
 * required d'origine reste dans le DOM (visuellement réduit à 1x1px via
 * .ag-visually-hidden — jamais display:none, qui exempterait le champ de la
 * validation HTML5 native, voir ag-wysiwyg.js) et continue de déclencher
 * l'évènement "invalid" normalement ; seul l'habillage visuel de l'erreur
 * doit viser la barre d'outils/zone d'édition Quill visible, pas le
 * <textarea> cliché à 1px. .ql-toolbar et .ql-container ont chacun leur
 * propre bordure (thème "snow") : le sélecteur ci-dessus s'applique aux deux
 * pour un encadrement rouge continu.
 */

.ag-textarea {
	resize: vertical;
	min-height: 100px;
}

.ag-select {
	appearance: none;
	background-image: linear-gradient(45deg, transparent 50%, var(--ag-color-text-muted) 50%), linear-gradient(135deg, var(--ag-color-text-muted) 50%, transparent 50%);
	background-position: calc(100% - 18px) calc(1em + 2px), calc(100% - 13px) calc(1em + 2px);
	background-size: 5px 5px, 5px 5px;
	background-repeat: no-repeat;
	padding-right: var(--ag-space-7);
}

/* Champ texte centré (ex: identifiant de compte comptable édité en ligne dans
   un tableau, treso_comptes_comptables.php) — .ag-input est en width: 100%
   par défaut (remplit sa cellule de tableau), ce modificateur ne touche que
   l'alignement du texte à l'intérieur. */
.ag-input--center {
	text-align: center;
}

.ag-field--inline {
	display: flex;
	align-items: center;
	gap: var(--ag-space-2);
	margin-bottom: var(--ag-space-3);
}

/* Case à cocher / radio */
.ag-checkbox,
.ag-radio {
	display: inline-flex;
	align-items: center;
	gap: var(--ag-space-2);
	font-size: var(--ag-font-size-sm);
	cursor: pointer;
}

.ag-checkbox input,
.ag-radio input {
	width: 16px;
	height: 16px;
	accent-color: var(--ag-color-primary);
}

/* Champ fichier */
.ag-file {
	display: block;
	width: 100%;
	font-size: var(--ag-font-size-sm);
	padding: var(--ag-space-2) 0;
}

/* Grille de champs (remplace les .span* de Bootstrap 2) */
.ag-field-row {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: 0 var(--ag-space-4);
}

/* Variante pour une ligne à 5-6 champs (ex: recherche comptabilité —
   Enregistrements/Statut/Rapprochement bancaire/Modes de paiement/Date
   début/Date fin sur 6 colonnes, ou Identifiant/Description/Numéro de
   remise/Montant/Personne sur 5, chacune sur une seule ligne comme dans la
   version actuelle) : le seuil de 220px de .ag-field-row est trop large
   pour que 5 colonnes ou plus tiennent sur la largeur d'un .ag-form-section
   standard, ce qui fait retomber les derniers champs seuls à la ligne
   suivante.
   150px → 140px (retour utilisateur du 23/08/2026, écran 14 pouces,
   admin_activites.php — Prix/Nombre de places/Annuelle/Complète/Active/ENT,
   6 colonnes) : vérifié en direct à 1366px de large (fenêtre navigateur), la
   largeur réelle d'un .ag-form-section avec le menu latéral déplié n'est que
   d'environ 962px — 6 colonnes à 150px + 5 espacements de 16px (var(--ag-space-4))
   dépassent alors cette largeur de 18px, ce qui suffit à faire retomber la
   6e colonne seule à la ligne suivante (auto-fit calcule le nombre de
   colonnes qui tiennent, pas un nombre fixe). 140px laisse une marge
   (6*140 + 5*16 = 920px, contre 962px disponibles) sans réduire la largeur
   réellement affichée des colonnes quand moins de 6 tiennent déjà (1fr
   absorbe l'espace restant). */
.ag-field-row--narrow {
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
}

/*
 * Variante à nombre de colonnes FIXE, pas auto-fit (retour utilisateur du
 * 07/09/2026, admin_inscriptions.php — switchs de mode d'affichage répartis
 * sur 2 .ag-field-row consécutifs, 5 champs sur le 1er puis 5 ou 6 sur le
 * 2nd selon $conf["sms_envoi_actif"] — "Niveaux doit être exactement au-
 * dessus de Commentaires") : avec auto-fit (.ag-field-row--narrow ci-
 * dessus), chaque .ag-field-row calcule indépendamment son nombre de
 * colonnes d'après le nombre d'éléments QU'IL CONTIENT (les pistes vides
 * sont supprimées) — deux lignes contenant un nombre d'éléments différent
 * (5 puis 6) répartissent donc la même largeur totale en un nombre de parts
 * différent, et leurs colonnes ne tombent plus aux mêmes abscisses d'une
 * ligne à l'autre. Un nombre de colonnes fixe (ici 6, le plus grand des
 * deux) garantit que les deux lignes partagent exactement les mêmes limites
 * de colonnes quel que soit le nombre d'éléments réellement présents dans
 * chacune (une colonne sans élément reste simplement vide, ex. la 6e du 1er
 * .ag-field-row à 5 champs).
 */
.ag-field-row--fixed6 {
	grid-template-columns: repeat(6, minmax(140px, 1fr));
}

.ag-form-section {
	background: var(--ag-color-surface);
	border: 1px solid var(--ag-color-border);
	border-radius: var(--ag-radius-md);
	padding: var(--ag-space-5);
	margin-bottom: var(--ag-space-5);
}

/* Interrupteur (input_switch(), includes/forms.php) */
.ag-switch {
	display: inline-flex;
	align-items: center;
	gap: var(--ag-space-2);
	cursor: pointer;
	font-size: var(--ag-font-size-sm);
	font-weight: var(--ag-font-weight-medium);
	color: var(--ag-color-text);
}

.ag-switch input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
}

.ag-switch__track {
	position: relative;
	width: 40px;
	height: 22px;
	flex-shrink: 0;
	background: var(--ag-color-border-strong);
	border-radius: var(--ag-radius-full);
	transition: background var(--ag-transition-fast);
}

.ag-switch__track::after {
	content: "";
	position: absolute;
	top: 2px;
	left: 2px;
	width: 18px;
	height: 18px;
	background: var(--ag-color-surface);
	border-radius: 50%;
	box-shadow: var(--ag-shadow-sm);
	transition: transform var(--ag-transition-fast);
}

.ag-switch input:checked + .ag-switch__track {
	background: var(--ag-color-success);
}

.ag-switch input:checked + .ag-switch__track::after {
	transform: translateX(18px);
}

.ag-switch input:focus-visible + .ag-switch__track {
	box-shadow: 0 0 0 3px var(--ag-color-primary-soft);
}
