/* Affinia — styles publics minimalistes (Phase 1).
   Conçus pour être facilement surchargés par le thème actif. */

.affinia { max-width: 480px; margin: 0 auto; }
.affinia-members-grid, .affinia-search, .affinia-interest-search { max-width: 900px; }

.affinia-form .affinia-field { margin: 0 0 16px; display: flex; flex-direction: column; gap: 6px; }
.affinia-form .affinia-field--checkbox { flex-direction: row; align-items: center; }
.affinia-form label { font-weight: 600; font-size: 0.9rem; }
.affinia-form input[type="text"],
.affinia-form input[type="email"],
.affinia-form input[type="password"],
.affinia-form input[type="date"],
.affinia-form input[type="file"],
.affinia-form select,
.affinia-form textarea {
	padding: 10px 12px;
	border: 1px solid #d8d0d3;
	border-radius: 8px;
	font-size: 1rem;
}
.affinia-form textarea { min-height: 120px; }

.affinia-honeypot { position: absolute !important; left: -9999px !important; }

.affinia-btn { display: inline-block; padding: 10px 22px; border-radius: 999px; border: none; cursor: pointer; font-weight: 600; }
.affinia-btn-primary { background: #4A132E; color: #fff; }
.affinia-btn-primary:hover { background: #350B20; }

.affinia-notice { padding: 12px 16px; border-radius: 8px; margin-bottom: 16px; }
.affinia-notice--success { background: #E7F5E9; color: #1E5B2A; }
.affinia-notice--error { background: #FBE8E8; color: #7A1F1F; }
.affinia-notice--info { background: #EAF2FB; color: #1B3A5C; }
/* Quota atteint (module Restrictions/permissions/quotas) : distinct de
   --error, il ne s'agit pas d'un échec mais d'une limite temporaire. */
.affinia-notice--warning { background: #FFF4E0; color: #6B4500; }

.affinia-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 20px; margin-top: 24px; }
.affinia-card { text-align: center; position: relative; }
.affinia-card-avatar img { border-radius: 50%; }
.affinia-card-name { margin-top: 8px; font-weight: 600; }

/*
 * Emplacements publicitaires (module Premium « AdSense », Lot 10). La
 * carte native insérée dans une grille de résultats occupe toute la
 * largeur de la ligne courante (jamais confondue visuellement avec une
 * fiche membre) ; .affinia-ad-slot habille tout emplacement (natif ou via
 * le shortcode [affinia_ad]) d'un espacement minimal, sans imposer de
 * style au contenu publicitaire lui-même (fourni par Google AdSense).
 */
.affinia-card-ad { grid-column: 1 / -1; text-align: center; }
.affinia-ad-slot { margin: 16px 0; text-align: center; }

/*
 * Mise en évidence de membre (module Premium) : classe exacte "highlight",
 * jamais appliquée à toute la page ni aux autres fiches. Couleurs pilotées
 * par des variables CSS injectées par Highlight_Service::print_css_variables()
 * uniquement quand le module est actif ; valeurs de repli ci-dessous si ce
 * bloc n'est jamais imprimé (module désactivé : aucune fiche ne porte la
 * classe "highlight", ces règles restent alors inertes).
 */
.affinia-card.highlight {
	background: var(--affinia-highlight-bg, #fff6d8);
	border: 2px solid var(--affinia-highlight-border, #e0b400);
	color: var(--affinia-highlight-text, #5a4600);
	border-radius: 10px;
	padding: 10px;
}
.affinia-highlight-badge {
	position: absolute;
	top: 6px;
	right: 6px;
	background: var(--affinia-highlight-border, #e0b400);
	color: #fff;
	font-size: 0.7rem;
	font-weight: 600;
	padding: 2px 8px;
	border-radius: 999px;
	line-height: 1.6;
}

.affinia-help { font-size: 0.8rem; color: #655760; }
.affinia-forgot { margin-left: 12px; font-size: 0.9rem; }

/* Phase 2 : galerie photo, options radio, pagination. */
.affinia-account { max-width: 640px; }
.affinia-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 16px; margin: 16px 0 32px; }
.affinia-gallery-item { border: 1px solid #e5dfe1; border-radius: 10px; overflow: hidden; padding-bottom: 10px; text-align: center; }
.affinia-gallery-item.is-primary { border-color: #4A132E; border-width: 2px; }
.affinia-gallery-item img { width: 100%; height: 140px; object-fit: cover; }
.affinia-gallery-status { font-size: 0.75rem; margin: 8px 0 4px; color: #655760; }
.affinia-gallery-actions { display: flex; flex-direction: column; gap: 4px; padding: 0 8px; }
.affinia-btn-link { background: none; border: none; color: #4A132E; text-decoration: underline; cursor: pointer; font-size: 0.8rem; padding: 0; }
.affinia-btn-link--danger { color: #7A1F1F; }
.affinia-radio-option { display: block; font-weight: 400; }
.affinia-field-group { margin: 28px 0 12px; padding-bottom: 6px; border-bottom: 1px solid #e5dfe1; color: #4A132E; }
.affinia-field-group:first-of-type { margin-top: 8px; }

/*
 * Module Premium « Galerie privée » : galerie du propriétaire (compte),
 * aperçu/bouton de demande sur la fiche détaillée d'un tiers, et tableau
 * des demandes d'accès reçues.
 */
.affinia-gallery--private .affinia-gallery-item { border-color: #d8c9b8; }
.affinia-detailed-profile-private-gallery { margin-top: 28px; }
.affinia-table { width: 100%; border-collapse: collapse; margin: 12px 0 28px; }
.affinia-table th, .affinia-table td { text-align: left; padding: 8px 10px; border-bottom: 1px solid #e5dfe1; font-size: 0.9rem; }
.affinia-table th { color: #4A132E; }

/*
 * Module Premium « Notifications instantanées » : cloche + liste
 * déroulante (élément <details> natif, sans JS requis pour l'ouverture ;
 * le seul JS chargé, notifications.js, ne fait que rafraîchir le badge).
 */
.affinia-notifications { max-width: none; display: inline-block; position: relative; }
.affinia-notifications-dropdown { display: inline-block; }
.affinia-notifications-bell { cursor: pointer; list-style: none; padding: 8px 14px; border-radius: 999px; background: #f4eef1; font-weight: 600; }
.affinia-notifications-bell::-webkit-details-marker { display: none; }
.affinia-notifications-badge { display: inline-block; min-width: 18px; padding: 0 5px; margin-left: 6px; border-radius: 999px; background: #7A1F1F; color: #fff; font-size: 0.7rem; line-height: 18px; text-align: center; }
/*
 * Positionnée en absolu : c'est une liste déroulante, sous une cloche, dans
 * une barre de navigation. Elle n'est plus employée sur la page dédiée, où
 * elle flottait au milieu du corps — voir .affinia-notifications-page.
 */
.affinia-notifications-dropdown .affinia-notifications-list { position: absolute; right: 0; z-index: 10; margin-top: 6px; width: 320px; max-height: 420px; overflow-y: auto; background: #fff; border: 1px solid #e5dfe1; border-radius: 10px; padding: 10px; box-shadow: 0 8px 24px rgba(0,0,0,0.12); }
.affinia-notifications-item { padding: 8px 4px; border-bottom: 1px solid #f0eaec; font-size: 0.85rem; }
.affinia-notifications-item.is-unread { background: #fbf7f2; }
.affinia-notifications-time { color: #918189; font-size: 0.75rem; margin: 2px 0 4px; }

.affinia-search-count { font-weight: 600; margin-top: 20px; }
.affinia-pagination { display: flex; gap: 6px; margin-top: 24px; }
.affinia-page-link { padding: 6px 12px; border: 1px solid #d8d0d3; border-radius: 6px; text-decoration: none; }
.affinia-page-link.is-current { background: #4A132E; color: #fff; border-color: #4A132E; }

/* Adhésions & paiement. */
.affinia-subscription-box { background: #F6E9E3; border-radius: 10px; padding: 16px 20px; margin-bottom: 28px; }
.affinia-plans { max-width: 1000px; }
.affinia-plans-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 24px; margin-top: 20px; }
.affinia-plan-card { border: 1px solid #e5dfe1; border-radius: 12px; padding: 24px; }
.affinia-plan-card.is-current { border-color: #4A132E; border-width: 2px; }
.affinia-plan-price { font-size: 1.5rem; font-weight: 700; color: #4A132E; }
.affinia-plan-duration { font-size: 0.9rem; font-weight: 400; color: #655760; }
.affinia-plan-features { list-style: none; padding: 0; margin: 16px 0; }
.affinia-plan-features li { padding: 4px 0; }
.affinia-plan-current-label { font-weight: 600; color: #4A132E; }

/* Recherche par centres d'intérêt (Premium, Lot 4). */
.affinia-field--group { border: 1px solid #d8d0d3; border-radius: 8px; padding: 10px 14px 14px; }
.affinia-field--group legend { font-weight: 600; font-size: 0.9rem; padding: 0 4px; }
.affinia-checkbox-option { display: inline-flex; align-items: center; gap: 6px; font-weight: 400; margin: 4px 14px 4px 0; }

/* Chat & Webcam (AtomChat). */
.affinia-chat-widget.affinia-chat-hide-desktop { display: none; }
.affinia-chat-call-buttons { max-width: 420px; border: 1px solid #e5dfe1; border-radius: 10px; padding: 16px 20px; }
.affinia-chat-target { font-weight: 700; margin: 0 0 8px; }
.affinia-chat-status-list { list-style: none; padding: 0; margin: 0 0 8px; }
.affinia-chat-status-list li { padding: 2px 0; font-size: 0.9rem; }
.affinia-chat-block-form, .affinia-chat-report-form { margin-top: 10px; display: flex; align-items: center; gap: 8px; }
@media screen and (max-width: 782px) {
	.affinia-chat-widget.affinia-chat-hide-mobile { display: none; }
}

/* Inscription rapide. */
.affinia-quick-status { background: #EAF2FB; border: 1px solid #B9D4F0; border-radius: 10px; padding: 16px 20px; margin-bottom: 28px; }
.affinia-badge-incomplete { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: #2271b1; margin-right: 6px; vertical-align: middle; }
.affinia-quick-checklist { list-style: none; padding: 0; margin: 12px 0; }
.affinia-quick-checklist li { padding: 2px 0; }
#affinia-quick-countdown { font-variant-numeric: tabular-nums; font-weight: 700; color: #2271b1; }

/*
 * Interface Élégance Rencontre — 0.13.1.
 * Adaptation des fondations Figma au HTML natif du plugin. Les variables
 * restent surchargeables par le thème, sans imposer de dépendance externe.
 */
.affinia {
	--affinia-ink: #241f2d;
	--affinia-muted: #6d6675;
	--affinia-primary: #6d3bd1;
	--affinia-primary-dark: #5630aa;
	--affinia-primary-soft: #f1eafd;
	--affinia-accent: #9fdb5b;
	--affinia-surface: #ffffff;
	--affinia-canvas: #fbf8f2;
	--affinia-border: #e7e0ec;
	--affinia-danger: #8c2438;
	--affinia-success: #426d16;
	--affinia-radius: 16px;
	--affinia-shadow: 0 18px 45px rgba(48, 40, 58, 0.12);
	width: 100%;
	max-width: 560px;
	color: var(--affinia-ink);
	font-family: Manrope, Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
	line-height: 1.55;
}

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

.affinia-members-grid,
.affinia-search,
.affinia-interest-search,
.affinia-plans,
.affinia-advanced-search { max-width: 1040px; }

.affinia a { color: var(--affinia-primary); text-underline-offset: 0.18em; }
.affinia a:hover { color: var(--affinia-primary-dark); }

.affinia-form {
	background: var(--affinia-surface);
	border: 1px solid var(--affinia-border);
	border-radius: 20px;
	box-shadow: var(--affinia-shadow);
	padding: clamp(20px, 4vw, 34px);
}

.affinia-form .affinia-field { margin-bottom: 20px; gap: 8px; }
.affinia-form label { color: var(--affinia-ink); font-size: 0.9rem; font-weight: 700; }

.affinia-form input[type="text"],
.affinia-form input[type="email"],
.affinia-form input[type="password"],
.affinia-form input[type="date"],
.affinia-form input[type="number"],
.affinia-form input[type="url"],
.affinia-form input[type="file"],
.affinia-form select,
.affinia-form textarea {
	min-height: 48px;
	width: 100%;
	max-width: 100%;
	padding: 11px 13px;
	border: 1px solid #cfc5d8;
	border-radius: 12px;
	background: #fff;
	color: var(--affinia-ink);
	font: inherit;
	transition: border-color 160ms ease, box-shadow 160ms ease;
}

.affinia-form input:hover,
.affinia-form select:hover,
.affinia-form textarea:hover { border-color: #9e91aa; }

.affinia :focus-visible {
	outline: 3px solid rgba(109, 59, 209, 0.3);
	outline-offset: 3px;
}

.affinia-form input:focus,
.affinia-form select:focus,
.affinia-form textarea:focus {
	border-color: var(--affinia-primary);
	box-shadow: 0 0 0 4px rgba(109, 59, 209, 0.12);
	outline: none;
}

.affinia-form input[type="checkbox"],
.affinia-form input[type="radio"] {
	accent-color: var(--affinia-primary);
	width: 18px;
	height: 18px;
	flex: 0 0 auto;
}

.affinia-field--checkbox { align-items: flex-start; }
.affinia-consent-label { display: flex; align-items: flex-start; gap: 10px; font-weight: 500 !important; }
.affinia-consent-label input { margin-top: 0.18em; }
.affinia-help { color: var(--affinia-muted); font-size: 0.82rem; }

.affinia-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 48px;
	padding: 10px 22px;
	border: 2px solid transparent;
	border-radius: 14px;
	font-size: 0.92rem;
	font-weight: 800;
	line-height: 1.25;
	text-align: center;
	text-decoration: none;
	transition: transform 160ms ease, box-shadow 160ms ease, background-color 160ms ease;
}

.affinia-btn-primary {
	background: var(--affinia-primary);
	color: #fff;
	box-shadow: 0 8px 20px rgba(109, 59, 209, 0.22);
}

.affinia-btn-primary:hover {
	background: var(--affinia-primary-dark);
	color: #fff;
	transform: translateY(-1px);
}

.affinia-btn-primary:active { transform: translateY(0); }
.affinia-btn-link { color: var(--affinia-primary); font-weight: 700; }

.affinia-notice {
	border: 1px solid transparent;
	border-radius: 14px;
	padding: 14px 16px;
	margin-bottom: 18px;
}
.affinia-notice--success { background: #e9f7d7; border-color: #c5e99b; color: #345813; }
.affinia-notice--error { background: #fff0f2; border-color: #efbcc5; color: var(--affinia-danger); }
.affinia-notice--info { background: var(--affinia-primary-soft); border-color: #d8c8f7; color: #472887; }
.affinia-notice--warning { background: #fff7e8; border-color: #efd295; color: #684800; }

.affinia-grid {
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 210px), 1fr));
	gap: 18px;
}

.affinia-card {
	min-width: 0;
	padding: 22px 18px;
	border: 1px solid var(--affinia-border);
	border-radius: var(--affinia-radius);
	background: var(--affinia-surface);
	box-shadow: 0 10px 28px rgba(48, 40, 58, 0.07);
	transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
}

.affinia-card:hover,
.affinia-card:focus-within {
	transform: translateY(-3px);
	border-color: #d4c7df;
	box-shadow: 0 16px 36px rgba(48, 40, 58, 0.12);
}

.affinia-card-avatar img,
.affinia-card-avatar .avatar {
	display: block;
	width: 96px;
	height: 96px;
	margin-inline: auto;
	border-radius: 50%;
	object-fit: cover;
}
.affinia-card-name { color: var(--affinia-ink); font-weight: 800; }

/*
 * Le lien qui enveloppe une carte de la Découverte.
 *
 * Il ne s'appelle pas « affinia-card-link » : ce nom sert au lien texte
 * « Voir le profil » des fiches enrichies, dont la règle est écrite plus
 * bas dans cette feuille et l'emportait donc ici — margin-top, couleur
 * violette, 0,875 rem et alignement à gauche s'appliquaient à toute la
 * carte, ce qui décalait le nom sous un avatar resté centré.
 *
 * Sans couleur ni soulignement propres : c'est la carte entière qui est
 * cliquable, et souligner le nom laisserait croire que seul le nom l'est.
 */
.affinia-card-couverture {
	display: block;
	color: inherit;
	text-decoration: none;
}

/*
 * Toute la carte répond au clic, pas seulement le bloc du lien.
 *
 * Le lien n'enveloppe que l'avatar, le nom et la mention. Le reste de la
 * carte — sa marge intérieure, la bande sous le nom — restait inerte :
 * un clic y tombait dans le vide, sans que rien ne change au pointeur.
 * D'où « je ne peux pas cliquer dessus » sur des cartes pourtant liées.
 *
 * Le pseudo-élément couvre la carte entière et porte le clic. La carte
 * doit donc être un repère de positionnement, et le curseur dire, sur
 * toute sa surface, qu'il y a quelque chose à ouvrir.
 */
.affinia-card--liee {
	position: relative;
	cursor: pointer;
	transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.affinia-card-couverture::after {
	content: '';
	position: absolute;
	inset: 0;
	border-radius: inherit;
}

/*
 * Le survol est la seule chose qui distingue, à l'œil, une carte qui
 * s'ouvre d'une vignette décorative.
 */
.affinia-card--liee:hover {
	transform: translateY(-2px);
	box-shadow: 0 10px 24px rgba(23, 15, 41, 0.12);
}

@media (prefers-reduced-motion: reduce) {
	.affinia-card--liee {
		transition: none;
	}

	.affinia-card--liee:hover {
		transform: none;
	}
}

/*
 * Le contour de focus est explicite, et posé sur la carte : le lien ne
 * couvre qu'une partie d'elle, alors que la zone cliquable, elle, est la
 * carte entière — c'est donc elle que le contour doit désigner. Quelqu'un
 * qui navigue au clavier doit voir où il est, et un survol à la souris
 * n'est pas un focus.
 */
.affinia-card--liee:focus-within {
	outline: 2px solid var(--affinia-ink);
	outline-offset: 4px;
	border-radius: 12px;
}

.affinia-card-couverture:focus-visible {
	outline: none;
}

.affinia-empty-state {
	position: relative;
	overflow: hidden;
	padding: clamp(28px, 6vw, 56px);
	border-radius: 22px;
	background: var(--affinia-ink);
	color: #fff;
	box-shadow: var(--affinia-shadow);
	isolation: isolate;
}

.affinia-empty-state::before {
	content: "";
	position: absolute;
	z-index: -1;
	right: 8%;
	bottom: -80px;
	width: 240px;
	height: 180px;
	border-radius: 50%;
	background: radial-gradient(circle, rgba(159, 219, 91, 0.18), rgba(159, 219, 91, 0) 68%);
	pointer-events: none;
}

.affinia-empty-state::after {
	content: "";
	position: absolute;
	right: -72px;
	top: -72px;
	width: 150px;
	height: 150px;
	border: 2px solid rgba(159, 219, 91, 0.45);
	border-radius: 50%;
	pointer-events: none;
	transition: transform 500ms ease, border-color 500ms ease;
}

.affinia-empty-state:hover::after { transform: scale(1.08) rotate(8deg); border-color: rgba(159, 219, 91, 0.72); }

.affinia-launch-badges {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin: 0 0 18px;
}

.affinia-launch-badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 32px;
	padding: 7px 14px;
	border-radius: 999px;
	font-size: 0.68rem;
	font-weight: 800;
	letter-spacing: 0.08em;
	line-height: 1.2;
	text-transform: uppercase;
	box-shadow: 0 8px 18px rgba(18, 12, 24, 0.2);
}

.affinia-launch-badge--primary { background: #34263f; color: #fff; }
.affinia-launch-badge--region { background: #edffd9; color: var(--affinia-ink); animation: affinia-gentle-float 3.8s ease-in-out infinite; }

@keyframes affinia-gentle-float {
	0%, 100% { transform: translateY(0); }
	50% { transform: translateY(-4px); }
}

.affinia-empty-state h2 {
	position: relative;
	max-width: 720px;
	margin: 8px 0 14px;
	color: #fff;
	font-size: clamp(1.55rem, 4vw, 2.45rem);
	line-height: 1.12;
	letter-spacing: -0.025em;
}
.affinia-empty-state > p:not(.affinia-eyebrow) { max-width: 720px; color: #eee8f3; }
.affinia-eyebrow { margin: 0; color: #d9c7ff; font-size: 0.76rem; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; }
.affinia-trust-list { display: grid; gap: 10px; margin: 24px 0; padding: 0; list-style: none; }
.affinia-trust-list li { position: relative; padding-left: 30px; }
.affinia-trust-list li::before { content: "✓"; position: absolute; left: 0; color: var(--affinia-accent); font-weight: 900; }
.affinia-empty-state .affinia-btn { position: relative; }
.affinia .affinia-empty-state .affinia-btn.affinia-btn-primary,
.affinia .affinia-empty-state .affinia-btn.affinia-btn-primary:visited {
	background: var(--affinia-primary);
	border-color: var(--affinia-primary);
	color: #fff;
}
.affinia .affinia-empty-state .affinia-btn.affinia-btn-primary:hover {
	background: var(--affinia-primary-dark);
	border-color: var(--affinia-primary-dark);
	color: #fff;
}

.affinia-empty-state--compact {
	padding: clamp(22px, 4vw, 36px);
	background: linear-gradient(135deg, #f3edff, #fff7fa 55%, #f1f7df);
	color: var(--affinia-ink);
	box-shadow: none;
}
.affinia-empty-state--compact h2 { color: var(--affinia-ink); font-size: clamp(1.35rem, 3vw, 1.9rem); }
.affinia-empty-state--compact > p:not(.affinia-eyebrow) { color: var(--affinia-muted); }

.affinia-plans-grid { gap: 20px; }
.affinia-plan-card { border-color: var(--affinia-border); border-radius: 18px; background: #fff; box-shadow: 0 10px 28px rgba(48, 40, 58, 0.07); }
.affinia-plan-card.is-current { border-color: var(--affinia-primary); }
.affinia-plan-price,
.affinia-plan-current-label,
.affinia-field-group,
.affinia-table th { color: var(--affinia-primary); }

.affinia-pagination { flex-wrap: wrap; }
.affinia-page-link { min-width: 40px; min-height: 40px; display: inline-flex; align-items: center; justify-content: center; border-color: var(--affinia-border); }
.affinia-page-link.is-current { background: var(--affinia-primary); border-color: var(--affinia-primary); }

@media (max-width: 600px) {
	.affinia { max-width: 100%; }
	.affinia-form { border-radius: 16px; padding: 20px 16px; }
	.affinia-btn { width: 100%; }
	.affinia-forgot { display: inline-block; margin: 12px 0 0; }
	.affinia-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
	.affinia-card { padding: 16px 10px; }
	.affinia-notifications-list { position: fixed; right: 12px; left: 12px; width: auto; max-width: none; }
	.affinia-table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
	.affinia-empty-state { padding: 30px 20px; border-radius: 18px; }
	.affinia-launch-badges { align-items: flex-start; flex-direction: column; margin-bottom: 20px; }
	.affinia-launch-badge--region { align-self: flex-end; }
}

@media (max-width: 360px) {
	.affinia-grid { grid-template-columns: 1fr; }
}

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

/*
 * Module « Assistant IA ». Reprend les composants existants (.affinia-form,
 * .affinia-btn, .affinia-notice) : seuls les éléments propres à l'assistant
 * — onglets, propositions, jauge, fil de conversation — sont définis ici.
 */

.affinia-ai { max-width: 760px; }

.affinia-ai-header { text-align: center; margin-bottom: 20px; }
.affinia-ai-title { margin: 0 0 6px; }
.affinia-ai-subtitle { margin: 0; color: #6a5f63; }
.affinia-ai-quota { margin: 8px 0 0; font-size: 0.85rem; color: #6a5f63; }

.affinia-ai-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; padding-bottom: 20px; border-bottom: 1px solid #ece5e7; }
.affinia-ai-tab {
	display: inline-flex; align-items: center; gap: 6px;
	padding: 8px 14px; border: 1px solid #d8d0d3; border-radius: 999px;
	background: #faf7f8; color: #6a5f63; font: inherit; font-size: 0.9rem; cursor: pointer;
}
.affinia-ai-tab:hover { border-color: #4A132E; color: #4A132E; }
.affinia-ai-tab.is-active { background: #4A132E; border-color: #4A132E; color: #fff; }

.affinia-ai-panel { display: none; }
.affinia-ai-panel.is-active { display: block; }
.affinia-ai-required { color: #7A1F1F; }

.affinia-ai-status { margin: 12px 0 0; min-height: 1.2em; font-size: 0.9rem; }
.affinia-ai-status.is-loading { color: #6a5f63; }
.affinia-ai-status.is-loading::before {
	content: ""; display: inline-block; width: 0.8em; height: 0.8em; margin-right: 8px;
	border: 2px solid #e3dadd; border-top-color: #4A132E; border-radius: 50%;
	animation: affinia-ai-spin 0.8s linear infinite;
}
@keyframes affinia-ai-spin { to { transform: rotate( 360deg ); } }
@media ( prefers-reduced-motion: reduce ) { .affinia-ai-status.is-loading::before { animation: none; } }

.affinia-ai-results:not( :empty ) { margin-top: 20px; }
.affinia-ai-block { margin-bottom: 24px; }
.affinia-ai-block-title { margin: 0 0 10px; font-size: 0.8rem; letter-spacing: 0.06em; text-transform: uppercase; color: #6a5f63; }

.affinia-ai-proposal { margin-bottom: 14px; padding: 16px 18px; background: #faf7f8; border: 1px solid #ece5e7; border-radius: 12px; }
.affinia-ai-proposal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
.affinia-ai-actions { display: inline-flex; gap: 12px; flex-shrink: 0; }
.affinia-ai-label { font-size: 0.75rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: #4A132E; }
.affinia-ai-proposal-text p, .affinia-ai-text p { margin: 0 0 10px; }
.affinia-ai-proposal-text p:last-child, .affinia-ai-text p:last-child { margin-bottom: 0; }
.affinia-ai-copy.is-copied { color: #1E5B2A; }

.affinia-ai-list { margin: 0; padding-left: 20px; }
.affinia-ai-list li { margin-bottom: 6px; }
.affinia-ai-block--positive .affinia-ai-list li::marker { color: #1E5B2A; }
.affinia-ai-block--negative .affinia-ai-list li::marker { color: #6B4500; }
.affinia-ai-block--warning { padding: 14px 18px; background: #FFF4E0; border-radius: 8px; }
.affinia-ai-block--warning .affinia-ai-block-title { color: #6B4500; }

.affinia-ai-gauge { height: 10px; background: #f0e8ea; border-radius: 999px; overflow: hidden; }
.affinia-ai-gauge-bar { height: 100%; background: #4A132E; border-radius: 999px; transition: width 0.5s ease; }
@media ( prefers-reduced-motion: reduce ) { .affinia-ai-gauge-bar { transition: none; } }
.affinia-ai-score { margin: 6px 0 0; font-weight: 700; }

.affinia-ai-thread { max-height: 380px; overflow-y: auto; margin-bottom: 16px; }
.affinia-ai-thread:empty { display: none; }
.affinia-ai-bubble { margin-bottom: 12px; padding: 12px 16px; border-radius: 12px; }
.affinia-ai-bubble--user { background: #f4ecef; margin-left: 12%; }
.affinia-ai-bubble--assistant { background: #faf7f8; border: 1px solid #ece5e7; margin-right: 12%; }
.affinia-ai-bubble-author { display: block; margin-bottom: 4px; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: #6a5f63; }
.affinia-ai-bubble p { margin: 0 0 8px; }
.affinia-ai-bubble p:last-child { margin-bottom: 0; }

.affinia-ai-history { margin-top: 24px; }
.affinia-ai-history-entry { margin: 12px 0; padding: 12px 16px; background: #faf7f8; border: 1px solid #ece5e7; border-radius: 10px; }
.affinia-ai-history-entry summary { cursor: pointer; font-weight: 600; }
.affinia-ai-history-entry[open] summary { margin-bottom: 12px; }

.affinia-ai-disclaimer { margin-top: 24px; padding-top: 16px; border-top: 1px solid #ece5e7; font-size: 0.82rem; }
.affinia-ai-upsell { text-align: center; padding: 24px; background: #faf7f8; border-radius: 12px; }

@media ( max-width: 640px ) {
	.affinia-ai-bubble--user { margin-left: 0; }
	.affinia-ai-bubble--assistant { margin-right: 0; }
	.affinia-ai-proposal-head { flex-direction: column; align-items: flex-start; gap: 6px; }
}

/* Page « Compléter mon profil ». */

.affinia-complete-profile { max-width: 760px; }

.affinia-completion { margin: 20px 0 28px; }
.affinia-completion-bar { height: 12px; background: #f0e8ea; border-radius: 999px; overflow: hidden; }
.affinia-completion-fill { height: 100%; background: #4A132E; border-radius: 999px; transition: width .5s ease; }
@media ( prefers-reduced-motion: reduce ) { .affinia-completion-fill { transition: none; } }
.affinia-completion-legend { margin: 8px 0 0; font-size: .95rem; }

.affinia-completion-group { margin-bottom: 12px; border: 1px solid #ece5e7; border-radius: 12px; background: #fff; }
.affinia-completion-group > summary {
	display: flex; align-items: center; justify-content: space-between; gap: 12px;
	padding: 14px 18px; cursor: pointer; font-weight: 600; list-style: none;
}
.affinia-completion-group > summary::-webkit-details-marker { display: none; }
.affinia-completion-group > summary::after { content: "＋"; color: #6a5f63; font-weight: 400; }
.affinia-completion-group[open] > summary::after { content: "－"; }
.affinia-completion-group[open] > summary { border-bottom: 1px solid #ece5e7; }
.affinia-completion-group > form { padding: 18px; }
.affinia-completion-group-count { font-weight: 400; font-size: .85rem; color: #6a5f63; }
.affinia-completion-group.is-complete > summary .affinia-completion-group-count { color: #1E5B2A; }

.affinia-completion-todo {
	display: inline-block; margin-left: 8px; padding: 1px 8px; border-radius: 999px;
	background: #FFF4E0; color: #6B4500; font-size: .72rem; font-weight: 600; vertical-align: middle;
}

.affinia-ai-toggle { margin-top: 6px; align-self: flex-start; }
.affinia-ai-embed { margin: 4px 0 20px; }
.affinia-ai-embed .affinia-ai { max-width: none; margin: 0; padding: 16px; background: #faf7f8; border: 1px solid #ece5e7; border-radius: 12px; }
.affinia-ai--embedded .affinia-ai-header { text-align: left; margin-bottom: 14px; }
.affinia-ai--embedded .affinia-ai-title { font-size: 1.05rem; }
.affinia-ai-insert { font-weight: 600; }

/*
 * Fiche membre enrichie (module Social, 0.17.1).
 *
 * Reprend les proportions de la maquette « Mes profils favoris » : photo de
 * 160 px, nom et cœur sur une même ligne, lieu, affinité, puis le lien.
 * Chaque bloc est facultatif — en production il en manquera souvent — d'où
 * l'absence de marge fixe entre eux : c'est la grille du parent qui espace,
 * et une carte à deux lignes reste alignée sur une carte à cinq.
 */
.affinia-card-photo {
	display: block;
	margin-bottom: 14px;
	border-radius: 12px;
	overflow: hidden;
	line-height: 0;
}

.affinia-card-photo img {
	width: 100%;
	height: 160px;
	object-fit: cover;
}

/*
 * Le cœur est poussé au bout de la ligne, jamais placé en absolu : une carte
 * sans photo ferait remonter un cœur positionné par-dessus le nom.
 */
.affinia-card-head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 12px;
	text-align: left;
}

.affinia-card-head .affinia-card-name {
	margin: 0;
	font-size: 1.05rem;
}

.affinia-card-meta {
	margin: 4px 0 0;
	color: var(--affinia-muted);
	font-size: 0.875rem;
	text-align: left;
}

/*
 * Bloc, pas pastille. « 92 % d'affinité astrologique · Balance ↔ Gémeaux »
 * est bien plus long que le « 92% de compatibilité » de la maquette — c'est
 * le prix d'un libellé exact — et une pastille en 999px qui passe à la ligne
 * se casse en deux demi-lunes. Un rectangle arrondi supporte le retour.
 */
.affinia-card-affinity {
	margin: 10px 0 0;
	padding: 6px 10px;
	border-radius: 10px;
	background: var(--affinia-primary-soft);
	color: #472887; /* 9,3:1 sur #f1eafd — largement lisible à 12 px. */
	font-size: 0.75rem;
	font-weight: 600;
	line-height: 1.35;
}

/*
 * `margin-top: auto` colle le lien au bas de la carte : sans lui, un profil
 * sans affinité remonterait son « Voir le profil » à mi-hauteur et la
 * rangée perdrait sa ligne de base commune.
 */
.affinia-card-link {
	display: block;
	margin-top: auto;
	padding-top: 12px;
	color: var(--affinia-primary);
	font-size: 0.875rem;
	font-weight: 600;
	text-align: left;
	text-decoration: none;
}

.affinia-card-link:hover,
.affinia-card-link:focus-visible {
	text-decoration: underline;
}

/*
 * La grille de base centre son contenu (fiches à avatar rond de
 * members-grid.php). Les fiches enrichies sont alignées à gauche : un texte
 * de deux lignes centré sous une photo pleine largeur se lit mal.
 */
/*
 * Colonne flex, et alignement à gauche : la grille de base centre son
 * contenu (fiches à avatar rond de members-grid.php), mais un texte de deux
 * lignes centré sous une photo pleine largeur se lit mal.
 */
.affinia-grid--favorites .affinia-card,
.affinia-grid--favorited-by .affinia-card,
.affinia-grid--visitors .affinia-card {
	display: flex;
	flex-direction: column;
	text-align: left;
}

/*
 * Écran « Paramètres & Confidentialité » (module Visibilité, 0.17.3).
 *
 * Les interrupteurs sont de vraies cases à cocher, repeintes. Un <div>
 * piloté par JavaScript aurait mieux ressemblé à la maquette et se serait
 * mal comporté partout ailleurs : sans clavier, sans lecteur d'écran, et
 * sans rien du tout si le script échoue — sur un écran qui décide de ce
 * qu'un membre montre de lui, c'est inacceptable. Le navigateur fait le
 * travail ; la peinture est ici.
 */
.affinia-settings {
	display: grid;
	gap: 20px;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
	align-items: start;
	/*
	 * `.affinia` vaut 480 px : c'est la colonne étroite par défaut du
	 * plugin, que chaque composant large surcharge (.affinia-members-grid
	 * 900, .affinia-plans 1000). Sans cette ligne, les deux groupes de la
	 * maquette s'empilaient au lieu de se placer côte à côte.
	 */
	max-width: 900px;
}

.affinia-settings-group {
	margin: 0;
	padding: 8px 24px 20px;
	border: 1px solid var(--affinia-border);
	border-radius: var(--affinia-radius);
	background: var(--affinia-surface);
}

.affinia-settings-group legend {
	padding: 0 4px;
	color: var(--affinia-ink);
	font-size: 1.15rem;
	font-weight: 800;
}

.affinia-settings-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 16px 0;
	border-bottom: 1px solid var(--affinia-border);
}

.affinia-settings-row:last-child {
	border-bottom: 0;
	padding-bottom: 0;
}

.affinia-settings-label {
	display: grid;
	gap: 3px;
	cursor: pointer;
}

.affinia-settings-title {
	color: var(--affinia-ink);
	font-weight: 600;
}

.affinia-settings-help {
	color: var(--affinia-muted);
	font-size: 0.8125rem;
	line-height: 1.4;
}

/*
 * appearance:none retire le carré natif ; tout le reste est dessiné sur la
 * case elle-même, qui garde son rôle, son focus et sa navigation clavier.
 */
.affinia-switch {
	appearance: none;
	-webkit-appearance: none;
	position: relative;
	flex: 0 0 auto;
	width: 46px;
	height: 26px;
	margin: 0;
	border: 0;
	border-radius: 999px;
	/*
	 * 3,7:1 sur blanc. Une piste plus claire aurait mieux ressemblé à la
	 * maquette et serait passée sous les 3:1 que WCAG 1.4.11 exige pour la
	 * limite visible d'un composant : l'interrupteur éteint aurait disparu
	 * du fond de la carte. Même rapport pour la pastille blanche dessus.
	 */
	background: #8a8296;
	cursor: pointer;
	transition: background 160ms ease;
}

.affinia-switch::after {
	content: "";
	position: absolute;
	top: 3px;
	left: 3px;
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: #fff;
	box-shadow: 0 1px 3px rgba(36, 31, 45, 0.35);
	transition: transform 160ms ease;
}

.affinia-switch:checked {
	/*
	 * 4,2:1 sur blanc, au-dessus des 3:1 requis. Et l'état ne tient pas
	 * qu'à la couleur : la pastille se déplace, ce que voit aussi qui ne
	 * distingue pas le vert du gris.
	 */
	background: #4f8a1f;
}

.affinia-switch:checked::after {
	transform: translateX(20px);
}

/*
 * Anneau de focus visible : sans lui, un membre au clavier ne saurait pas
 * quel interrupteur il s'apprête à basculer.
 */
.affinia-switch:focus-visible {
	outline: 3px solid var(--affinia-primary);
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	.affinia-switch,
	.affinia-switch::after {
		transition: none;
	}
}

.affinia-settings > .affinia-btn {
	grid-column: 1 / -1;
	justify-self: start;
}

/*
 * Messagerie intégrée (0.18.2).
 *
 * AtomChat reçoit une largeur en pixels — 990 par défaut — qu'il applique
 * telle quelle. Sur un téléphone de 390 px, c'est 600 px de débordement :
 * toute la page glisse horizontalement, en-tête et pied compris.
 *
 * Le débordement est donc confiné au widget. `overflow-x: auto` sur lui, et
 * non sur le corps de la page : si la conversation d'AtomChat ne peut pas
 * se réduire davantage, c'est elle qui défile, pas le site.
 *
 * Rien n'est imposé au contenu d'AtomChat lui-même : `max-width` sur ses
 * enfants directs suffit à le contenir quand il sait se réduire, et le
 * laisse tranquille quand il ne sait pas.
 */
.affinia-chat-widget--embedded {
	max-width: 100%;
	overflow-x: auto;
}

.affinia-chat-widget--embedded > * {
	max-width: 100%;
}

/*
 * Les iframes ne se réduisent pas d'elles-mêmes : leur largeur d'attribut
 * fait loi tant qu'une règle ne la contredit pas.
 */
.affinia-chat-widget--embedded iframe {
	max-width: 100%;
}

/*
 * Bascule « afficher / masquer » du mot de passe (0.19.2).
 *
 * L'enveloppe est posée par le script, jamais par le gabarit : sans
 * JavaScript, le champ reste un champ ordinaire et ces règles ne
 * s'appliquent à rien.
 */
.affinia-password-wrap {
	position: relative;
	display: block;
}

/* De la place pour le bouton, sinon le texte saisi passe dessous. */
.affinia-password-wrap input {
	width: 100%;
	padding-right: 48px;
	box-sizing: border-box;
}

.affinia-password-toggle {
	position: absolute;
	top: 50%;
	right: 8px;
	transform: translateY(-50%);
	display: grid;
	place-items: center;
	/* 40px : la cible tactile minimale recommandée, et l'icône seule en
	   ferait 20. */
	width: 40px;
	height: 40px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: #5b5366; /* 7,3:1 sur blanc — mesuré, pas estimé. */
	cursor: pointer;
}

.affinia-password-toggle:hover {
	color: var(--affinia-primary);
	background: var(--affinia-primary-soft);
}

.affinia-password-toggle:focus-visible {
	outline: 3px solid var(--affinia-primary);
	outline-offset: 2px;
}

/* Retour différé après inscription (0.19.2). */
.affinia-redirect {
	margin-top: 16px;
	color: var(--affinia-muted);
	font-size: 0.875rem;
	text-align: center;
}

.affinia-redirect a {
	color: var(--affinia-primary);
	font-weight: 600;
}

/* Un vrai bouton, repeint en lien : il annule, il ne navigue pas. */
.affinia-redirect-cancel {
	padding: 0;
	border: 0;
	background: none;
	color: var(--affinia-muted);
	font: inherit;
	text-decoration: underline;
	cursor: pointer;
}

/*
 * Choix multiples (0.19.8).
 *
 * Remplace le <select multiple>, qui exigeait Ctrl+clic et dont un clic
 * simple effaçait la sélection. Les cases restent de vraies cases à cocher :
 * on les habille, on ne les remplace pas par des <div> pilotés en
 * JavaScript, qui perdraient le clavier et les lecteurs d'écran.
 */
.affinia-choices {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.affinia-choice {
	position: relative;
	display: inline-flex;
}

/* La case est masquée à l'œil, jamais au clavier : `display:none` la
   sortirait de l'ordre de tabulation. */
.affinia-choice input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
}

.affinia-choice label {
	display: inline-block;
	padding: 9px 16px;
	/*
	 * 3,2:1 sur blanc, et non le gris de --affinia-border (1,3:1) : c'est
	 * ici la limite visible d'un contrôle, pas un simple filet décoratif, et
	 * WCAG 1.4.11 demande 3:1. Avec le token, la puce non cochée n'avait
	 * presque plus de forme — seul son texte se voyait.
	 */
	border: 1px solid #948ca0;
	border-radius: 999px;
	background: var(--affinia-surface);
	color: var(--affinia-ink);
	font-size: 0.875rem;
	line-height: 1.2;
	cursor: pointer;
	transition: background 140ms ease, border-color 140ms ease;
}

.affinia-choice input:checked + label {
	border-color: var(--affinia-primary);
	background: var(--affinia-primary-soft);
	color: #472887; /* 9,3:1 sur #f1eafd — mesuré. */
	font-weight: 700;
}

/* L'état ne tient pas qu'à la couleur : la coche le dit aussi. */
.affinia-choice input:checked + label::before {
	content: "✓ ";
	font-weight: 800;
}

.affinia-choice input:focus-visible + label {
	outline: 3px solid var(--affinia-primary);
	outline-offset: 2px;
}

/*
 * La mention « démonstration ».
 *
 * Lisible, mais pas criarde : elle doit être vue sans transformer la
 * grille en avertissement. Contraste mesuré du texte sur son fond :
 * 5,95:1, au-dessus des 4,5:1 exigés pour du texte de cette taille —
 * une mention légale illisible ne protège personne.
 *
 * La pastille elle-même ne ressort qu'à 1,2:1 sur une carte blanche, et
 * c'est sans conséquence : ce n'est pas elle qui porte l'information,
 * c'est le texte qu'elle contient. Le seuil de 3:1 vise les contrôles
 * et les éléments graphiques porteurs de sens, pas un fond décoratif
 * derrière un texte déjà lisible.
 */
.affinia-card-demo,
.affinia-profile-demo {
	display: inline-block;
	margin-top: 6px;
	padding: 2px 10px;
	border-radius: 999px;
	background: #f0ead9;
	color: #6b551a;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

.affinia-profile-demo {
	margin-top: 10px;
	text-transform: none;
	font-size: 13px;
	letter-spacing: 0;
}

/*
 * Le mot réservé à l'administrateur, sous une grille vide.
 *
 * Volontairement discret, et pourtant lisible : il n'est pas une alerte,
 * seulement une explication que le visiteur n'a pas à lire. Contraste
 * mesuré à 9,30:1 sur le fond de l'état vide (--affinia-ink, #241f2d) :
 * discret ne veut pas dire illisible, et une explication qu'on ne lit
 * pas ne sert à rien.
 */
/*
 * Deux fonds, deux traitements.
 *
 * Cette classe est née sous l'état vide, qui est sombre. Réutilisée sous
 * la grille, qui est claire, elle donnait du #c9c2d6 sur blanc : 1,73:1,
 * illisible. Le relevé était donc bien rendu, et invisible — j'ai passé
 * un échange à chercher pourquoi il n'apparaissait pas.
 *
 * Le cas clair est le défaut, le cas sombre l'exception : une classe
 * réutilisée ailleurs tombera sur le fond le plus courant.
 */
.affinia-empty-admin {
	margin-top: 20px;
	padding-top: 16px;
	border-top: 1px solid #d9d3e2;
	color: #5d5668; /* 7,01:1 sur blanc */
	font-size: 13px;
	line-height: 1.6;
	text-align: left;
}

.affinia-empty-state .affinia-empty-admin {
	border-top-color: rgba( 255, 255, 255, 0.18 );
	color: #c9c2d6; /* 9,30:1 sur --affinia-ink */
}

/*
 * Le bouton de déconnexion et son voyant de session.
 *
 * Bouton bordé, pas plein : se déconnecter n'est pas l'action principale
 * d'une page de compte, et un bouton plein à côté d'« Enregistrer »
 * ferait hésiter. Bordure à 3:1 minimum sur le fond, seuil du critère
 * 1.4.11 pour la limite d'un élément d'interface.
 */
.affinia-account-logout {
	margin: 0 0 16px;
	text-align: right;
}

.affinia-session {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}

.affinia-btn.affinia-logout {
	padding: 8px 18px;
	border: 1px solid #8f8699; /* 3,48:1 sur blanc — au-dessus du 3:1 exigé pour la limite d'un élément d'interface. */
	background: transparent;
	color: #4a4256; /* 9,52:1 sur blanc. */
	font-size: 0.9rem;
	text-decoration: none;
}

.affinia-btn.affinia-logout:hover,
.affinia-btn.affinia-logout:focus-visible {
	border-color: var(--affinia-ink);
	background: #f4eef1;
	color: var(--affinia-ink);
}

/*
 * Le voyant.
 *
 * La couleur ne porte jamais l'information seule : le libellé qui suit
 * dit la même chose en toutes lettres, et reste dans le document même
 * lorsqu'il est masqué à l'œil (dans un menu, par exemple). La forme
 * change aussi — plein pour une session confirmée, cerclé quand elle ne
 * l'est pas — pour qui ne distingue pas le vert de l'ambre.
 */
.affinia-session-voyant {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	flex: 0 0 auto;
}

.affinia-session[data-etat="active"] .affinia-session-voyant {
	background: #2f7d3a; /* 5,10:1 sur blanc — lisible comme du texte, a fortiori comme une pastille. */
	border: 2px solid #2f7d3a;
}

.affinia-session[data-etat="non_confirmee"] .affinia-session-voyant {
	background: transparent;
	border: 2px solid #8a5a00; /* 5,93:1 sur blanc. */
}

.affinia-session-etat {
	color: #5d5668; /* 7,01:1 sur blanc. */
	font-size: 0.8rem;
}

.affinia-session[data-etat="non_confirmee"] .affinia-session-etat {
	color: #6b4500; /* 8,48:1 sur blanc — c'est la seule ligne à lire quand elle apparaît. */
	font-weight: 600;
}

/*
 * Masqué à l'œil, présent pour un lecteur d'écran. Sans cela, le voyant
 * du menu ne dirait rien du tout à qui ne voit pas la couleur.
 */
.affinia-sr {
	position: absolute !important;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

/* Dans un menu, le bouton se fait discret : c'est une barre de navigation. */
.affinia-menu-logout .affinia-btn.affinia-logout {
	padding: 6px 14px;
	font-size: 0.85rem;
}

/* -------------------------------------------------------------------------
 * Le panneau du membre déjà connecté (/connexion/, /inscription/).
 *
 * Il ne porte que ce qui n'est nulle part ailleurs sur la page. Le
 * portrait, le salut et la jauge d'avancement en ont été retirés : le
 * thème affiche déjà les deux premiers en tête de chaque page membre, et
 * la troisième dans sa carte « Profil ». La même chose deux fois à deux
 * hauteurs d'écran n'est pas deux fois plus utile.
 * ---------------------------------------------------------------------- */
.affinia-deja-connecte {
	max-width: 720px;
	margin-inline: auto;
}

.affinia-dc-consigne {
	margin: 0;
	padding: 14px 18px;
	border-radius: 14px;
	background: linear-gradient( 135deg, #f1eafd 0%, #fdf3ee 100% );
	color: #4a4256; /* 8,13:1 sur l'extrémité violette du dégradé, 8,72:1 sur l'extrémité rosée. */
}

.affinia-dc-intertitre {
	margin: 26px 0 0;
	color: #5d5668; /* 7,01:1 sur blanc. */
	font-size: 0.8rem;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.affinia-dc-intertitre + .affinia-dc-raccourcis {
	margin-top: 12px;
}
.affinia-dc-raccourcis {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 200px, 1fr ) );
	gap: 14px;
	margin: 24px 0 0;
	padding: 0;
	list-style: none;
}

.affinia-dc-raccourci {
	display: block;
	height: 100%;
	padding: 16px 18px;
	border: 1px solid #ddd6e4; /* 1,42:1 — un filet de séparation, pas la limite d'une commande : le 3:1 du critère 1.4.11 ne s'y applique pas, le lien étant le bloc entier et nommé par son titre. */
	border-radius: 14px;
	color: inherit;
	text-decoration: none;
	transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}

.affinia-dc-raccourci:hover,
.affinia-dc-raccourci:focus-visible {
	border-color: #8f8699;
	transform: translateY( -2px );
	box-shadow: 0 10px 24px rgba( 23, 15, 41, 0.10 );
}

@media (prefers-reduced-motion: reduce) {
	.affinia-dc-raccourci {
		transition: none;
	}

	.affinia-dc-raccourci:hover,
	.affinia-dc-raccourci:focus-visible {
		transform: none;
	}
}

.affinia-dc-raccourci-titre {
	display: block;
	color: var(--affinia-ink);
	font-weight: 700;
}

.affinia-dc-raccourci-texte {
	display: block;
	margin-top: 4px;
	color: #5d5668; /* 7,01:1 sur blanc. */
	font-size: 0.85rem;
}

.affinia-dc-pied {
	margin-top: 24px;
	padding-top: 18px;
	border-top: 1px solid #ece7f2;
	text-align: right;
}


/* -------------------------------------------------------------------------
 * Le centre de notifications, sur sa propre page.
 *
 * La page rendait la cloche déroulante prévue pour une barre de
 * navigation : liste calée à droite sur 320 px, repliée au chargement, et
 * le mot « Notifications » lu trois fois — menu, titre, pastille. Ici,
 * pleine largeur, dépliée, sans redite.
 * ---------------------------------------------------------------------- */
.affinia-notifications-page {
	max-width: 720px;
	margin-inline: auto;
}

.affinia-notifications-entete {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: wrap;
	margin-bottom: 18px;
}

.affinia-notifications-compte {
	margin: 0;
	color: var(--affinia-ink);
	font-weight: 700;
}

.affinia-btn-secondaire {
	padding: 8px 18px;
	border: 1px solid #8f8699; /* 3,48:1 sur blanc. */
	background: transparent;
	color: #4a4256; /* 9,52:1 sur blanc. */
	font-size: 0.9rem;
	text-decoration: none;
}

.affinia-btn-secondaire:hover,
.affinia-btn-secondaire:focus-visible {
	border-color: var(--affinia-ink);
	background: #f4eef1;
}

.affinia-notifications-liste {
	margin: 0;
	padding: 0;
	list-style: none;
	border: 1px solid #ece7f2;
	border-radius: 14px;
	overflow: hidden;
}

.affinia-notifications-page .affinia-notifications-item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 14px 18px;
	border-bottom: 1px solid #f0eaec;
	font-size: 1rem;
}

.affinia-notifications-page .affinia-notifications-item:last-child {
	border-bottom: 0;
}

/*
 * Non lue : une barre à gauche en plus du fond. La teinte seule ne
 * distingue pas assez deux lignes voisines, et ne distingue rien du tout
 * pour qui ne perçoit pas ces nuances.
 */
.affinia-notifications-page .affinia-notifications-item.is-unread {
	background: #fbf7f2;
	box-shadow: inset 3px 0 0 0 var(--affinia-primary);
}

.affinia-notifications-message {
	margin: 0;
	color: var(--affinia-ink);
}

.affinia-notifications-page .affinia-notifications-time {
	margin: 4px 0 0;
	color: #5d5668; /* 7,01:1 sur blanc. */
	font-size: 0.8rem;
}

.affinia-notifications-vide {
	padding: 24px;
	border: 1px solid #ece7f2;
	border-radius: 14px;
}

.affinia-notifications-vide-titre {
	margin: 0 0 12px;
	color: var(--affinia-ink);
	font-weight: 700;
}

.affinia-notifications-declencheurs {
	margin: 8px 0 0;
	padding-left: 20px;
	color: #4a4256; /* 9,52:1 sur blanc. */
}

.affinia-notifications-declencheurs li {
	padding: 2px 0;
}

/* -------------------------------------------------------------------------
 * Les espaces de rencontre (« Rencontre gay », « Rencontre lesbienne »).
 *
 * Un seul jeu de règles pour les deux : ce qui les distingue est du texte,
 * pas de la mise en forme. Les cartes viennent du partiel commun et sont
 * donc déjà habillées.
 * ---------------------------------------------------------------------- */
.affinia-communaute {
	max-width: 900px;
}

.affinia-communaute-entete h2 {
	margin: 0;
	color: var(--affinia-ink);
}

.affinia-communaute-accroche {
	margin: 6px 0 0;
	color: #5d5668; /* 7,01:1 sur blanc. */
}

.affinia-communaute-filtres {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 160px, 1fr ) );
	gap: 14px;
	align-items: end;
	margin: 22px 0 0;
	padding: 18px;
	border: 1px solid #ece7f2;
	border-radius: 14px;
}

.affinia-communaute-filtres .affinia-field {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin: 0;
}

.affinia-communaute-filtres .affinia-field--checkbox {
	flex-direction: row;
	align-items: center;
}

.affinia-communaute-filtres label {
	color: #4a4256; /* 9,52:1 sur blanc. */
	font-size: 0.85rem;
	font-weight: 600;
}

.affinia-communaute-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

/* -------------------------------------------------------------------------
 * L'en-tête d'un espace de rencontre.
 *
 * Deux colonnes sur écran large — le texte, puis l'image ou l'illustration.
 * Une seule sur mobile, le texte d'abord : c'est lui qui dit où l'on est.
 * ---------------------------------------------------------------------- */
.affinia-espace-hero {
	display: grid;
	gap: 24px;
	align-items: center;
	padding: 24px;
	border-radius: 20px;
	background: linear-gradient( 135deg, #f6f2fd 0%, #fdf5f0 100% );
}

@media (min-width: 720px) {
	.affinia-espace-hero {
		grid-template-columns: 1.1fr 0.9fr;
		padding: 32px;
	}
}

.affinia-espace-hero h2 {
	margin: 0;
	color: var(--affinia-ink);
	font-size: clamp( 1.5rem, 3vw, 2rem );
	line-height: 1.2;
}

.affinia-espace-hero__compte {
	margin: 12px 0 0;
	color: #4a4256; /* 8,63:1 sur l'extrémité violette du dégradé, 8,84:1 sur l'extrémité rosée. */
	font-weight: 700;
}

.affinia-espace-hero__actions {
	margin: 18px 0 0;
}

/*
 * L'illustration et la photo occupent le même cadre : passer de l'une à
 * l'autre ne doit pas déplacer le texte à côté. Le rapport 8/5 est celui
 * du viewBox du SVG, pour qu'aucune des deux ne se déforme.
 */
.affinia-espace-hero__visuel {
	aspect-ratio: 8 / 5;
	border-radius: 16px;
	overflow: hidden;
}

.affinia-espace-illustration,
.affinia-espace-photo {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* --- Les trois repères, en bas de page ------------------------------- */

.affinia-espace-reperes {
	margin-top: 40px;
	padding-top: 28px;
	border-top: 1px solid #ece7f2;
}

.affinia-espace-reperes h3 {
	margin: 0 0 18px;
	color: var(--affinia-ink);
	font-size: 1.1rem;
}

.affinia-espace-reperes__grille {
	display: grid;
	gap: 18px;
	grid-template-columns: repeat( auto-fit, minmax( 220px, 1fr ) );
}

.affinia-espace-reperes article {
	display: flex;
	gap: 10px;
	align-items: start;
}

.affinia-espace-reperes svg {
	flex: 0 0 auto;
	width: 20px;
	height: 20px;
	margin-top: 2px;
	color: #2f7d3a; /* 5,10:1 sur blanc. */
}

.affinia-espace-reperes h4 {
	margin: 0 0 4px;
	color: var(--affinia-ink);
	font-size: 0.95rem;
}

.affinia-espace-reperes p {
	margin: 0;
	color: #5d5668; /* 7,01:1 sur blanc. */
	font-size: 0.875rem;
	line-height: 1.5;
}

/*
 * Le point de recadrage de la photo d'en-tête.
 *
 * Le cadre est en 8/5. Une photo verticale n'en garde qu'une bande
 * horizontale, et le sujet peut en sortir. Ces trois classes rattrapent
 * les cas courants sans passer par un éditeur d'image, en réglant l'axe
 * vertical seulement : l'horizontal reste centré, un recadrage latéral
 * étant rarement ce qu'on veut sur un portrait.
 */
.affinia-cadrage-haut .affinia-espace-photo { object-position: center 20%; }
.affinia-cadrage-centre .affinia-espace-photo { object-position: center center; }
.affinia-cadrage-bas .affinia-espace-photo { object-position: center 80%; }

/* -------------------------------------------------------------------------
 * Filtrage instantané d'un espace.
 *
 * Tout ce qui suit habille une page qui fonctionne déjà sans JavaScript.
 * Les raccourcis sont des liens, le bouton « Voir plus » est caché tant
 * que le script ne l'a pas montré, et la liste qui se recharge reste
 * lisible pendant qu'elle se recharge : elle pâlit, elle ne disparaît pas.
 * ---------------------------------------------------------------------- */
.affinia-communaute-raccourcis {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 18px 0 0;
}

.affinia-raccourci {
	padding: 7px 15px;
	border: 1px solid #8f8699; /* 3,48:1 sur blanc — limite d'un élément d'interface. */
	border-radius: 999px;
	background: transparent;
	color: #4a4256; /* 9,52:1 sur blanc. */
	font-size: 0.85rem;
	font-weight: 600;
	text-decoration: none;
	line-height: 1.3;
}

.affinia-raccourci:hover,
.affinia-raccourci:focus-visible {
	border-color: var(--affinia-ink);
	background: #f4eef1;
}

/*
 * Le raccourci actif est plein, et pas seulement d'une autre teinte : un
 * état signalé par la couleur seule se perd pour qui ne la distingue pas.
 * Le contraste de forme le dit aussi.
 */
.affinia-raccourci.is-actif {
	border-color: var(--affinia-ink);
	background: var(--affinia-ink);
	color: #ffffff; /* 16,04:1 sur #241f2d. */
}

.affinia-raccourci.is-actif::after {
	content: " ×";
	font-weight: 400;
}

/*
 * La zone de résultats pendant une requête.
 *
 * Elle s'estompe et cesse de répondre au clic, mais reste en place : vider
 * la grille le temps d'un aller-retour ferait sauter la page à chaque
 * caractère tapé dans « Ville ».
 */
.affinia-espace-resultats {
	position: relative;
	transition: opacity 140ms ease;
}

.affinia-espace-resultats.est-occupee {
	opacity: 0.45;
	pointer-events: none;
}

.affinia-espace-suite {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 12px;
	margin-top: 28px;
}

.affinia-espace-plus {
	display: inline-flex;
	align-items: baseline;
	gap: 8px;
}

/*
 * Le piège de l'attribut hidden.
 *
 * Le navigateur le traduit par display:none — dans sa propre feuille, que
 * la moindre règle d'auteur emporte. Un display:inline-flex écrit ici
 * suffit donc à faire réapparaître un élément marqué hidden, et c'est ce
 * qui serait arrivé : le bouton « Voir plus » serait resté visible pour
 * qui n'a pas de JavaScript — un bouton mort, qui promet une suite qu'il
 * ne peut pas charger. Il faut le redire, élément par élément.
 */
.affinia-espace-plus[hidden],
.affinia-pagination[hidden] {
	display: none;
}

.affinia-espace-plus[disabled] {
	cursor: progress;
	opacity: 0.6;
}

.affinia-espace-plus__reste {
	color: #5d5668; /* 7,01:1 sur blanc. */
	font-size: 0.8rem;
	font-weight: 400;
}

/*
 * L'arrivée des cartes ajoutées. Douze cartes qui apparaissent d'un bloc
 * ne disent pas où la liste s'est allongée ; un fondu très court le dit.
 */
.affinia-card--arrivee {
	animation: affinia-arrivee 220ms ease-out both;
}

@keyframes affinia-arrivee {
	from { opacity: 0; transform: translateY( 6px ); }
	to   { opacity: 1; transform: none; }
}

/*
 * Le mouvement est un confort, jamais une condition : qui l'a désactivé
 * au niveau du système voit les cartes arriver sans transition, et voit
 * exactement les mêmes cartes.
 */
@media ( prefers-reduced-motion: reduce ) {
	.affinia-card--arrivee { animation: none; }
	.affinia-espace-resultats { transition: none; }
}

/*
 * La carte ajoutée reçoit le focus pour ne pas renvoyer la lecture en
 * haut de page. Un focus qui ne se voit pas est un focus perdu : le
 * contour reste, même sur un lien rendu focusable par le script.
 */
.affinia-card-couverture:focus-visible {
	outline: 2px solid var(--affinia-ink);
	outline-offset: 3px;
	border-radius: 12px;
}

/* -------------------------------------------------------------------------
 * La recherche de membres.
 *
 * Ce gabarit était écrit dans les idiomes de l'administration de
 * WordPress : des onglets nav-tab dans un <h2>, des boutons « button
 * button-primary », des notes « description », et huit styles en ligne aux
 * gris de l'admin. Aucune de ces classes n'existe sur le site public. Les
 * onglets retombaient donc dans le style d'un titre de niveau 2 — « Par
 * profil » s'affichait en énorme, en violet, au milieu de la page.
 *
 * Rien de tout cela ne se voit en relisant le code : le balisage est
 * correct, il l'est simplement pour un autre endroit.
 * ---------------------------------------------------------------------- */
.affinia-advanced-search {
	max-width: 900px;
}

.affinia-onglets {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin: 0 0 20px;
	border-bottom: 1px solid #ece7f2;
	padding-bottom: 10px;
}

.affinia-onglet {
	padding: 7px 15px;
	border: 1px solid #8f8699; /* 3,48:1 sur blanc — limite d'un élément d'interface. */
	border-radius: 999px;
	color: #4a4256; /* 9,52:1 sur blanc. */
	font-size: 0.9rem;
	font-weight: 600;
	text-decoration: none;
	line-height: 1.3;
}

.affinia-onglet:hover,
.affinia-onglet:focus-visible {
	border-color: var(--affinia-ink);
	background: #f4eef1;
}

/*
 * L'onglet ouvert est plein, pas seulement d'une autre teinte : un état
 * signalé par la couleur seule se perd pour qui ne la distingue pas. Le
 * contraste de forme le dit aussi, et aria-current le dit aux lecteurs
 * d'écran.
 */
.affinia-onglet.is-actif {
	border-color: var(--affinia-ink);
	background: var(--affinia-ink);
	color: #ffffff; /* 16,04:1 sur #241f2d. */
}

.affinia-recherche-form {
	margin: 0 0 24px;
	padding: 18px;
	border: 1px solid #ece7f2;
	border-radius: 14px;
}

.affinia-recherche-essentiel {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 160px, 1fr ) );
	gap: 14px;
	align-items: end;
}

.affinia-recherche-essentiel .affinia-field,
.affinia-recherche-grille .affinia-field {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin: 0;
}

.affinia-recherche-essentiel label,
.affinia-recherche-grille label,
.affinia-recherche-grille legend {
	color: #4a4256; /* 9,52:1 sur blanc. */
	font-size: 0.85rem;
	font-weight: 600;
}

/*
 * Le repli des critères secondaires. Le triangle par défaut du navigateur
 * est remplacé par un signe qui pivote : le sien n'est pas cliquable sur
 * toute sa surface et change d'un navigateur à l'autre.
 */
.affinia-recherche-plus {
	margin-top: 14px;
}

.affinia-recherche-plus > summary {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	width: fit-content;
	padding: 6px 2px;
	color: #4a4256; /* 9,52:1 sur blanc. */
	font-size: 0.85rem;
	font-weight: 600;
	cursor: pointer;
	list-style: none;
}

.affinia-recherche-plus > summary::-webkit-details-marker {
	display: none;
}

.affinia-recherche-plus > summary::before {
	content: "+";
	display: inline-block;
	width: 1.1em;
	height: 1.1em;
	border: 1px solid #8f8699; /* 3,48:1 sur blanc. */
	border-radius: 4px;
	font-weight: 700;
	line-height: 1;
	text-align: center;
	transition: transform 140ms ease;
}

.affinia-recherche-plus[open] > summary::before {
	content: "−";
}

.affinia-recherche-plus > summary:hover::before,
.affinia-recherche-plus > summary:focus-visible::before {
	border-color: var(--affinia-ink);
}

.affinia-recherche-grille {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 180px, 1fr ) );
	gap: 14px;
	margin-top: 12px;
	padding-top: 14px;
	border-top: 1px solid #ece7f2;
}

.affinia-recherche-grille .affinia-field--groupe {
	margin: 0;
	padding: 0;
	border: 0;
}

.affinia-recherche-grille .affinia-field--checkbox {
	display: flex;
	align-items: center;
	gap: 6px;
	margin-top: 5px;
	font-weight: 400;
}

.affinia-recherche-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 16px;
}

/* Un champ qui n'attend que deux ou trois chiffres. */
.affinia-champ-court {
	width: 5.5rem;
}

.affinia-aide {
	color: #5d5668; /* 7,01:1 sur blanc. */
	font-size: 0.85rem;
}

/*
 * La carte de proximité. Ses dimensions vivent ici et non dans un style en
 * ligne : le script se contente de retirer l'attribut hidden, et la
 * hauteur peut donc s'adapter à l'écran sans être réécrite en JavaScript.
 */
.affinia-carte {
	width: 100%;
	height: 400px;
	margin-bottom: 16px;
	border-radius: 12px;
}

@media ( max-width: 600px ) {
	.affinia-carte { height: 260px; }
}

@media ( prefers-reduced-motion: reduce ) {
	.affinia-recherche-plus > summary::before { transition: none; }
}

/*
 * « Signaler » est un <summary> : il ouvre un formulaire replié, il n'est
 * donc pas un bouton au sens du balisage, mais il doit se voir comme tel.
 * Le triangle du navigateur est retiré — à l'intérieur d'une pastille, il
 * ressemble à une erreur d'affichage.
 *
 * Ces contrôles portaient la classe « button » de l'administration de
 * WordPress, qui n'existe pas côté public : « Bloquer » et « Signaler »
 * s'affichaient en texte brut. Ce sont les deux outils de sécurité de la
 * fiche, et un outil de sécurité qui ne ressemble à rien ne se trouve pas.
 */
.affinia-signaler {
	display: inline-block;
	list-style: none;
	cursor: pointer;
}

.affinia-signaler::-webkit-details-marker {
	display: none;
}
