/* =============================================================================
 * FÍSIC v2 — Capa de rediseño (design system "Vital Balance")
 * -----------------------------------------------------------------------------
 * Basado en el proyecto de diseño "Rediseño FÍSIC móvil.dc.html" (Claude Design).
 *
 * REGLA DE ORO: todo cuelga de .fv2 y usa prefijo .fv2-
 * Nada de esto puede afectar al resto de la aplicación (backoffice, tablas,
 * diálogos, calendario...). Si se quita el <link> de este archivo y la clase
 * .fv2 del contenedor, la app vuelve exactamente al estado anterior.
 *
 * Tematización por cliente (multi-tenant): basta con sobreescribir --fv2-accent
 * en el elemento .fv2 (style inline desde el .tpl leyendo $cfg.ini) o en un
 * bloque body[data-cliente="xxx"]. Los tres tokens que el diseño expone como
 * configurables son: --fv2-accent, --fv2-radius-tile, --fv2-radius-card.
 * ========================================================================== */

/* -------------------------------------------------- 1. Tokens ------------- */
/*
 * ⚠️ body.fv2-cal y body.fv2-entrada VAN AQUÍ, y no son un añadido decorativo.
 *
 * Ni el calendario ni las pantallas de entrada tienen contenedor .fv2 (ver sus
 * bloques más abajo: se retiñen sin heredar la maquetación), así que sin estas
 * dos líneas sus reglas apuntarían a tokens que allí NO EXISTEN.
 *
 * Y una variable indefinida no "no hace nada": deja la propiedad inválida en
 * tiempo de cálculo, o sea que se comporta como si no se hubiera escrito. Pasó:
 * los botones de la barra salían con el fondo del acento —ese sí llega, porque
 * base.tpl lo inyecta en el <body>— pero con el texto heredado oscuro encima.
 * Botones negros con la letra invisible. Y volvió a pasar con la tarjeta del
 * login: radio, relleno y sombra sí se aplicaban (son literales) pero
 * `background: var(--fv2-card)` quedaba transparente y la tarjeta no existía.
 *
 * Sólo se comparte ESTE bloque, el de tokens. El de más abajo (tipografía,
 * max-width, márgenes) sigue siendo exclusivo de .fv2: son maquetación.
 */
.fv2,
body.fv2-cal,
body.fv2-entrada {
	/* Marca (configurable por cliente) */
	--fv2-accent:            #574FEC;
	--fv2-accent-soft:       #eef0ff;
	--fv2-accent-strong:     #453bdb;
	--fv2-on-accent:         #ffffff;

	/* Superficies */
	--fv2-surface:           #f9f9ff;
	--fv2-card:              #ffffff;
	--fv2-card-alt:          #f4f6fe;

	/* Texto */
	--fv2-on-surface:        #121c2c;
	--fv2-on-surface-var:    #3f4949;
	--fv2-outline:           #6f7979;
	--fv2-muted:             #8b93a7;
	--fv2-chevron:           #c4cbdb;

	/* Bordes y separadores */
	--fv2-border:            #e7eeff;
	--fv2-divider:           #f0f2f9;

	/* Estado */
	--fv2-error:             #ba1a1a;
	--fv2-error-container:   #ffdad6;
	--fv2-on-error-cont:     #93000a;
	--fv2-ok:                #1f8a5b;
	--fv2-ok-container:      #d7f2e3;
	--fv2-warn:              #ffb867;

	/* Forma (configurable) */
	--fv2-radius-tile:       18px;
	--fv2-radius-card:       16px;
	--fv2-radius-sm:         12px;

	/* Elevación */
	--fv2-shadow-card:       0 2px 14px rgba(18, 28, 44, .05);
	--fv2-shadow-hero:       0 4px 18px rgba(18, 28, 44, .08);

	/* Tipografía */
	--fv2-font-head:         'Archivo Narrow', 'Roboto', sans-serif;
	--fv2-font-body:         'Libre Franklin', 'Roboto', sans-serif;

	/* Ritmo vertical (base 8px) */
	--fv2-gutter:            18px;
}

/* -------------------------------------------------- 2. Contenedor -------- */
.fv2 {
	font-family: var(--fv2-font-body);
	color: var(--fv2-on-surface);
	background: var(--fv2-surface);
	max-width: 640px;
	margin: 0 auto;
	padding: 0 0 40px;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

/*
 * ⚠️ EL :where() ES OBLIGATORIO. NO cambiarlo por ".fv2 a".
 *
 * La intención de esta regla es que un enlace suelto no salga azul de Bootstrap,
 * sino del color del texto que lo rodea. Pero escrita como ".fv2 a" tiene
 * especificidad 0,1,1 (una clase + un tipo), y por tanto GANA a cualquier
 * componente nuestro de una sola clase (0,1,0):
 *
 *     .fv2-chip--go { color: var(--fv2-on-accent); }   <- 0,1,0, perdia
 *
 * Consecuencia real: los botones "Edita" de la pestaña Ficha salian con el texto
 * azul marino sobre fondo azul marino, ilegibles. Y lo mismo le pasaba, sin que
 * se notara tanto, a .fv2-tab (pestañas no activas), .fv2-acc-dots y .fv2-btn-wide.
 * El sintoma que lo delata: en la misma fila, un boton que era <span> SI se leia.
 *
 * :where() aporta especificidad CERO, así que la regla queda en 0,0,1: sigue
 * ganando al azul de Bootstrap (misma especificidad, pero este archivo carga
 * despues) y pierde contra cualquier clase nuestra, que es lo que se quiere.
 */
:where(.fv2) a {
	color: inherit;
	text-decoration: none;
}

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

/* La app pinta un fondo distinto en <main>; lo igualamos sólo en la home v2 */
body.fv2-page,
body.fv2-page #wrapper,
body.fv2-page main#middle {
	background: #f9f9ff;
}

/*
 * Sticky footer.
 * #wrapper no es un contenedor flex en base.tpl, así que el .flex-fill de
 * <main id="middle"> hoy no hace nada y el footer queda flotando a media
 * página cuando el contenido es corto. La Home v2 es bastante más compacta
 * que el menú anterior (iconos de 58px en vez de imágenes de 100px), así que
 * el hueco se nota. Lo convertimos en columna flex — sólo en body.fv2-page,
 * para no alterar el layout del resto de la aplicación.
 */
body.fv2-page #wrapper {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
	min-height: 100dvh; /* evita el salto por la barra de URL en móvil */
}

/*
 * ⚠️ NO QUITAR EL !important DE AQUÍ ABAJO.
 *
 * En base.tpl, #wrapper_content y <main id="middle"> llevan la clase .flex-fill,
 * y los utilities de Bootstrap 5 se declaran con !important:
 *
 *     .flex-fill { flex: 1 1 auto !important; }   <- css/fisic-css/core.css:5998
 *
 * Al convertir #wrapper en columna flex, #wrapper_content (que sólo contiene la
 * modal de reserva, oculta) se volvió un item que CRECE y se repartió el espacio
 * libre con <main>, empujando la portada hacia abajo: salía una banda vacía de
 * ~185px entre la cabecera y el saludo. Sin !important estas dos reglas pierden
 * contra .flex-fill y el hueco vuelve.
 */
body.fv2-page #wrapper_content {
	flex: 0 0 auto !important;   /* la modal está oculta: no debe ocupar alto */
}

body.fv2-page main#middle {
	flex: 1 1 auto !important;   /* es el único que debe crecer */

	/*
	 * ⚠️ LAS DOS DECLARACIONES VAN JUNTAS. Quitar una rompe la otra.
	 *
	 * <main> lleva la clase mx-auto de base.tpl. En flexbox, un item con margen
	 * AUTO en el eje transversal NO se estira: la spec sólo da stretch si
	 * "neither of the cross-axis margins are auto". Como #wrapper es flex en
	 * columna, el eje transversal es el horizontal, así que mx-auto dejaba
	 * #middle en shrink-to-fit y la portada salía estrecha.
	 *
	 * El primer arreglo fue poner los márgenes a 0. Funcionó para el ancho, pero
	 * creó otro problema: el tema le pone a #middle un max-width propio, y sin
	 * márgenes automáticos no puede centrarse dentro de ese tope. En una pantalla
	 * de 2552px quedaba de 1655px pegado a la izquierda, con 900px de vacío a la
	 * derecha, y todo lo de dentro heredaba ese descentrado.
	 *
	 * La solución correcta es no depender del stretch: con width:100% el ancho ya
	 * es definido, así que los márgenes automáticos vuelven a ser seguros y hacen
	 * su trabajo de centrar.
	 */
	width: 100%;
	margin-left: auto !important;
	margin-right: auto !important;

	/*
	 * El tema admin mete padding: 30px en #middle. Para la Home v2 lo ajustamos:
	 * el saludo ya trae su propio aire y en móvil esos 30px se notan.
	 */
	padding-top: 10px;
	padding-bottom: 0;
}

body.fv2-page #footer {
	flex: none;
	margin-top: auto;
}

/*
 * ANCHO COMPLETO en todas las pantallas del rediseño.
 *
 * El tema recorta el área de contenido en pantallas grandes (core.css:20024):
 *
 *     @media (min-width: 992px) {
 *       body.layout-admin #middle.mx-auto { max-width: 1655px !important; }
 *     }
 *
 * En un monitor de 2500px eso deja 850px de vacío a un lado. Las pantallas v2
 * gobiernan su propio ancho: el contenedor .fv2 limita a 640px cuando toca (la
 * portada del socio, pensada para el móvil) y lo libera cuando la pantalla lo
 * pide (.fv2-ficha, .fv2-listado). Así que el tope del tema sobra.
 *
 * ⚠️ El selector lleva .mx-auto y main a propósito: la regla del tema es
 * !important, así que sólo se puede ganar con MÁS ESPECIFICIDAD. La del tema es
 * (1,2,1); ésta es (1,2,2). Quitarle el `main` o el `.mx-auto` la deja empatada
 * o por debajo y el tope vuelve, sin que nada avise.
 */
body.fv2-page main#middle.mx-auto {
	max-width: none !important;
}

/* =============================================================================
 * CABECERA EN MÓVIL (body.fv2-tema)
 * -----------------------------------------------------------------------------
 * Va sobre .fv2-tema y no sobre .fv2-page a propósito: la cabecera es la misma en
 * TODAS las pantallas de la app, migradas o no, y verla cambiar de forma al pasar
 * de /usuarios a /caja sería peor que dejarla como estaba. .fv2-tema la marca
 * base.tpl cuando el cliente tiene home_diseno="v2", así que los clientes sin el
 * rediseño no se ven afectados.
 *
 * EL PROBLEMA (medido): en móvil la cabecera ocupaba 149px —un 17% de la
 * pantalla— en tres filas: logos, los cinco iconos de navegación y las acciones
 * de usuario. Mucho sitio para lo que hay.
 *
 * ⚠️ POR QUÉ NO SE COMPRIME A DOS FILAS.
 *
 * El primer intento subió las acciones al hueco vacío de la derecha del logo con
 * position:absolute. Funcionaba en /usuarios (acciones de 155px) y se rompía en
 * la portada: cuando el usuario tiene MÁS DE UN CENTRO, ese bloque incluye además
 * un <select> con los centros y pasa a medir ~290px, así que empezaba en x=101 y
 * se montaba encima del logo, que llega hasta x=185.
 *
 * Y no hay forma de decidirlo en CSS: la anchura de las acciones depende de si
 * ese cliente tiene varios centros, o sea de los datos. Cualquier tope fijo
 * acierta en unas instalaciones y falla en otras.
 *
 * Así que se dejan las tres filas —que se recolocan solas según lo que quepa— y
 * lo que se hace es APRETARLAS. Medido desactivando cada cosa por separado en la
 * portada, que es la pantalla peor (lleva el selector de centros):
 *
 *     149px  original
 *     135px  con esto (los rellenos aportan 24px; el tope del logo, 28px)
 *
 * Tres filas de objetivos táctiles de ~40px tienen ese suelo: no se puede bajar
 * mucho más sin hacer los iconos incómodos de pulsar.
 * ========================================================================== */
@media (max-width: 991.98px) {

	/* El tema deja 12px arriba y abajo del navbar; en móvil se notan */
	body.fv2-tema #header .navbar {
		padding-top: 2px;
		padding-bottom: 2px;
		row-gap: 0;
	}

	/* La fila de iconos de navegación traía su propio relleno vertical */
	body.fv2-tema #header .navbar-nav.flex-row > li {
		padding-top: 0 !important;
		padding-bottom: 0 !important;
	}

	/* Las acciones de usuario, pegadas a la fila de iconos */
	body.fv2-tema #header .navbar > ul.list-inline {
		margin-top: 0;
		margin-bottom: 0;
	}

	/*
	 * El logo del cliente lo sube él y puede venir con cualquier alto, así que en
	 * móvil se le pone tope. Es la palanca que MÁS baja la cabecera —medido: 28px—
	 * pero también la única que el cliente nota, porque le encoge la marca.
	 *
	 * 46px es un punto medio deliberado: el de fisic pasa de 60 a 46 y sigue
	 * leyéndose. Bajarlo a 40 sólo ahorra 6px más y no compensa. Si algún cliente
	 * quiere su logo entero, subir este número es todo lo que hay que tocar.
	 */
	body.fv2-tema #header .navbar-brand img {
		max-height: 46px;
		width: auto;
	}
}


/* Icon font (Material Symbols Outlined, subconjunto — ver head.tpl) */
.fv2 .fv2-ms {
	font-family: 'Material Symbols Outlined';
	font-weight: 400;
	font-style: normal;
	line-height: 1;
	display: inline-block;
	letter-spacing: normal;
	text-transform: none;
	white-space: nowrap;
	direction: ltr;
	font-feature-settings: 'liga';
	-webkit-font-feature-settings: 'liga';
	-webkit-font-smoothing: antialiased;
}

/* -------------------------------------------------- 3. Greeting ---------- */
.fv2-greet {
	padding: 18px var(--fv2-gutter) 2px;
}

.fv2-greet-eyebrow {
	font: 400 13px/1.4 var(--fv2-font-body);
	color: var(--fv2-outline);
}

.fv2-greet-name {
	font: 700 27px/1.05 var(--fv2-font-head);
	letter-spacing: -.01em;
	color: var(--fv2-on-surface);
	margin: 0;
}

/* -------------------------------------------------- 4. SectionHeader ----- */
.fv2-section {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 24px var(--fv2-gutter) 12px;
}

.fv2-section-title {
	font: 600 12px/1.4 var(--fv2-font-body);
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--fv2-outline);
	margin: 0;
}

.fv2-section-extra {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	font: 500 11px var(--fv2-font-body);
	color: var(--fv2-muted);
}

.fv2-section-extra .fv2-ms {
	font-size: 16px;
	color: var(--fv2-muted);
}

/* -------------------------------------------------- 5. HeroCard ---------- */
.fv2-hero-wrap {
	padding: 0 var(--fv2-gutter);
	padding-top: 19px;
}

.fv2-hero {
	position: relative;
	display: block;
	height: 158px;
	border-radius: var(--fv2-radius-card);
	overflow: hidden;
	box-shadow: var(--fv2-shadow-hero);
	transition: transform .18s ease, box-shadow .18s ease;
}

.fv2-hero:hover,
.fv2-hero:focus-visible {
	transform: translateY(-2px);
	box-shadow: 0 10px 26px rgba(18, 28, 44, .14);
}

/*
 * Placeholder de imagen.
 * El diseño original lleva fotografía (componente <image-slot>). Mientras no
 * haya fotos gestionables, pintamos un degradado de marca con un icono
 * "fantasma": queda intencionado, no roto. Para activar foto real basta con
 * poner background-image en .fv2-hero-media (atributo style desde el .tpl).
 */
.fv2-hero-media,
.fv2-feat-media {
	position: absolute;
	inset: 0;
	background:
		radial-gradient(120% 110% at 12% 8%, rgba(255, 255, 255, .30) 0%, rgba(255, 255, 255, 0) 55%),
		linear-gradient(135deg, var(--fv2-accent) 0%, var(--fv2-accent-strong) 58%, #2b2496 100%);
	background-size: cover;
	background-position: center;
}

.fv2-hero-ghost,
.fv2-feat-ghost {
	position: absolute;
	right: -14px;
	bottom: -22px;
	font-size: 132px;
	color: rgba(255, 255, 255, .16);
	pointer-events: none;
	user-select: none;
}

.fv2-feat-ghost {
	font-size: 96px;
	right: -10px;
	bottom: -16px;
}

/*
 * Icono personalizado del cliente sobre una Hero/FeatureCard (sin foto).
 * Los iconos del catálogo son trazo oscuro pensados para fondo claro; aquí van
 * sobre el degradado de marca, así que se pintan en blanco (brightness+invert)
 * y centrados, dejando el título abajo. Es el equivalente v2 del "icono grande"
 * del diseño anterior. Si la foto está puesta, esto no se pinta (manda la foto).
 */
.fv2-hero-icoimg,
.fv2-feat-icoimg {
	position: absolute;
	left: 50%;
	top: 42%;
	transform: translate(-50%, -50%);
	width: 76px;
	height: 76px;
	object-fit: contain;
	pointer-events: none;
	user-select: none;
	filter: brightness(0) invert(1) drop-shadow(0 2px 6px rgba(18, 20, 52, .35));
}

.fv2-feat-icoimg {
	width: 56px;
	height: 56px;
	top: 40%;
}

.fv2-hero-scrim,
.fv2-feat-scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(18, 20, 52, .82), rgba(18, 20, 52, .05) 62%);
	pointer-events: none;
}

.fv2-hero-body {
	position: absolute;
	left: 16px;
	right: 62px;
	bottom: 14px;
	pointer-events: none;
}

.fv2-hero-title {
	font: 700 23px/1.05 var(--fv2-font-head);
	color: #fff;
	margin: 0;
}

.fv2-hero-sub {
	font: 400 12px/1.4 var(--fv2-font-body);
	color: rgba(255, 255, 255, .85);
	margin: 3px 0 0;
}

.fv2-hero-go {
	position: absolute;
	top: 14px;
	right: 14px;
	width: 34px;
	height: 34px;
	border-radius: 50%;
	background: rgba(255, 255, 255, .92);
	display: flex;
	align-items: center;
	justify-content: center;
	pointer-events: none;
}

.fv2-hero-go .fv2-ms {
	font-size: 20px;
}

/* -------------------------------------------------- 6. FeatureCard ------- */
.fv2-feat-grid {
	padding: 12px var(--fv2-gutter) 0;
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 12px;
}

.fv2-feat {
	position: relative;
	display: block;
	height: 132px;
	border-radius: var(--fv2-radius-card);
	overflow: hidden;
	box-shadow: var(--fv2-shadow-hero);
	transition: transform .18s ease, box-shadow .18s ease;
}

.fv2-feat:hover,
.fv2-feat:focus-visible {
	transform: translateY(-2px);
	box-shadow: 0 10px 26px rgba(18, 28, 44, .14);
}

/* Segunda tarjeta con un tinte distinto para que la pareja no se lea plana */
.fv2-feat--alt .fv2-feat-media {
	background:
		radial-gradient(120% 110% at 12% 8%, rgba(255, 255, 255, .28) 0%, rgba(255, 255, 255, 0) 55%),
		linear-gradient(135deg, #3f7ea8 0%, #2c5f86 58%, #1d4260 100%);
}

.fv2-feat-scrim {
	background: linear-gradient(to top, rgba(18, 20, 52, .82), rgba(18, 20, 52, 0) 65%);
}

.fv2-feat-title {
	position: absolute;
	left: 12px;
	right: 12px;
	bottom: 11px;
	font: 700 17px/1.05 var(--fv2-font-head);
	color: #fff;
	pointer-events: none;
}

/* -------------------------------------------------- 7. IconTile ---------- */
.fv2-tiles {
	padding: 0 14px;
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 14px 4px;
}

.fv2-tile {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 7px;
	padding: 6px 2px;
	position: relative;
	min-height: 88px;
	border-radius: 12px;
	transition: transform .15s ease;
}

.fv2-tile:hover,
.fv2-tile:focus-visible {
	transform: translateY(-2px);
}

.fv2-tile:focus-visible {
	outline: 2px solid var(--fv2-accent);
	outline-offset: 2px;
}

.fv2-tile-ico {
	width: 58px;
	height: 58px;
	border-radius: var(--fv2-radius-tile);
	background: var(--fv2-accent-soft);
	display: flex;
	align-items: center;
	justify-content: center;
	flex: none;
}

.fv2-tile-ico .fv2-ms {
	font-size: 25px;
}

/*
 * Tipo 'img' — icono personalizado por el cliente desde
 * Configuración > Empresa > Logos del menú (upload/menu/<base>.<ext>).
 * Los SVG del tema son ilustraciones a color, así que no se recolorean:
 * se muestran tal cual dentro de la pastilla, con un poco menos de tamaño
 * que el icono de fuente para que la rejilla siga alineada.
 */
.fv2-tile-ico img {
	width: 34px;
	height: 34px;
	object-fit: contain;
}

/*
 * Tipo 'foto' — foto grande subida a upload/menu/hero/<base>.<ext>.
 * La tile pasa a ocupar dos columnas y se pinta como una FeatureCard.
 */
.fv2-tile--foto {
	grid-column: span 2;
	min-height: 104px;
	padding: 0;
	border-radius: var(--fv2-radius-card);
	overflow: hidden;
	box-shadow: var(--fv2-shadow-hero);
	justify-content: flex-end;
	align-items: flex-start;
}

.fv2-tile-foto {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	background-color: var(--fv2-accent-soft);
}

.fv2-tile-foto-scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(18, 20, 52, .82), rgba(18, 20, 52, 0) 68%);
	pointer-events: none;
}

.fv2-tile--foto .fv2-tile-label {
	position: relative;
	z-index: 1;
	text-align: left;
	color: #fff;
	font: 700 15px/1.15 var(--fv2-font-head);
	padding: 0 12px 11px;
	text-shadow: 0 1px 3px rgba(18, 20, 52, .5);
}

.fv2-tile--foto .fv2-tile-badge {
	right: 10px;
	transform: none;
	top: 10px;
}

.fv2-tile--foto .fv2-tile-progress {
	position: absolute;
	bottom: 6px;
	right: 10px;
	z-index: 1;
	background: rgba(255, 255, 255, .35);
}

/* En pantallas de 3 columnas, una foto a doble ancho deja hueco: que ocupe todo */
@media (max-width: 575px) {
	.fv2-tile--foto { grid-column: 1 / -1; }
}

/*
 * Tamaño de las etiquetas. El mockup era un móvil de 392px, donde 10.5px
 * cuadraba; en escritorio se leía diminuto al lado del menú anterior (que usa
 * ~18px). Se sube la escala en todos los breakpoints.
 */
.fv2-tile-label {
	font: 500 11.5px/1.25 var(--fv2-font-body);
	text-align: center;
	color: var(--fv2-on-surface-var);
	display: block;
	max-width: 100%;
}

/* Contador (chats sin leer, sugerencias pendientes) */
.fv2-tile-badge {
	position: absolute;
	top: 0;
	right: 50%;
	transform: translateX(38px);
	min-width: 19px;
	height: 19px;
	padding: 0 5px;
	border-radius: 10px;
	background: var(--fv2-error);
	color: #fff;
	font: 700 10px/19px var(--fv2-font-body);
	text-align: center;
	box-shadow: 0 0 0 2px var(--fv2-surface);
}

/* Barra de avance de desarrollo — se conserva, pero discreta */
.fv2-tile-progress {
	width: 34px;
	height: 3px;
	border-radius: 2px;
	background: var(--fv2-divider);
	overflow: hidden;
	margin-top: -2px;
}

.fv2-tile-progress > span {
	display: block;
	height: 100%;
	background: var(--fv2-ok);
}

.fv2-tile.is-incomplete .fv2-tile-progress > span { background: var(--fv2-warn); }
.fv2-tile.is-disabled   .fv2-tile-progress > span { background: var(--fv2-muted); }

.fv2-tile.is-disabled {
	opacity: .45;
	pointer-events: none;
}

/* -------------------------------------------------- 8. InfoRow / lista --- */
.fv2-list {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	overflow: hidden;
	box-shadow: var(--fv2-shadow-card);
}

.fv2-row {
	display: flex;
	align-items: center;
	gap: 13px;
	padding: 15px 16px;
	border-bottom: 1px solid var(--fv2-divider);
	background: var(--fv2-card);
	transition: background .15s ease;
}

.fv2-row:last-child {
	border-bottom: 0;
}

.fv2-row:hover {
	background: var(--fv2-card-alt);
}

.fv2-row > .fv2-ms {
	font-size: 20px;
	flex: none;
}

.fv2-row-icon-img {
	width: 20px;
	height: 20px;
	object-fit: contain;
	flex: none;
}

/* Miniatura para filas con FOTO propia (p.ej. avisos CMS con cms_icono): más
 * grande y con "cover" para que se vea la foto, no un icono de 20px encogido. */
.fv2-row-thumb {
	width: 44px;
	height: 44px;
	border-radius: 10px;
	object-fit: cover;
	flex: none;
}

.fv2-row-label {
	flex: 1;
	font: 500 13px/1.4 var(--fv2-font-body);
	color: var(--fv2-on-surface);
	min-width: 0;
}

.fv2-row-chev {
	font-size: 18px !important;
	color: var(--fv2-chevron) !important;
	flex: none;
}

/* -------------------------------------------------- 9. Aviso / alerta ---- */
.fv2-alert {
	margin: 12px var(--fv2-gutter) 0;
	display: flex;
	align-items: center;
	gap: 12px;
	background: var(--fv2-error-container);
	border-radius: var(--fv2-radius-card);
	padding: 14px;
}

.fv2-alert .fv2-ms {
	font-size: 24px;
	color: var(--fv2-error);
}

.fv2-alert-title {
	font: 600 13px var(--fv2-font-body);
	color: var(--fv2-on-error-cont);
}

.fv2-alert-sub {
	font: 400 11px var(--fv2-font-body);
	color: var(--fv2-error);
}

/* -------------------------------------------------- 10. Responsive ------- */
/* Móvil pequeño: los rótulos de 3 columnas se estrechan mucho */
@media (max-width: 359px) {
	.fv2 { --fv2-gutter: 14px; }
	.fv2-tile-ico { width: 52px; height: 52px; }
	.fv2-tile-ico .fv2-ms { font-size: 23px; }
}

/* Tablet en adelante: más columnas y tarjetas algo más altas */
@media (min-width: 576px) {
	.fv2-tiles { grid-template-columns: repeat(4, 1fr); gap: 16px 6px; }
	.fv2-tile-label { font-size: 12.5px; }
}

@media (min-width: 768px) {
	.fv2 { max-width: 720px; padding-top: 4px; }
	.fv2-tiles { grid-template-columns: repeat(5, 1fr); }
	.fv2-hero { height: 190px; }
	.fv2-feat { height: 150px; }

	/*
	 * En móvil las secciones se separan solas por el scroll. En pantalla ancha
	 * quedaban flotando en medio de la nada, así que se les pone una línea
	 * de pelo que las lee como bloques.
	 */
	.fv2-section {
		border-top: 1px solid var(--fv2-border);
		margin-top: 10px;
		padding-top: 22px;
	}
}

/*
 * Escritorio: el diseño nace de un mockup de móvil, y a 1900px de ancho una
 * columna de 640px se ve perdida. Se ensancha el contenido, se añaden columnas
 * y se agrandan las pastillas para que ocupe el espacio con intención en vez
 * de parecer un móvil estirado.
 */
@media (min-width: 1200px) {
	.fv2 {
		max-width: 940px;
		--fv2-gutter: 24px;
	}
	.fv2-tiles {
		grid-template-columns: repeat(6, 1fr);
		gap: 22px 10px;
		padding: 0 18px;
	}
	.fv2-tile { min-height: 108px; }
	.fv2-tile-ico { width: 72px; height: 72px; }
	.fv2-tile-ico .fv2-ms { font-size: 32px; }
	.fv2-tile-ico img { width: 42px; height: 42px; }
	.fv2-tile-label { font-size: 14px; }

	/* Los rótulos de sección acompañan al tamaño de las etiquetas */
	.fv2-section-title { font-size: 13px; }

	.fv2-greet { padding-top: 22px; }
	.fv2-greet-name { font: 700 32px/1.05 var(--fv2-font-head); }

	.fv2-hero { height: 220px; }
	.fv2-hero-title { font-size: 26px; }
	.fv2-feat { height: 168px; }
	.fv2-feat-title { font-size: 19px; }

	.fv2-row-label { font-size: 14px; }
	.fv2-row { padding: 17px 18px; }
}

@media (min-width: 1600px) {
	.fv2 { max-width: 1080px; }
	.fv2-tiles { grid-template-columns: repeat(7, 1fr); }
}

/* =============================================================================
 * FICHA DE CLIENTE (mockup 2b)
 * -----------------------------------------------------------------------------
 * Sólo la carcasa: cabecera de perfil + navegación. El contenido de cada
 * pestaña llega por AJAX desde otras plantillas y conserva su aspecto actual.
 *
 *   móvil     una columna, pestañas como chips con scroll horizontal
 *   tablet    más aire, datos a dos columnas, chips sin scroll
 *   ≥1200px   dos columnas: perfil + navegación | contenido
 * ========================================================================== */

/*
 * La ficha usa TODO el ancho disponible: lleva contenido denso (tablas de bonos,
 * valoraciones, la programación) y el tope de la página ya lo pone el .container
 * de la app según ancho_pantalla.
 *
 * ⚠️ Los max-width de la ficha se escriben con DOBLE clase (.fv2.fv2-ficha).
 * El elemento lleva .fv2 y .fv2-ficha a la vez, así que contra un `.fv2` suelto
 * habría empate de especificidad y decidiría el orden en el archivo — que es
 * justo lo que pasaba: `body.layout-ancho .fv2` (más abajo) le ganaba a
 * `body.layout-ancho .fv2-ficha` y la ficha se quedaba en el ancho de la
 * portada. Con dos clases gana siempre, esté donde esté.
 */
.fv2.fv2-ficha { max-width: none; }

/* -------------------------------------------------- ProfileHeader -------- */
.fv2-profile {
	background: var(--fv2-card);
	border-radius: var(--fv2-radius-card);
	box-shadow: var(--fv2-shadow-card);
	margin: 0 var(--fv2-gutter) 16px;
	padding: 18px;
}

.fv2-profile-main {
	display: flex;
	align-items: center;
	gap: 14px;
}

.fv2-avatar {
	flex: 0 0 auto;
	width: 62px;
	height: 62px;
	border-radius: 50%;
	overflow: hidden;
	background: var(--fv2-accent-soft);
	display: flex;
	align-items: center;
	justify-content: center;
}

.fv2-avatar img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Sin foto: iniciales. Evita el hueco gris y no obliga a subir imagen. */
.fv2-avatar-ini {
	font: 700 22px/1 var(--fv2-font-head);
	color: var(--fv2-accent);
	letter-spacing: .02em;
}

.fv2-profile-id { min-width: 0; }

.fv2-profile-name {
	font: 700 24px/1.1 var(--fv2-font-head);
	letter-spacing: -.01em;
	color: var(--fv2-on-surface);
	margin: 0;
	overflow-wrap: anywhere;
}

.fv2-profile-badges {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin-top: 8px;
}

.fv2-badge {
	font: 600 10.5px/1 var(--fv2-font-body);
	border: 1px solid var(--fv2-border);
	color: var(--fv2-on-surface-var);
	padding: 3px 10px;
	border-radius: 8px;
	white-space: nowrap;
}

.fv2-badge--on  { background: var(--fv2-accent); border-color: var(--fv2-accent); color: var(--fv2-on-accent); }
.fv2-badge--off { background: var(--fv2-error-container); border-color: var(--fv2-error-container); color: var(--fv2-on-error-cont); }

/* -------------------------------------------------- Datos de contacto ---- */
.fv2-profile-data {
	display: grid;
	grid-template-columns: 1fr;
	gap: 2px;
	margin-top: 16px;
	border-top: 1px solid var(--fv2-divider);
	padding-top: 12px;
}

.fv2-data {
	display: flex;
	align-items: center;
	gap: 11px;
	padding: 7px 0;
	color: inherit;
}

.fv2-data .fv2-ms { font-size: 19px; flex: none; color: var(--fv2-muted); }

.fv2-data-body { display: flex; flex-direction: column; min-width: 0; }
.fv2-data-lbl  { font: 400 10.5px/1.3 var(--fv2-font-body); color: var(--fv2-outline); }
.fv2-data-val  { font: 500 13.5px/1.35 var(--fv2-font-body); color: var(--fv2-on-surface); overflow-wrap: anywhere; }

a.fv2-data:hover .fv2-data-val { color: var(--fv2-accent); }

/*
 * Input de fecha de alta (staff): un datepicker dentro de la fila .fv2-data, con
 * la misma pinta que un valor pero editable. Sin esto heredaba el form-control de
 * Bootstrap y desentonaba (era lo que salía descuadrado en el rediseño).
 */
.fv2-data-input {
	width: 130px;
	max-width: 100%;
	margin-top: 2px;
	padding: 5px 9px;
	font: 500 13.5px/1.2 var(--fv2-font-body);
	color: var(--fv2-on-surface);
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-sm);
}

.fv2-data-input:focus {
	outline: none;
	border-color: var(--fv2-accent);
	box-shadow: 0 0 0 3px var(--fv2-accent-soft);
}

.fv2-profile .fv2-stats { margin-top: 14px; }

/* -------------------------------------------------- Navegación ----------- */
/*
 * display explícito y con la especificidad de .fv2-ficha a propósito: el <ul>
 * reutiliza el id #nav_responsive de la ficha clásica, donde llevaba las clases
 * .collapse .d-lg-block de Bootstrap. Si algo del tema (o un $.SOW.reinit tras
 * cargar una pestaña por AJAX) vuelve a tratarlo como un collapse, .collapse
 * pondría display:none y las pestañas desaparecerían sin más.
 */
.fv2-ficha .fv2-tabs   { display: block; }
.fv2-ficha .fv2-tablist { display: flex; }

.fv2-tabs { margin: 0 0 16px; }

.fv2-tablist {
	list-style: none;
	margin: 0;
	padding: 0 var(--fv2-gutter);
	display: flex;
	gap: 8px;
	/* Móvil: no caben todas, se deslizan. Sin barra visible. */
	overflow-x: auto;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
}

.fv2-tablist::-webkit-scrollbar { display: none; }

.fv2-tablist .nav-item { flex: 0 0 auto; }

.fv2-tab {
	position: relative;
	display: flex;
	align-items: center;
	gap: 7px;
	white-space: nowrap;
	cursor: pointer;
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-sm);
	padding: 10px 14px;
	font: 600 12.5px/1 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
	/*
	 * ⚠️ NO animar aquí "background" ni "color": SÓLO el borde.
	 *
	 * El fondo y el texto de una pestaña se invierten al activarse (fondo claro +
	 * texto oscuro  ->  fondo acento + texto claro). Si se animan, durante los
	 * 150 ms de la transición cada uno va por su cuenta y hay fotogramas con los
	 * dos claros o los dos oscuros: el texto se vuelve ilegible justo al cambiar
	 * de pestaña. Y como .fv2-ms no heredaba la transición, el icono saltaba de
	 * golpe y el texto no, que era aún más raro de ver.
	 *
	 * Con el cambio instantáneo el par fondo/texto nunca se descompone.
	 */
	transition: border-color .15s ease;
}

.fv2-tab .fv2-ms { font-size: 19px; color: var(--fv2-muted); }
.fv2-tab:hover { border-color: var(--fv2-accent); }

/* .active lo pone y lo quita mi_cuenta.tpl.js sobre el <li> */
.fv2-tablist .nav-item.active .fv2-tab {
	background: var(--fv2-accent);
	border-color: var(--fv2-accent);
	color: var(--fv2-on-accent);
}

.fv2-tablist .nav-item.active .fv2-tab .fv2-ms { color: var(--fv2-on-accent); }

/* Aviso de mensajes sin leer */
.fv2-tab-dot {
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: var(--fv2-error);
	flex: none;
}

/* -------------------------------------------------- Contenido ------------ */
.fv2-ficha-body { padding: 0 var(--fv2-gutter); }

.fv2-ficha-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: 12px;
}

.fv2-btn-wide {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: 10px;
	padding: 7px 12px;
	font: 600 11.5px/1 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
	cursor: pointer;
}

.fv2-btn-wide .fv2-ms { font-size: 17px; color: var(--fv2-muted); }
.fv2-btn-wide:hover { border-color: var(--fv2-accent); }

/* El botón de ensanchar sólo tiene sentido donde hay dos columnas */
.fv2-btn-wide { display: none; }

/* -------------------------------------------------- Tablet --------------- */
@media (min-width: 768px) {

	.fv2-profile { padding: 22px; }
	.fv2-avatar { width: 76px; height: 76px; }
	.fv2-avatar-ini { font-size: 27px; }
	.fv2-profile-name { font-size: 28px; }

	/* Los datos caben a dos columnas y el bloque deja de ser una lista larga */
	.fv2-profile-data { grid-template-columns: 1fr 1fr; column-gap: 20px; }

	/* Ya caben todas las pestañas: se envuelven en vez de deslizarse */
	.fv2-tablist { flex-wrap: wrap; overflow-x: visible; }
	.fv2-tab { font-size: 13px; padding: 11px 16px; }
}

/* -------------------------------------------------- Escritorio ----------- */
@media (min-width: 1200px) {

	/*
	 * SIN TOPE DE ANCHO (decisión del usuario, ago-2026). Antes había aquí un
	 * max-width: 1320px que dejaba la ficha centrada con bandas de vacío a los
	 * lados en monitores grandes. La columna del perfil sigue fija en 380px, así
	 * que todo el ancho que se gana se lo lleva el contenido de las pestañas, que
	 * es donde están las tablas y los formularios.
	 *
	 * ⚠️ Esto sólo surte efecto porque el tope de #middle también está levantado
	 * (ver "ANCHO COMPLETO" arriba); si alguien devuelve aquel max-width, la ficha
	 * vuelve a cortarse en 1655px sin que nada avise.
	 */
	.fv2.fv2-ficha {
		max-width: none;
		display: grid;
		/* 380px: con 320 el nombre se partía en tres líneas y las tres cifras
		   salían apretadas contra los bordes de su tarjeta */
		grid-template-columns: 380px minmax(0, 1fr);
		column-gap: 26px;
		align-items: start;
	}

	/*
	 * UNA sola fila, y perfil+pestañas en una única celda.
	 *
	 * ⚠️ NO volver a repartirlos en dos filas con el contenido en
	 * "grid-row: 1 / span 2". Cuando un item abarca varias filas automáticas, el
	 * navegador reparte su altura ENTRE ellas en vez de echarla a la última: con
	 * una pestaña de contenido alto la fila 1 crecía enormemente y las pestañas,
	 * que estaban en la fila 2, terminaban fuera de la pantalla. Medían bien y
	 * eran visibles, pero quedaban miles de píxeles más abajo.
	 */
	/*
	 * La columna izquierda es UNA SOLA TARJETA: perfil y pestañas dentro, sin
	 * costuras. Antes el perfil traía su propio fondo, sombra y márgenes, así que
	 * se veían dos cajas sueltas una encima de otra con un hueco en medio.
	 *
	 * El cromo va aquí y no en .fv2-profile porque en móvil .fv2-ficha-side es
	 * display:contents —no existe como caja— y allí el perfil sí debe ser su
	 * propia tarjeta. Por eso todo esto vive dentro del @media.
	 */
	.fv2-ficha > .fv2-ficha-side {
		display: block;
		grid-column: 1;
		grid-row: 1;
		background: var(--fv2-card);
		border-radius: var(--fv2-radius-card);
		box-shadow: var(--fv2-shadow-card);
		margin-left: var(--fv2-gutter);
		overflow: hidden;
	}

	.fv2-ficha > .fv2-ficha-body {
		grid-column: 2;
		grid-row: 1;
		padding-right: var(--fv2-gutter);
		padding-left: 0;
	}

	/*
	 * El perfil deja de ser una tarjeta y pasa a ser el contenido de arriba de la
	 * columna: fuera fondo, sombra, esquinas y márgenes propios. Sólo conserva su
	 * relleno, que ahora es el de la tarjeta común.
	 */
	.fv2-ficha-side .fv2-profile {
		background: transparent;
		box-shadow: none;
		border-radius: 0;
		margin: 0;
	}

	/* Las pestañas, en la misma tarjeta, separadas por una línea */
	.fv2-ficha-side .fv2-tabs {
		margin: 0;
		padding: 8px 10px 12px;
		border-top: 1px solid var(--fv2-divider);
	}

	/*
	 * DEFENSA: cualquier hijo que NO sea uno de los dos esperados se manda a una
	 * fila propia por debajo, a todo el ancho. El contenido de las pestañas es
	 * HTML heredado inyectado dentro de la rejilla; si a una le falta un cierre,
	 * el navegador no cierra .fv2-ficha y el pie pasa a ser hijo de la rejilla.
	 * Así, en el peor caso queda debajo y a la vista, no encima de nada.
	 */
	.fv2-ficha > :not(.fv2-ficha-side):not(.fv2-ficha-body) {
		grid-column: 1 / -1;
		grid-row: 2;
	}

	/* Y aunque algo se solape, las pestañas quedan por encima */
	.fv2-ficha .fv2-tabs { position: relative; z-index: 2; }

	/* En la columna estrecha los datos vuelven a una sola columna */
	.fv2-profile-data { grid-template-columns: 1fr; }

	/* El perfil gana presencia: es la identidad de la pantalla */
	.fv2-profile { padding: 24px 22px 20px; }
	.fv2-profile-main { gap: 18px; }
	.fv2-avatar { width: 92px; height: 92px; }
	.fv2-avatar-ini { font-size: 33px; }
	.fv2-profile-name { font-size: 31px; }
	.fv2-data { padding: 9px 0; }
	.fv2-data .fv2-ms { font-size: 21px; }
	.fv2-data-lbl { font-size: 11.5px; }
	.fv2-data-val { font-size: 15px; }
	.fv2-profile .fv2-stat-num { font-size: 23px; }
	.fv2-profile .fv2-stat-lbl { font-size: 10px; }

	/* Y las pestañas pasan de chips a lista vertical.
	   Sin sangría propia: el relleno lo pone ya .fv2-ficha-side .fv2-tabs */
	.fv2-ficha .fv2-tablist {
		flex-direction: column;
		flex-wrap: nowrap;
		gap: 2px;
		padding-left: 0;
		padding-right: 0;
	}

	.fv2-tablist .nav-item { flex: 1 1 auto; }

	.fv2-tab {
		border-color: transparent;
		background: transparent;
		padding: 11px 12px;
		border-radius: 10px;
	}

	/* --fv2-card seria invisible: es el fondo de la propia tarjeta de la columna */
	.fv2-tab:hover { background: var(--fv2-card-alt); border-color: transparent; }

	.fv2-tab-dot { margin-left: auto; }

	.fv2-btn-wide { display: inline-flex; }

	/* Ensanchar: se oculta la columna izquierda y el contenido ocupa todo.
	   Doble clase por el mismo motivo que los max-width de arriba. */
	.fv2.fv2-ficha--wide { grid-template-columns: minmax(0, 1fr); }
	.fv2-ficha--wide > .fv2-ficha-side { display: none; }
	.fv2-ficha--wide > .fv2-ficha-body { grid-column: 1; padding-left: var(--fv2-gutter); }
}

/* =============================================================================
 * PIEL v2 PARA EL CONTENIDO DE LAS PESTAÑAS
 * -----------------------------------------------------------------------------
 * Las cinco pestañas (mi_cuenta, mis_bonos, entrenamientos, valoraciones, chat)
 * son ~1.140 líneas de plantilla con tablas, diálogos y handlers JS propios.
 * Reescribirlas es trabajo de días y riesgo alto: cada una tiene sus contratos
 * con el JS (onclick, data-*, footable, datatables...).
 *
 * En vez de eso se les pone piel a los primitivos de Bootstrap que ya usan,
 * acotado a .fv2-ficha-body. Cero cambios en sus plantillas => cero riesgo de
 * romper nada, y las cinco quedan coherentes con el rediseño de una vez.
 *
 * Todo aquí dentro está limitado a .fv2-ficha-body: no puede escaparse al resto
 * de la aplicación.
 * ========================================================================== */

.fv2-ficha-body {
	font-family: var(--fv2-font-body);
	color: var(--fv2-on-surface);
}

/* --- Tarjetas y secciones --- */
.fv2-ficha-body .section,
.fv2-ficha-body .card {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	box-shadow: var(--fv2-shadow-card);
}

.fv2-ficha-body .card { margin-bottom: 14px; }

/* --- Titulares --- */
.fv2-ficha-body h1, .fv2-ficha-body h2, .fv2-ficha-body h3,
.fv2-ficha-body h4, .fv2-ficha-body h5, .fv2-ficha-body .h4, .fv2-ficha-body .h5 {
	font-family: var(--fv2-font-head);
	font-weight: 700;
	letter-spacing: -.01em;
	color: var(--fv2-on-surface);
}

/* --- Tablas: es lo que más se ve en bonos y valoraciones --- */
.fv2-ficha-body table { font-size: 13.5px; }

.fv2-ficha-body thead th {
	font: 600 11px/1.3 var(--fv2-font-body);
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--fv2-outline);
	border-bottom: 1px solid var(--fv2-border);
	white-space: nowrap;
}

.fv2-ficha-body tbody td { border-color: var(--fv2-divider); vertical-align: middle; }
.fv2-ficha-body tbody tr:hover > td { background: var(--fv2-card-alt); }

/* --- Botones --- */
.fv2-ficha-body .btn {
	font-family: var(--fv2-font-body);
	font-weight: 600;
	border-radius: 10px;
}

.fv2-ficha-body .btn-primary {
	background: var(--fv2-accent);
	border-color: var(--fv2-accent);
	color: var(--fv2-on-accent);
}

.fv2-ficha-body .btn-primary:hover,
.fv2-ficha-body .btn-primary:focus {
	background: var(--fv2-accent-strong);
	border-color: var(--fv2-accent-strong);
}

/* --- Distintivos --- */
.fv2-ficha-body .badge {
	font-family: var(--fv2-font-body);
	font-weight: 600;
	border-radius: 8px;
}

/* --- Anidamiento de .section ---------------------------------------------
 * entrenamientos.tpl mete .section dentro de .section (una por pestaña), y con
 * la regla de arriba salía una tarjeta dentro de otra, con doble borde y doble
 * sombra. Las interiores pierden el cromo y sólo aportan espaciado.
 */
.fv2-ficha-body .section .section,
.fv2-ficha-body .card .card {
	border: 0;
	box-shadow: none;
	background: transparent;
}

/* --- Sub-pestañas internas ------------------------------------------------
 * Las usan mis_bonos (.nav-invert) y entrenamientos (.nav-tabs, 6 pestañas).
 * Se pintan como chips en vez de solapas: con 6 y en móvil, las solapas se
 * amontonan y se cortan; los chips fluyen y se deslizan.
 */
.fv2-ficha-body .nav-tabs {
	border-bottom: 0;
	gap: 8px;
	flex-wrap: nowrap;
	overflow-x: auto;
	scrollbar-width: none;
	padding-bottom: 2px;
	margin-bottom: 14px;
}

.fv2-ficha-body .nav-tabs::-webkit-scrollbar { display: none; }

.fv2-ficha-body .nav-tabs .nav-item { flex: 0 0 auto; }

.fv2-ficha-body .nav-tabs .nav-link {
	font: 600 12.5px/1 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-sm);
	padding: 10px 15px;
	white-space: nowrap;
	/* Anula el "transition: color, background-color, border-color" de Bootstrap.
	   Mismo motivo que en .fv2-tab: ver el aviso de ahí arriba. */
	transition: border-color .15s ease;
}

.fv2-ficha-body .nav-tabs .nav-link:hover { border-color: var(--fv2-accent); }

.fv2-ficha-body .nav-tabs .nav-link.active {
	color: var(--fv2-on-accent) !important;   /* mismo !important del tema, ver #mis_bonos */
	background: var(--fv2-accent);
	border-color: var(--fv2-accent);
}

/* A partir de tablet ya caben: se envuelven en vez de deslizarse */
@media (min-width: 768px) {
	.fv2-ficha-body .nav-tabs { flex-wrap: wrap; overflow-x: visible; }
}

/* --- Cabecera y cuerpo de tarjeta ----------------------------------------- */
.fv2-ficha-body .card-header {
	background: transparent;
	border-bottom: 1px solid var(--fv2-divider);
}

/* --- Botones "soft" (los usa entrenamientos por todas partes) ------------- */
.fv2-ficha-body .btn-soft.btn-primary {
	background: var(--fv2-accent-soft);
	border-color: transparent;
	color: var(--fv2-accent);
}

.fv2-ficha-body .btn-soft.btn-primary:hover {
	background: var(--fv2-accent);
	color: var(--fv2-on-accent);
}

/* --- Menús desplegables (acciones de fila) -------------------------------- */
.fv2-ficha-body .dropdown-menu {
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-sm);
	box-shadow: 0 8px 24px rgba(18, 28, 44, .12);
}

.fv2-ficha-body .dropdown-item {
	font: 500 13px/1.4 var(--fv2-font-body);
	border-radius: 8px;
}

.fv2-ficha-body .dropdown-item:hover { background: var(--fv2-accent-soft); color: var(--fv2-accent); }

/* --- Formularios --- */
.fv2-ficha-body .form-control,
.fv2-ficha-body .form-select {
	font-family: var(--fv2-font-body);
	border-radius: 10px;
	border-color: var(--fv2-border);
}

.fv2-ficha-body .form-control:focus,
.fv2-ficha-body .form-select:focus {
	border-color: var(--fv2-accent);
	box-shadow: 0 0 0 3px rgba(87, 79, 236, .12);
}

.fv2-ficha-body .form-label,
.fv2-ficha-body label { font-family: var(--fv2-font-body); }

/* --- Texto auxiliar --- */
.fv2-ficha-body .text-muted { color: var(--fv2-muted) !important; }

/* =============================================================================
 * PESTAÑA "FICHA" (#mi_cuenta) — página de ajustes
 * -----------------------------------------------------------------------------
 * Esta es la única pestaña con plantilla propia (modules/mi_cuenta.v2.tpl); las
 * otras cuatro sólo llevan piel. Ver el motivo en la cabecera de esa plantilla.
 *
 * El contenedor lleva class="section" porque comentarios_cliente() lo necesita
 * como ancestro para anclar el aviso de guardado. Aquí se le quita todo el
 * cromo que .fv2-ficha-body .section le habría puesto: las tarjetas son las
 * filas, no el contenedor.
 * ========================================================================== */
.fv2-ficha-body #mi_cuenta {
	background: transparent;
	border: 0;
	box-shadow: none;
	padding: 0;
}

/* --- Cabecera de grupo ---------------------------------------------------- */
.fv2-acc-top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin-bottom: 10px;
}

.fv2-acc-h {
	font: 700 13px/1.2 var(--fv2-font-body);
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--fv2-outline);
	margin: 0;
}

/* Grupos siguientes (Seguridad, Pagos): necesitan aire por arriba */
.fv2-acc-h--sep { margin: 26px 0 10px; }

/* El botón de tres puntos. .dropstart es de Bootstrap y se conserva para que
   el desplegable siga funcionando igual. */
.fv2-acc-dots {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border-radius: 50%;
	color: var(--fv2-muted);
	background: transparent;
	text-decoration: none;
	transition: background .15s ease;
}

.fv2-acc-dots:hover { background: var(--fv2-card-alt); color: var(--fv2-on-surface); }
.fv2-acc-dots .fv2-ms { font-size: 20px; }
.fv2-acc-dots::after { display: none; }   /* flechita del dropdown-toggle */

/* --- Filas de ajuste ------------------------------------------------------ */
.fv2-sets {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	box-shadow: var(--fv2-shadow-card);
	overflow: hidden;
}

.fv2-set {
	display: flex;
	align-items: center;
	gap: 13px;
	padding: 14px 16px;
	border-bottom: 1px solid var(--fv2-divider);
}

.fv2-set:last-child { border-bottom: 0; }

/* Pastilla del icono */
.fv2-set-ico {
	flex: none;
	width: 38px;
	height: 38px;
	border-radius: 11px;
	background: var(--fv2-accent-soft);
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

.fv2-set-ico .fv2-ms { font-size: 20px; color: var(--fv2-accent); }

.fv2-set-body {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.fv2-set-lbl {
	font: 600 13.5px/1.3 var(--fv2-font-body);
	color: var(--fv2-on-surface);
}

/* El dato (correo, distintivo): puede ser largo, así que se parte */
.fv2-set-val {
	font: 400 13px/1.4 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
	overflow-wrap: anywhere;
}

.fv2-set-hint {
	font: 400 11.5px/1.45 var(--fv2-font-body);
	color: var(--fv2-muted);
}

.fv2-set-act {
	flex: none;
	display: flex;
	align-items: center;
	gap: 6px;
}

/* Eliminar cuenta: el icono en rojo, sin gritar con toda la fila en rojo */
.fv2-set--danger .fv2-set-ico { background: var(--fv2-error-container); }
.fv2-set--danger .fv2-set-ico .fv2-ms { color: var(--fv2-error); }

/* Fila que apila (comentarios internos): la acción es el propio campo */
.fv2-set--stack { align-items: flex-start; }
.fv2-set--stack .fv2-set-ico { margin-top: 2px; }

/* --- Botón de fila -------------------------------------------------------- */
.fv2-chip {
	display: inline-flex;
	align-items: center;
	white-space: nowrap;
	padding: 8px 13px;
	border-radius: 10px;
	border: 1px solid var(--fv2-border);
	background: var(--fv2-card);
	color: var(--fv2-on-surface-var);
	font: 600 12.5px/1 var(--fv2-font-body);
	text-decoration: none;
	cursor: pointer;
	transition: border-color .15s ease;   /* ver el aviso de .fv2-tab */
}

.fv2-chip--go {
	background: var(--fv2-accent);
	border-color: var(--fv2-accent);
	color: var(--fv2-on-accent);
}

.fv2-chip--go:hover {
	background: var(--fv2-accent-strong);
	border-color: var(--fv2-accent-strong);
	color: var(--fv2-on-accent);
}

/*
 * ⚠️ Los !important son obligatorios, no dejadez:
 *
 *     .isDisabled { pointer-events: none !important; background: #ffc5c5 !important; }
 *          <- css\fisic-css\style.css:141
 *
 * Se conserva la clase TAL CUAL en las tres acciones desactivadas (cambiar
 * contraseña, eliminar cuenta, cambiar correo) para que el comportamiento sea
 * idéntico al de antes: no se puede pulsar. Lo único que cambia es el aspecto,
 * porque el rosa chicle del tema se leía como "error", no como "desactivado".
 */
.fv2-ficha-body #mi_cuenta .isDisabled {
	background: var(--fv2-card-alt) !important;
	border-color: var(--fv2-divider);
	/*
	 * --fv2-muted (#8b93a7) sobre --fv2-card-alt (#f4f6fe) da un contraste de
	 * ~3:1: insuficiente para texto de 12,5px, y en pantalla no se leia. Con
	 * --fv2-outline (#6f7979) sube a ~4,6:1 y sigue leyendose como desactivado.
	 */
	color: var(--fv2-outline);
	opacity: 1;                /* el .5 del tema lo dejaba ilegible */
	cursor: not-allowed;
}

/* --- Campo de comentarios ------------------------------------------------- */
.fv2-ta {
	width: 100%;
	margin-top: 8px;
	min-height: 92px;
	resize: vertical;
	padding: 11px 13px;
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-sm);
	background: var(--fv2-card);
	color: var(--fv2-on-surface);
	font: 400 13px/1.5 var(--fv2-font-body);
}

.fv2-ta:focus {
	outline: 0;
	border-color: var(--fv2-accent);
	box-shadow: 0 0 0 3px var(--fv2-accent-soft);
}

/*
 * Móvil estrecho: etiqueta + dato + dos botones no caben en una línea. La fila
 * pasa a rejilla de dos columnas y las acciones bajan bajo el texto, alineadas
 * con él (no debajo del icono, que dejaba un escalón raro).
 */
@media (max-width: 519px) {

	.fv2-set {
		display: grid;
		grid-template-columns: 38px minmax(0, 1fr);
		column-gap: 13px;
		row-gap: 9px;
		align-items: start;
	}

	.fv2-set-ico { grid-column: 1; grid-row: 1; }
	.fv2-set-body { grid-column: 2; grid-row: 1; }
	.fv2-set-act { grid-column: 2; grid-row: 2; flex-wrap: wrap; }
}

/* =============================================================================
 * PESTAÑA "BONOS Y PAGOS" (#mis_bonos) — pantalla 2c del mockup
 * -----------------------------------------------------------------------------
 * Todo es CSS: la plantilla NO se toca. Motivo, que no es estético:
 *
 *   do_filter() (mi_cuenta.tpl.js:~700) hace literalmente
 *       $('tbody#tbody_bonos tr[data-act]')
 *   para el filtro Todos / Activos / Anteriores. Convertir la tabla en tarjetas
 *   en el HTML rompería el filtro sin dar ningún error.
 *
 * Así que se conserva <table><tbody id="tbody_bonos"><tr data-act> y se cambia
 * cómo SE PINTA. Funciona con el filtro porque éste sólo pone/quita display
 * inline y la clase .hidden sobre los <tr>.
 *
 * Por debajo de 760px, responsive-table.css ya pasa la tabla a bloques y saca
 * las etiquetas con [data-content]:before. Aquí se construye sobre eso en vez
 * de duplicarlo.
 *
 * Todo acotado a .fv2-ficha-body #mis_bonos.
 * ========================================================================== */

.fv2-ficha-body #mis_bonos { padding: 0; border: 0; box-shadow: none; background: transparent; }

/* --- Sub-navegación: Pagos pendientes / Estado / Historial / Minibar ------ */
/*
 * El <ul> lleva .nav-invert, que el tema pinta como una píldora gris con
 * padding propio (core.css:15792). Con chips que ya tienen su borde, eso
 * dibujaba una cápsula alrededor de otra. Se neutraliza.
 */
.fv2-ficha-body #mis_bonos > .d-flex > .w-100 > ul.nav {
	gap: 8px;
	flex-wrap: wrap;
	border: 0;
	margin-bottom: 14px;
	background: transparent;
	padding: 0;
	display: flex;
}

.fv2-ficha-body #mis_bonos > .d-flex > .w-100 > ul.nav .nav-link {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-sm);
	padding: 10px 15px;
	font: 600 12.5px/1 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
	transition: border-color .15s ease;   /* ver el aviso de .fv2-tab */
}

/*
 * ⚠️ El !important del color es obligatorio, no es dejadez:
 *
 *     .nav-invert .nav-link.active { color: var(--bs-primary) !important; }
 *          <- css/fisic-css/core.css:15804
 *
 * Nuestra regla lleva un #id, así que gana el FONDO (acento, oscuro), pero el
 * !important del tema gana el COLOR y dejaba texto azul marino sobre fondo
 * azul marino: la pestaña activa era ilegible. Sin este !important vuelve.
 */
.fv2-ficha-body #mis_bonos > .d-flex > .w-100 > ul.nav .nav-link.active {
	background: var(--fv2-accent);
	border-color: var(--fv2-accent);
	color: var(--fv2-on-accent) !important;
}

.fv2-ficha-body #mis_bonos .tab-content { padding: 0 !important; }

/* --- Filtro Todos / Activos / Anteriores --------------------------------- */
.fv2-ficha-body #mis_bonos .filtro { margin: 0 0 14px !important; }

.fv2-ficha-body #mis_bonos .filtro .btn-group { gap: 8px; flex-wrap: wrap; }

.fv2-ficha-body #mis_bonos .filtro .btn {
	border-radius: 10px !important;
	border: 1px solid var(--fv2-border);
	background: var(--fv2-card);
	color: var(--fv2-on-surface-var);
	font: 600 12px/1 var(--fv2-font-body);
	padding: 9px 14px;
}

.fv2-ficha-body #mis_bonos .filtro .btn.active {
	background: var(--fv2-accent);
	border-color: var(--fv2-accent);
	color: var(--fv2-on-accent);
}

/* --- Encabezados de bloque ------------------------------------------------ */
.fv2-ficha-body #mis_bonos h5 {
	font: 600 12px/1.4 var(--fv2-font-body);
	letter-spacing: .08em;
	text-transform: uppercase;
}

.fv2-ficha-body #mis_bonos h5 .fw-bold { font-weight: 600; }
.fv2-ficha-body #mis_bonos hr { display: none; }

/* --- Bonos: tarjetas en móvil/tablet ------------------------------------- */
@media only screen and (max-width: 760px),
       (min-device-width: 768px) and (max-device-width: 1024px) {

	.fv2-ficha-body #mis_bonos table.table-mobile-responsive { border: 0; }

	/* Cada fila del bono es una tarjeta (mockup 2c) */
	.fv2-ficha-body #mis_bonos #tbody_bonos > tr {
		background: var(--fv2-card);
		border: 1px solid var(--fv2-border);
		border-radius: var(--fv2-radius-card);
		box-shadow: var(--fv2-shadow-card);
		padding: 14px 16px;
		margin-bottom: 12px;
	}

	.fv2-ficha-body #mis_bonos #tbody_bonos > tr > td {
		border: 0;
		/*
		 * ⚠️ El !important es obligatorio: responsive-table.css:63 pone
		 * "padding-top: 1.5rem !important" en la celda para hacerle sitio a la
		 * etiqueta. Sin anularlo, cada fila salia con 24px de aire arriba y la
		 * etiqueta flotando en el hueco.
		 */
		padding: 5px 0 !important;
		display: flex;
		align-items: baseline;
		justify-content: space-between;
		gap: 12px;
		text-align: right !important;
	}

	/*
	 * ⚠️ EL "position: static" ES EL ARREGLO, no una redundancia.
	 *
	 * La etiqueta la pinta responsive-table.css con [data-content]:before, pero
	 * POSICIONADA EN ABSOLUTO (linea 67: position:absolute; top:15px; left:0;
	 * width:45%), y la celda le hace sitio con padding-left:50%.
	 *
	 * Un elemento absoluto esta fuera del flujo, o sea que NO es un item flex:
	 * al quitarle el padding-left a la celda para montar la fila con flex, la
	 * etiqueta se quedaba encima del valor, recortada arriba a la izquierda.
	 *
	 * Volviendola estatica pasa a ser un item flex de verdad y la fila queda en
	 * dos columnas que se adaptan al texto, sin el 50% a ojo.
	 */
	.fv2-ficha-body #mis_bonos #tbody_bonos > tr > td:before {
		position: static;
		top: auto;
		left: auto;
		width: auto;
		font: 400 11.5px/1.3 var(--fv2-font-body);
		color: var(--fv2-outline);
		text-align: left;
		flex: 0 0 auto;
		white-space: normal;
	}

	/* El nombre del bono es el titular de la tarjeta */
	.fv2-ficha-body #mis_bonos #tbody_bonos > tr > td:nth-child(2) {
		font: 700 17px/1.2 var(--fv2-font-head);
		border-bottom: 1px solid var(--fv2-divider);
		padding-bottom: 10px;
		margin-bottom: 4px;
	}
	.fv2-ficha-body #mis_bonos #tbody_bonos > tr > td:nth-child(2):before { display: none; }

	/* Sin etiqueta para la celda de acciones */
	.fv2-ficha-body #mis_bonos #tbody_bonos > tr > td:last-child { justify-content: flex-end; }
}

/* --- Bonos: tabla limpia en escritorio ----------------------------------- */
@media (min-width: 1025px) {

	.fv2-ficha-body #mis_bonos table {
		background: var(--fv2-card);
		border: 1px solid var(--fv2-border);
		border-radius: var(--fv2-radius-card);
		border-collapse: separate;
		border-spacing: 0;
		overflow: hidden;
		box-shadow: var(--fv2-shadow-card);
	}

	.fv2-ficha-body #mis_bonos thead th { padding: 12px 14px; background: var(--fv2-card-alt); }
	.fv2-ficha-body #mis_bonos tbody td { padding: 13px 14px; }

	/* El nombre del bono, con peso de titular */
	.fv2-ficha-body #mis_bonos #tbody_bonos > tr > td:nth-child(2) {
		font-family: var(--fv2-font-head);
		font-weight: 700;
		font-size: 15px;
	}
}

/* --- Reservas y sesiones (modules/sesion.tpl → .cita) -------------------- */
.fv2-ficha-body .cita {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border) !important;
	border-radius: var(--fv2-radius-card);
	box-shadow: var(--fv2-shadow-card);
	margin-bottom: 12px !important;
	overflow: hidden;
}

.fv2-ficha-body .cita p { font-size: 13.5px; }
.fv2-ficha-body .cita p strong { font-family: var(--fv2-font-head); font-size: 15.5px; }

/*
 * Los botones (Cambiar / Cancelar / Asignar / Liberar) van pegados a la derecha
 * de su columna, junto al bloque de la fecha, en vez de sueltos en medio de la
 * fila. Es la columna del medio de las tres de sesion.tpl (texto · botones · día).
 */
.fv2-ficha-body .cita > div:nth-child(2) {
	justify-content: flex-end;
	gap: 6px;
	flex-wrap: wrap;
}

/* En móvil las tres columnas se apilan y "a la derecha" ya no significa nada */
@media (max-width: 767px) {
	.fv2-ficha-body .cita > div:nth-child(2) { justify-content: flex-start; }
}

/* El bloque de día/mes de la derecha, como en el mockup */
.fv2-ficha-body .cita > div:last-child {
	background: var(--fv2-card-alt);
	justify-content: center !important;
}

.fv2-ficha-body .cita > div:last-child > div:first-child {
	font-family: var(--fv2-font-head) !important;
	font-weight: 700;
	color: var(--fv2-accent);
	line-height: 1;
}

.fv2-ficha-body .cita > div:last-child > div:last-child {
	font: 600 11px/1.4 var(--fv2-font-body);
	letter-spacing: .1em;
	color: var(--fv2-outline);
}

.fv2-ficha-body #reservas > div { margin-bottom: 0; }

/* --- Historial de pagos --------------------------------------------------- */
.fv2-ficha-body .a-pedido,
.fv2-ficha-body .pedido { transition: border-color .15s ease; }
.fv2-ficha-body .a-pedido:hover { border-color: var(--fv2-accent); }
.fv2-ficha-body .pedido h5 { text-transform: none; letter-spacing: 0; font-size: 16px; color: var(--fv2-on-surface); }

/* =============================================================================
 * PESTAÑA "VALORACIONES" (#valoraciones)
 * -----------------------------------------------------------------------------
 * Solo CSS: la plantilla únicamente recibe el id (una línea) para poder acotar
 * esto sin colgarlo de .section, que es genérica y la usan varias pestañas.
 * ========================================================================== */
.fv2-ficha-body #valoraciones {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	box-shadow: var(--fv2-shadow-card);
	overflow: hidden;
}

.fv2-ficha-body #valoraciones .card-header {
	padding: 16px !important;
	border-bottom: 1px solid var(--fv2-divider);
	background: transparent;
}

/* --- Buscador ------------------------------------------------------------- */
/* El campo lleva .bg-gray-100 (core.css:11061, con !important) */
.fv2-ficha-body #valoraciones input[name="title"] {
	background: var(--fv2-card-alt) !important;
	border: 1px solid var(--fv2-border) !important;
	border-radius: var(--fv2-radius-sm);
	height: 42px;
	font: 400 13.5px/1 var(--fv2-font-body);
	color: var(--fv2-on-surface);
}

.fv2-ficha-body #valoraciones input[name="title"]:focus {
	border-color: var(--fv2-accent) !important;
	box-shadow: 0 0 0 3px var(--fv2-accent-soft) !important;
}

/* La lupa iba en .text-primary: aquí es decoración, no un elemento activo */
.fv2-ficha-body #valoraciones form > svg { color: var(--fv2-muted) !important; }

/* --- Tabla en escritorio -------------------------------------------------- */
/*
 * El título de cada valoración era un botón azul (.btn-soft.btn-primary). Es un
 * enlace a la ficha de la valoración, no una acción destacada: se pinta como
 * texto con peso, que además deja leer títulos largos sin romper la tabla.
 */
.fv2-ficha-body #valoraciones td .btn-soft {
	background: transparent !important;
	border: 0 !important;
	padding: 0 !important;
	text-align: left;
	white-space: normal;
	font: 600 14px/1.35 var(--fv2-font-body);
	color: var(--fv2-on-surface) !important;
}

.fv2-ficha-body #valoraciones td .btn-soft:hover { color: var(--fv2-accent) !important; }

.fv2-ficha-body #valoraciones tbody td {
	font: 400 13px/1.4 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
}

/* Botón de tres puntos de cada fila */
.fv2-ficha-body #valoraciones td.dropstart > a {
	color: var(--fv2-muted) !important;
	background: transparent !important;
	border: 0 !important;
}

.fv2-ficha-body #valoraciones td.dropstart > a:hover {
	background: var(--fv2-card-alt) !important;
	color: var(--fv2-on-surface) !important;
}

/* --- Filtros en uso ------------------------------------------------------- */
.fv2-ficha-body #valoraciones .list-inline-item.badge {
	border-radius: 8px !important;
	font-weight: 600;
}

/*
 * Móvil: la tabla pasa a tarjetas.
 *
 * OJO: aquí NO se puede usar el truco de #mis_bonos, que se apoya en
 * .table-mobile-responsive y en los atributos data-content de responsive-table.css
 * para pintar las etiquetas con :before. Esta tabla no los lleva.
 *
 * Se resuelve sin etiquetas: título grande en la primera línea con el menú a la
 * derecha, y "tipo · fecha" debajo. Como la primera línea ya ocupa todo el ancho
 * (el título crece), las dos celdas siguientes bajan solas a la segunda línea.
 * El separador es un punto medio, que no hay que traducir.
 */
@media (max-width: 700px) {

	.fv2-ficha-body #valoraciones .table-responsive-md { padding: 4px 0; }
	.fv2-ficha-body #valoraciones table { border: 0; }
	.fv2-ficha-body #valoraciones thead { display: none; }

	.fv2-ficha-body #valoraciones tbody,
	.fv2-ficha-body #valoraciones tbody tr,
	.fv2-ficha-body #valoraciones tbody td { display: block; }

	.fv2-ficha-body #valoraciones tbody tr {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		column-gap: 8px;
		row-gap: 2px;
		padding: 13px 16px;
		border-bottom: 1px solid var(--fv2-divider);
	}

	.fv2-ficha-body #valoraciones tbody tr:last-child { border-bottom: 0; }

	.fv2-ficha-body #valoraciones tbody td {
		border: 0 !important;
		padding: 0 !important;
		width: auto;
	}

	.fv2-ficha-body #valoraciones tbody td:nth-child(1) { flex: 1 1 auto; order: 1; min-width: 0; }
	.fv2-ficha-body #valoraciones tbody td:nth-child(4) { flex: 0 0 auto; order: 2; }
	.fv2-ficha-body #valoraciones tbody td:nth-child(2) { flex: 0 0 auto; order: 3; }
	.fv2-ficha-body #valoraciones tbody td:nth-child(3) { flex: 0 0 auto; order: 4; }

	.fv2-ficha-body #valoraciones tbody td:nth-child(2),
	.fv2-ficha-body #valoraciones tbody td:nth-child(3) {
		font: 400 12px/1.4 var(--fv2-font-body);
		color: var(--fv2-muted);
	}

	.fv2-ficha-body #valoraciones tbody td:nth-child(3):before {
		content: '·';
		margin-right: 6px;
		color: var(--fv2-chevron);
	}

	.fv2-ficha-body #valoraciones td .btn-soft { font-size: 15px; }
}

/* =============================================================================
 * PESTAÑA "ENTRENAMIENTOS" — programación (#e-actual)
 * -----------------------------------------------------------------------------
 * La pantalla la componen cuatro plantillas encadenadas:
 *
 *     entrenamientos.tpl            sub-pestañas + rótulos de sección
 *       planificacion.semanas.tpl   título, objetivo, semanas, Fase, cifras
 *         fases.tpl                 el código de colores de la fase
 *         planificacion.dia.tpl     día, bloques y ejercicios (dentro del swiper)
 *
 * ⚠️ CONTRATOS QUE NO SE PUEDEN ROMPER:
 *
 *   .semanas-pla li      common.tpl.js:23 alterna .active en el <li> y
 *                        .active/.d-none en #swiper-<pr_id>-<n>. No tocar el
 *                        display de .swiper-container ni el significado de .d-none.
 *
 *   .swiper-slide        Swiper fija ancho y transform EN LÍNEA y luego
 *                        swiperInst[id].update() los recalcula. No se toca su
 *                        layout: solo el contenido.
 *
 *   .btn-bloque-activo   plan_dia() (js_body.tpl:563) busca
 *                        "svg.svg-activo.active" para saber a qué día deslizar, y
 *                        el <style> de planificacion.semanas.tpl alterna esos svg
 *                        con display. Aquí solo se estiliza el botón.
 * ========================================================================== */

/* --- Rótulos de sección --------------------------------------------------- */
/*
 * entrenamientos.tpl pinta <h5>Calentamiento</h5> y justo debajo la plantilla de
 * la programación repite su título con <h4>, que en este centro también se llama
 * "Calentamiento". No es un fallo de la plantilla —el programa se llama así— pero
 * se leían como dos títulos iguales seguidos. Bajando el h5 a rótulo, la jerarquía
 * queda clara sin tocar el HTML.
 */
.fv2-ficha-body #e-actual > .section > .mb-3 > h5,
.fv2-ficha-body #e-actual > .section > h5 {
	font: 600 11px/1.4 var(--fv2-font-body);
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--fv2-outline);
	margin: 4px 0 10px;
}

/* --- Cabecera de la programación ------------------------------------------ */
.fv2-ficha-body .prog h4 {
	font: 700 20px/1.25 var(--fv2-font-head);
	color: var(--fv2-on-surface);
	margin-bottom: 10px;
}

/*
 * El objetivo es un <textarea readonly>: no se edita nunca, así que dejarlo con
 * pinta de campo de formulario invita a escribir en él. Se presenta como una nota.
 */
.fv2-ficha-body .prog textarea[name="objetivo"] {
	background: var(--fv2-card-alt) !important;
	border: 0 !important;
	border-left: 3px solid var(--fv2-accent-soft) !important;
	border-radius: 0 var(--fv2-radius-sm) var(--fv2-radius-sm) 0;
	color: var(--fv2-on-surface-var);
	font: 400 13.5px/1.5 var(--fv2-font-body);
	padding: 12px 14px;
	cursor: default;
	box-shadow: none !important;
}

/* La etiqueta flotante de ese campo sobra: el texto ya se explica solo */
.fv2-ficha-body .prog .form-floating > textarea[name="objetivo"] ~ label { display: none; }

/* --- Tarjetas de Fase y cifras -------------------------------------------- */
.fv2-ficha-body .bloque-prog {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	padding: 10px;
	/* En la tira no se encoge: si se encoge, el icono de la cabecera se sale */
	flex: 0 0 auto;
}

/*
 * ⚠️ El nowrap y el min-width no son cosmética.
 *
 * Estas tarjetas se pintan con el ancho de su contenido. Si el rótulo puede
 * partirse, la tarjeta se estrecha hasta que el icono de FontAwesome de la
 * cabecera (fa-bars-progress en Fase, fa-star-half-stroke en Valoraciones) se
 * sale por el borde izquierdo y aparece flotando fuera, como un icono suelto en
 * medio de la pantalla. Es lo que pasaba a 1000px y a 1920px.
 */
.fv2-ficha-body .bloque-prog .card-header {
	padding: 0 0 8px !important;
	background: transparent !important;
	font: 600 10.5px/1.3 var(--fv2-font-body) !important;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--fv2-outline) !important;
	white-space: nowrap;
	overflow: visible;
}

.fv2-ficha-body .bloque-prog .card-header i { color: var(--fv2-muted); }

/* El botón "Individual" salía partido en dos líneas ("Individu / al") */
.fv2-ficha-body .bloque-prog .btn {
	white-space: nowrap;
	gap: 6px;
}

/* =============================================================================
 * La fila de cabecera de la programación (.prog)
 * -----------------------------------------------------------------------------
 * Se conserva el MISMO reparto de siempre —Valoraciones · centro · Fase+cifras
 * en una línea— pero repartido por contenido en vez de por doceavos.
 *
 * ⚠️ LAS CLASES col-md-* DE LA PLANTILLA NO SE PUEDEN QUITAR: entrenamientos.tpl
 * es COMPARTIDA, y los clientes que siguen en el diseño clásico dependen de
 * ellas. Aquí no se eliminan, se recolocan.
 *
 * Por qué no valían los doceavos dentro de la ficha: col-md-3 son un 25% del
 * contenedor, y la ficha ya es estrecha de por sí. A 1000px eso son ~180px, y
 * las cajas de cifras se quedaban con ~50px útiles: "1 dias / semana" salía a
 * palabra por línea y hasta partido a mitad ("sem/ana"). Con reparto por
 * contenido, cada bloque pide lo que necesita y el del medio se queda el resto.
 *
 * Y NO hacen falta !important: Bootstrap declara .col-12 (core.css:646) y
 * .col-md-* (:927) SIN !important, así que basta con especificidad —
 * ".fv2-ficha-body .prog > .col-md-2" son 0,3,0 frente a 0,1,0. El único
 * !important es el de .justify-content-evenly, que sí es una utilidad (:6049).
 * ========================================================================== */
.fv2-ficha-body .prog {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: 14px 18px;
}

/* El hueco lo da el gap, no el padding de las columnas */
.fv2-ficha-body .prog > [class*="col-"] {
	width: auto;
	max-width: none;
	padding-left: 0;
	padding-right: 0;
}

/*
 * Valoraciones: ancho por contenido. El mínimo es lo que evita que se parta
 * "Valoraciones" o el botón "Individual" — que se partían también en el diseño
 * clásico, por cierto.
 */
.fv2-ficha-body .prog > .col-md-2 { flex: 0 0 auto; min-width: 150px; }

/*
 * El centro es el que crece. La base de 320px es el punto de corte: cuando no
 * quedan 320px libres, baja de línea entero en vez de estrujar a los vecinos.
 */
.fv2-ficha-body .prog > .col-md-7,
.fv2-ficha-body .prog > .col-md-9 { flex: 1 1 320px; min-width: 0; }

/* Fase + cifras: ancho por contenido, como Valoraciones */
.fv2-ficha-body .prog > .col-md-3 { flex: 0 0 auto; }

/*
 * Dentro de esa columna, Fase a la izquierda y las cifras apiladas a su derecha,
 * igual que siempre. El !important es porque .justify-content-evenly sí lo lleva.
 */
.fv2-ficha-body .prog .justify-content-evenly {
	justify-content: flex-start !important;
	align-items: flex-start;
	gap: 10px;
}

.fv2-ficha-body .prog .justify-content-evenly > div:last-child {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/*
 * El objetivo suele venir vacío en los calentamientos, y dejaba una caja alta y
 * vacía en medio de la pantalla. Un <textarea> sin contenido SÍ cumple :empty
 * (su valor son nodos de texto hijos), así que no hace falta :has() ni tocar la
 * plantilla.
 */
.fv2-ficha-body .prog textarea[name="objetivo"]:empty { display: none; }

/*
 * Las dos cifras (días/semana y fechas) venían con py-4 y sombra de tarjeta
 * flotante: dos bloques enormes y vacíos. Se compactan y se les quita la
 * animación de hover, que no llevan a ninguna parte porque no son pulsables.
 */
.fv2-ficha-body .prog .transition-hover-top {
	box-shadow: none !important;
	transform: none !important;
	transition: none !important;
	background: var(--fv2-card-alt);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-sm);
	padding: 9px 12px !important;
	margin-bottom: 0;         /* la separación la da el gap de la columna */
	text-align: left !important;
	display: flex;
	align-items: center;
	/* Que no se encoja hasta partir "1 dias / semana" o la fecha por la mitad */
	flex: 0 0 auto;
	min-width: max-content;
}

.fv2-ficha-body .prog .transition-hover-top span {
	font: 600 12.5px/1.35 var(--fv2-font-body) !important;
	color: var(--fv2-on-surface-var) !important;
	white-space: nowrap;
}

/* --- Fase: el código de colores ------------------------------------------- */
/*
 * ⚠️ Los colores (rojo/naranja/amarillo/verde, style.css:169-179) son un CÓDIGO
 * que el centro lee: NO se tocan. Lo que se arregla es la forma.
 *
 * #div-fases .form-check llevaba padding: 6px 20px (style.css:181), o sea 40px
 * horizontales. Dentro de la columna estrecha de la ficha no cabía ni "PCB", que
 * salía partido en tres líneas: P / C / B.
 */
.fv2-ficha-body #div-fases { max-width: none; }

.fv2-ficha-body #div-fases .form-check {
	padding: 5px 12px !important;
	margin: 0 !important;
	border-radius: 8px;
	white-space: nowrap;      /* esto es lo que evita el "P C B" en vertical */
	min-height: 0;
}

.fv2-ficha-body #div-fases .form-check-label {
	font: 700 12px/1.2 var(--fv2-font-body);
	letter-spacing: .04em;
	cursor: default;
}

/* --- Selector de semana --------------------------------------------------- */
.fv2-ficha-body .semanas-pla {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	text-align: left !important;
	margin: 12px 0 0 !important;
	padding: 0;
}

/*
 * ⚠️ El !important del color es obligatorio: la plantilla pone .text-white en el
 * <a> y en el <span> de dentro (planificacion.semanas.tpl:53-54) y Bootstrap lo
 * declara con !important. Sin anularlo, un chip inactivo con fondo claro saldría
 * con el texto blanco, es decir invisible.
 */
.fv2-ficha-body .semanas-pla li {
	margin: 0 !important;
	border-radius: 10px !important;
	padding: 8px 13px !important;
	background: var(--fv2-card) !important;
	border: 1px solid var(--fv2-border);
	font: 600 12px/1 var(--fv2-font-body);
	cursor: pointer;
	transition: border-color .15s ease;   /* ver el aviso de .fv2-tab */
}

.fv2-ficha-body .semanas-pla li,
.fv2-ficha-body .semanas-pla li .text-white { color: var(--fv2-on-surface-var) !important; }

.fv2-ficha-body .semanas-pla li:hover { border-color: var(--fv2-accent); }

.fv2-ficha-body .semanas-pla li.active {
	background: var(--fv2-accent) !important;
	border-color: var(--fv2-accent);
}

.fv2-ficha-body .semanas-pla li.active,
.fv2-ficha-body .semanas-pla li.active .text-white { color: var(--fv2-on-accent) !important; }

.fv2-ficha-body .semanas-pla .del-semana { opacity: .8; }

/* --- Cabecera del día ----------------------------------------------------- */
/* .text-center viene en la plantilla (con !important de Bootstrap) */
.fv2-ficha-body .dias .swiper-slide > .text-center { text-align: left !important; }

.fv2-ficha-body .dias .card-header {
	padding: 0 0 10px !important;
	background: transparent !important;
	border: 0 !important;
	font: 700 16px/1.2 var(--fv2-font-head) !important;
	color: var(--fv2-on-surface) !important;
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}

/* El botón de "día por defecto" es una casilla, no un botón: que lo parezca */
.fv2-ficha-body .btn-bloque-activo {
	color: var(--fv2-chevron);
	line-height: 1;
}

.fv2-ficha-body .btn-bloque-activo svg.svg-activo { color: var(--fv2-accent); }

.fv2-ficha-body .div_pda_fecha {
	font: 400 11.5px/1 var(--fv2-font-body) !important;
	color: var(--fv2-muted);
	margin-left: auto;
}

/* --- Bloques del día ------------------------------------------------------ */
/* Cabecera opcional del bloque (prb_cabecera) */
.fv2-ficha-body .dias .title {
	font: 600 10.5px/1.4 var(--fv2-font-body);
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--fv2-outline);
	text-align: left;
	margin: 14px 0 6px;
}

.fv2-ficha-body .dias .title:empty { display: none; }

/*
 * El bloque es un desplegable del tema (nav-deep-hover). Se le da forma de fila
 * de tarjeta; el chevron ya lo pinta la plantilla con .group-icon.float-end.
 */
.fv2-ficha-body .dias nav.nav-deep > ul > li > .nav-link,
.fv2-ficha-body .dias .nav.flex-column > .nav-item > .nav-link {
	background: var(--fv2-card-alt) !important;
	border: 1px solid var(--fv2-border) !important;
	border-radius: var(--fv2-radius-sm) !important;
	padding: 12px 14px !important;
	font: 600 14px/1.3 var(--fv2-font-body) !important;
	color: var(--fv2-on-surface) !important;
	text-align: left;
	margin-bottom: 6px;
	transition: border-color .15s ease;
}

.fv2-ficha-body .dias .nav.flex-column > .nav-item > .nav-link:hover {
	border-color: var(--fv2-accent) !important;
}

.fv2-ficha-body .dias .nav.flex-column > .nav-item > .nav-link .group-icon {
	color: var(--fv2-chevron);
}

/* --- Ejercicios ----------------------------------------------------------- */
.fv2-ficha-body .dias p.sub {
	font: 600 13.5px/1.4 var(--fv2-font-body);
	color: var(--fv2-on-surface);
	text-align: left;
	margin: 10px 0 4px;
}

.fv2-ficha-body .desc-ejercicio {
	text-align: left;
	font: 400 13px/1.5 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
}

.fv2-ficha-body .desc-ejercicio video {
	border-radius: var(--fv2-radius-sm);
	max-width: 100%;
	background: var(--fv2-card-alt);
}

.fv2-ficha-body .desc-ejercicio p.nom { margin: 6px 0 0; }

/*
 * ⚠️ FALLO REAL, no cosmético: las variables del ejercicio son
 *      <li class="list-inline-item bg-primary me-1">
 * sin ninguna clase de color de texto (planificacion.dia.tpl:88). .bg-primary
 * pinta el fondo con --bs-primary (#1c0950, core.css:41) y el texto se hereda del
 * entorno, que es oscuro: quedaba #121c2c sobre #1c0950, o sea ilegible.
 *
 * Se presentan como pastillas de acento suave, que además pesan menos en la
 * lectura que un bloque oscuro por cada variable.
 */
.fv2-ficha-body .variables ul {
	display: flex;
	flex-wrap: wrap;
	gap: 5px;
	text-align: left !important;
	margin: 6px 0 12px !important;
	padding: 0;
}

.fv2-ficha-body .variables li {
	margin: 0 !important;
	padding: 5px 10px;
	border-radius: 8px;
	background: var(--fv2-accent-soft) !important;
	color: var(--fv2-accent) !important;
	font: 600 11.5px/1.3 var(--fv2-font-body);
	white-space: nowrap;
}

/* --- Swiper --------------------------------------------------------------- */
/* Solo cromo: ni ancho ni transform, que los gestiona Swiper en línea */
.fv2-ficha-body .dias .swiper-pagination-progressbar {
	background: var(--fv2-divider) !important;
	border-radius: 2px;
}

.fv2-ficha-body .dias .swiper-pagination-progressbar-fill {
	background: var(--fv2-accent) !important;
	border-radius: 2px;
}

.fv2-ficha-body .dias .swiper-button-next,
.fv2-ficha-body .dias .swiper-button-prev {
	color: var(--fv2-accent);
	--swiper-navigation-size: 22px;
}

/* --- Càrregues / Objectius: las tablas de valores ------------------------- */
.fv2-ficha-body .table.tablas { font-size: 13px; }
.fv2-ficha-body .table.tablas th { white-space: nowrap; }

/* --- Documentos (#documentos) --------------------------------------------- */
/*
 * ⚠️ Los botones de la barra salían con el texto partido A MITAD DE PALABRA:
 * "Añadi / r tipo" y "Su / bir".
 *
 * Causa: son items de un contenedor flex (.d-flex ... gap-3) y por defecto un
 * item flex SE ENCOGE por debajo de su contenido. Y Bootstrap 5 quitó el
 * "white-space: nowrap" que .btn sí tenía en Bootstrap 4, así que al encogerse
 * el texto se parte. Con la palabra más ancha que el hueco, parte por dentro.
 *
 * Se arregla en el sitio correcto: que no se encojan y que no partan.
 */
.fv2-ficha-body #documentos .btn {
	white-space: nowrap;
	flex: 0 0 auto;
}

/* El grupo de selectores es lo único que debe repartirse el espacio sobrante */
.fv2-ficha-body #documentos .input-group {
	flex: 1 1 340px;
	min-width: 0;
	flex-wrap: nowrap;
}

/*
 * Los desplegables salían recortados ("— Sin valoració", "informe-fisiote").
 * .input-group > .form-select viene con "width: 1%" de Bootstrap (core.css:2125)
 * para repartirse a partes iguales; con un mínimo se lee el contenido.
 */
.fv2-ficha-body #documentos .input-group .form-select {
	min-width: 170px;
	font-size: 13px;
}

/* La barra envuelve en vez de estrujar cuando no caben todos */
.fv2-ficha-body #documentos .portlet-body > .d-flex {
	flex-wrap: wrap;
	align-items: center;
}

/*
 * El árbol de carpetas recortaba los nombres largos ("Densitometría"). Los
 * enlaces son d-block w-100 dentro de un portlet con scroll horizontal: en vez
 * de obligar a desplazar para leer el nombre de una carpeta, que envuelva.
 */
.fv2-ficha-body #documentos #ul_tipos_documentos a {
	white-space: normal;
	overflow-wrap: anywhere;
	line-height: 1.35;
}

.fv2-ficha-body #documentos details summary { cursor: pointer; }

.fv2-ficha-body #documentos .portlet {
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	background: var(--fv2-card);
}

/* --- Historial de programaciones (#historial-entrenamientos) -------------- */
/*
 * Pestaña solo para el personal. La plantilla usa .list-group de Bootstrap para
 * que en los clientes que siguen en v1 se vea decente sin nada de esto.
 */
.fv2-ficha-body #historial-entrenamientos > h5 {
	font: 600 11px/1.4 var(--fv2-font-body) !important;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--fv2-outline) !important;
	margin: 0 0 10px;
	display: flex;
	align-items: center;
	gap: 8px;
}

.fv2-ficha-body .hist-list {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	box-shadow: var(--fv2-shadow-card);
	overflow: hidden;
}

.fv2-ficha-body .hist-item {
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 13px 16px !important;
	border: 0 !important;
	border-bottom: 1px solid var(--fv2-divider) !important;
	background: transparent !important;
	border-radius: 0 !important;
}

.fv2-ficha-body .hist-item:last-child { border-bottom: 0 !important; }

.fv2-ficha-body .hist-main { flex: 1; min-width: 0; }

.fv2-ficha-body .hist-titulo {
	font: 600 14px/1.3 var(--fv2-font-body);
	color: var(--fv2-on-surface);
	overflow-wrap: anywhere;
}

.fv2-ficha-body .hist-badges {
	display: flex;
	flex-wrap: wrap;
	gap: 5px;
	margin: 6px 0 5px;
}

.fv2-ficha-body .hist-badges .badge {
	font: 600 10.5px/1.3 var(--fv2-font-body);
	border-radius: 7px;
	padding: 4px 8px;
}

.fv2-ficha-body .hist-meta {
	font: 400 11.5px/1.5 var(--fv2-font-body);
	color: var(--fv2-muted);
}

.fv2-ficha-body .hist-acciones {
	flex: none;
	display: flex;
	flex-direction: column;
	gap: 5px;
}

.fv2-ficha-body .hist-acciones .btn {
	padding: 6px 12px;
	font-size: 12px;
	white-space: nowrap;
}

/* Móvil: las acciones bajan y se ponen en fila */
@media (max-width: 519px) {
	.fv2-ficha-body .hist-item { flex-wrap: wrap; }
	.fv2-ficha-body .hist-acciones { flex-direction: row; width: 100%; }
}

/* =============================================================================
 * PESTAÑA "MENSAJERÍA" (#portlet-chat)
 * -----------------------------------------------------------------------------
 * ⚠️ modules/chat.base.tpl lo COMPARTE la pantalla suelta smarty/templates/chats.tpl
 * (la lista de chats del backoffice). Por eso todo esto cuelga de .fv2-ficha-body:
 * fuera de la ficha el chat sigue exactamente como estaba.
 *
 * Las burbujas las pinta modules/chat.mensajes.tpl con clases de utilidad
 * (.bg-primary / .bg-light / .rounded-xl), todas con !important desde core.css,
 * de ahí los !important de aquí.
 * ========================================================================== */
.fv2-ficha-body #portlet-chat {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	box-shadow: var(--fv2-shadow-card);
	overflow: hidden;
}

/* --- Barra superior ------------------------------------------------------- */
.fv2-ficha-body #nav-chat {
	padding: 12px 14px !important;
	border-bottom: 1px solid var(--fv2-divider) !important;
	border-radius: 0 !important;
	background: var(--fv2-card) !important;
	min-height: 0;
}

/*
 * El botón de recargar lleva style="min-width: 280px" EN LÍNEA, pensado para el
 * ancho del chat a pantalla completa. En un móvil de 360px se come la fila
 * entera y empuja el nombre fuera. Al ser estilo en línea hace falta !important.
 */
.fv2-ficha-body #nav-chat #reload {
	min-width: 0 !important;
	gap: 7px;
	border-radius: 10px;
	background: var(--fv2-accent-soft) !important;
	border-color: var(--fv2-accent-soft) !important;
	color: var(--fv2-accent) !important;
	font: 600 12px/1 var(--fv2-font-body);
	padding: 9px 12px !important;
}

.fv2-ficha-body #nav-chat #last_update { font-weight: 500; }

.fv2-ficha-body #nav-chat #n-chat {
	font: 700 15px/1.2 var(--fv2-font-head);
	color: var(--fv2-on-surface);
	padding-top: 0 !important;   /* load_chat() se lo pone con .css() */
}

.fv2-ficha-body #nav-chat #n-chat-auto {
	font: 400 11.5px/1.3 var(--fv2-font-body);
	color: var(--fv2-muted);
}

/* --- Zona de mensajes ----------------------------------------------------- */
/*
 * ⚠️ #chat trae style="height: calc(-382px + 100vh)" EN LÍNEA: un número mágico
 * calculado para el chat a pantalla completa (cabecera + pie + barra). Dentro de
 * la ficha, con las pestañas encima y el perfil al lado, sobra alto y en móvil
 * se queda corto. clamp() lo resuelve en una línea y sin depender del layout.
 */
.fv2-ficha-body #chat {
	height: clamp(300px, 56vh, 620px) !important;
	padding: 0 !important;
	background: var(--fv2-surface);
}

.fv2-ficha-body #sow-chat-history {
	padding: 14px 14px 8px !important;
	font-family: var(--fv2-font-body);
}

/* Separador de día: es el único hijo directo con esas clases */
.fv2-ficha-body #sow-chat-history > .d-flex.align-items-center.flex-column {
	font: 600 10.5px/1 var(--fv2-font-body);
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--fv2-outline);
	margin: 14px 0 10px;
}

/* Nombre de quien escribe (solo en los mensajes del otro) */
.fv2-ficha-body #sow-chat-history span.fw-medium {
	font: 600 11px/1 var(--fv2-font-body) !important;
	color: var(--fv2-muted);
	padding-left: 4px !important;
}

/* --- Burbujas ------------------------------------------------------------- */
.fv2-ficha-body #sow-chat-history p.rounded-xl {
	max-width: 80%;
	border-radius: 16px !important;
	padding: 10px 14px !important;
	font: 400 13.5px/1.45 var(--fv2-font-body);
	box-shadow: 0 1px 3px rgba(18, 28, 44, .06);
}

/* Del otro: gris. Mía: acento. Las dos con la esquina de "cola" marcada */
.fv2-ficha-body #sow-chat-history p.bg-light {
	background: var(--fv2-card) !important;
	color: var(--fv2-on-surface) !important;
	border: 1px solid var(--fv2-border);
	border-bottom-left-radius: 5px !important;
}

.fv2-ficha-body #sow-chat-history p.bg-primary {
	background: var(--fv2-accent) !important;
	color: var(--fv2-on-accent) !important;
	border-bottom-right-radius: 5px !important;
}

/* Hora debajo de la burbuja */
.fv2-ficha-body #sow-chat-history label {
	font: 400 10.5px/1 var(--fv2-font-body);
	color: var(--fv2-muted);
	margin-bottom: 6px !important;
}

/* --- Cargar más ----------------------------------------------------------- */
.fv2-ficha-body #load_more .btn {
	border-radius: 999px;
	border-color: var(--fv2-border);
	color: var(--fv2-on-surface-var);
	font: 600 12px/1 var(--fv2-font-body);
	padding: 8px 16px;
}

.fv2-ficha-body #load_more .btn:hover {
	border-color: var(--fv2-accent);
	color: var(--fv2-accent);
	background: transparent;
}

/* --- Barra de escritura --------------------------------------------------- */
/* .portlet-footer ya es flex (core.css:19975) */
.fv2-ficha-body #portlet-chat .portlet-footer {
	padding: 10px 12px !important;
	gap: 8px;
	align-items: flex-end;
	border-top: 1px solid var(--fv2-divider);
	background: var(--fv2-card);
}

/* Lleva .border-primary, que fija border-color con !important */
.fv2-ficha-body #chat-input {
	min-height: 44px;
	max-height: 140px;
	border: 1px solid var(--fv2-border) !important;
	border-radius: var(--fv2-radius-sm);
	padding: 11px 13px;
	font: 400 13.5px/1.4 var(--fv2-font-body);
	background: var(--fv2-card-alt);
	resize: none;
	margin-right: 0 !important;   /* el .me-1 de la plantilla */
}

.fv2-ficha-body #chat-input:focus {
	background: var(--fv2-card);
	border-color: var(--fv2-accent) !important;
	box-shadow: 0 0 0 3px var(--fv2-accent-soft);
}

/* Enviar: es un <label>, no un <button> */
.fv2-ficha-body #send {
	flex: none;
	width: 44px;
	height: 44px;
	padding: 0;
	border-radius: 12px;
	justify-content: center;
	background: var(--fv2-accent) !important;
	border-color: var(--fv2-accent) !important;
	color: var(--fv2-on-accent) !important;
	cursor: pointer;
}

.fv2-ficha-body #send:hover {
	background: var(--fv2-accent-strong) !important;
	border-color: var(--fv2-accent-strong) !important;
}

/* --- Estados sin chat y avisos ------------------------------------------- */
/*
 * "Chat finalizado, solo visible por empleados": venia como un boton rojo con
 * pulso. Es un aviso, no algo que se pulse.
 */
.fv2-ficha-body .animate-pulse-danger {
	animation: none !important;
	background: var(--fv2-error-container) !important;
	border-color: var(--fv2-error-container) !important;
	color: var(--fv2-on-error-cont) !important;
	border-radius: 10px !important;
	font: 600 12px/1.3 var(--fv2-font-body) !important;
	padding: 9px 13px !important;
}

/*
 * Estado vacío: "no cuenta con ninguna sesión de chat activa". La plantilla lo
 * pinta como <h3> dentro de un div sin clase propia, hijo directo del destino
 * del AJAX, así que se localiza por ahí.
 */
.fv2-ficha-body #contenido_mi_cuenta > .col.m-3 {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	box-shadow: var(--fv2-shadow-card);
	padding: 22px;
	margin: 0 !important;
}

.fv2-ficha-body #contenido_mi_cuenta > .col.m-3 h3 {
	font: 600 15px/1.5 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
	margin: 0;
}

/*
 * La ficha no lleva tope propio en ningún ancho: manda el .container de la app,
 * que ya responde a ancho_pantalla. Las reglas van igualmente porque más abajo
 * "body.layout-ancho .fv2" le pondría 1400px, y con la doble clase esto gana.
 */
@media (min-width: 1200px) {
	body.layout-ancho .fv2.fv2-ficha,
	body.layout-full  .fv2.fv2-ficha { max-width: none; }
}

/* =============================================================================
 * PANEL DE DOS COLUMNAS (escritorio) — portada del cliente
 * -----------------------------------------------------------------------------
 * El mockup era de móvil: una columna vertical. Estirarla a 1400px no la
 * convierte en un diseño de escritorio, sólo deja cada fila más vacía (el hero
 * quedaba en 6:1 con un título diminuto, y tres cifras ocupando 460px cada una).
 *
 * A partir de 1200px se compone como un panel:
 *      columna principal (izq.)  lo accionable: reservar, tarjetas, accesos
 *      columna lateral  (der.)   lo informativo: próxima sesión, cifras, avisos
 *
 * En móvil .fv2-dash y .fv2-col son display:contents, o sea que desaparecen del
 * layout: el orden y el aspecto son exactamente los de antes. Toda la
 * composición vive aquí, la plantilla sólo aporta tres contenedores.
 * ========================================================================== */
/* Contenedores que sólo existen para componer en escritorio: en móvil
   desaparecen del layout y todo queda en el orden y aspecto de siempre. */
.fv2-dash,
.fv2-col,
.fv2-ficha-side {
	display: contents;
}

@media (min-width: 1200px) {

	.fv2-dash {
		display: grid;
		/* La principal manda: ~2/3 frente a 1/3. minmax(0,..) evita que una
		   tarjeta ancha desborde la columna (mínimo auto de las grid tracks). */
		grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr);
		column-gap: 28px;
		align-items: start;
	}

	.fv2-col { display: block; }

	/* Filas explícitas: sólo hay estos tres hijos en la rejilla, así que la
	   colocación es determinista y no depende del auto-placement. */
	.fv2-col--main  { grid-column: 1; grid-row: 1 / span 2; }
	.fv2-col--side1 { grid-column: 2; grid-row: 1; }
	.fv2-col--side2 { grid-column: 2; grid-row: 2; }

	/* Dentro de una columna de ~900px el hero recupera proporción y el título
	   deja de parecer una nota al pie */
	.fv2-dash .fv2-hero { height: 260px; }
	.fv2-dash .fv2-hero-title { font-size: 32px; }
	.fv2-dash .fv2-hero-sub { font-size: 14px; margin-top: 5px; }
	.fv2-dash .fv2-feat { height: 190px; }
	.fv2-dash .fv2-feat-title { font-size: 21px; }

	/*
	 * Las cifras: en la columna estrecha se apilan, y cada una pasa de caja
	 * centrada a fila compacta (número + etiqueta al lado). Tres cajas
	 * centradas en 1/3 de ancho dejaban los números perdidos en medio del gris.
	 * OJO: .fv2-stats es FLEX, no grid.
	 */
	.fv2-dash .fv2-stats {
		flex-direction: column;
		gap: 8px;
	}

	.fv2-dash .fv2-stat {
		flex-direction: row;
		align-items: baseline;
		justify-content: flex-start;
		gap: 10px;
		padding: 14px;
	}

	.fv2-dash .fv2-stat-lbl { text-align: left; }

	/* La primera sección de cada columna no necesita línea superior: ya las
	   separa la propia composición */
	.fv2-col > .fv2-section:first-child { border-top: 0; margin-top: 0; padding-top: 6px; padding-left: 0px }
}

/*
 * Ancho de pantalla configurable (ini: ancho_pantalla) — ver style.css.
 * Las pantallas v2 acompañan al resto de la app cuando el cliente pide layout
 * ancho o completo.
 *
 * Clave: la rejilla pasa de un número FIJO de columnas a auto-fill, para que el
 * ancho extra se traduzca en MÁS columnas y no en pastillas gigantes separadas
 * por kilómetros. Con minmax(132px, 1fr) el tamaño del tile se mantiene y el
 * número de columnas lo decide el navegador según el ancho real.
 *
 * Gana por especificidad (body.x .fv2 = 0,2,0 frente a .fv2 = 0,1,0), así que
 * anula los max-width de los bloques de arriba sin depender del orden.
 */
@media (min-width: 1200px) {

	body.layout-ancho .fv2 { max-width: 1400px; }
	body.layout-full  .fv2 { max-width: 100%; }

	/*
	 * Excepción: la portada de un SOCIO (no del personal).
	 *
	 * El backoffice tiene una veintena de accesos y agradece los 1400px, pero la
	 * portada de un socio son cuatro cosas —próxima sesión, cifras, un par de
	 * accesos— y estirada a lo ancho quedan desperdigadas por la pantalla. Se le
	 * pone un ancho cómodo; el "margin: 0 auto" de .fv2 ya la centra.
	 *
	 * La clase la pone menu.v2.tpl con la MISMA condición que decide las dos
	 * columnas ($fv2_dash), así que no pueden desincronizarse.
	 *
	 * Doble clase por lo de siempre: contra "body.layout-ancho .fv2" (0,2,0) haría
	 * falta empatar y ganar por orden; con .fv2.fv2-portada-socio gana seguro.
	 */
	body.layout-ancho .fv2.fv2-portada-socio,
	body.layout-full  .fv2.fv2-portada-socio { max-width: 1100px; }

	/* minmax acompaña al tamaño de pastilla y etiqueta: con 116px las etiquetas
	   de dos palabras se partían en tres líneas */
	body.layout-ancho .fv2-tiles,
	body.layout-full  .fv2-tiles {
		grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
	}

	/* Al ensancharse, hero y tarjetas quedaban demasiado apaisadas */
	body.layout-ancho .fv2-hero,
	body.layout-full  .fv2-hero { height: 240px; }

	body.layout-ancho .fv2-feat,
	body.layout-full  .fv2-feat { height: 180px; }

	/*
	 * La lista de avisos es texto: a 2000px de ancho una fila de 20px de alto
	 * con el chevron en la otra punta de la pantalla es ilegible. Se le pone
	 * tope aunque el resto vaya a ancho completo.
	 */
	body.layout-full .fv2-list { max-width: 1100px; }
}

/*
 * La barrita de avance de desarrollo (verde/naranja bajo la etiqueta) llamaba
 * demasiado la atención: en la rejilla parecía un subrayado aleatorio.
 */
.fv2-tile-progress { width: 22px; opacity: .75; }

/* Un tile deshabilitado al 45% se leía como "roto" más que como "desactivado" */
.fv2-tile.is-disabled { opacity: .55; }

/* -------------------------------------------------- 11. Accesibilidad ---- */
@media (prefers-reduced-motion: reduce) {
	.fv2 *,
	.fv2 *::before,
	.fv2 *::after {
		transition: none !important;
		animation: none !important;
	}
}

.fv2 a:focus-visible {
	outline: 2px solid var(--fv2-accent);
	outline-offset: 2px;
	border-radius: 8px;
}

/* -------------------------------------------------- 9. Portada datos reales --
 * Aviso de pago, próxima sesión y stats (Home v2, mockup 2a). Todo bajo .fv2.
 * -------------------------------------------------------------------------- */

/* Aviso de pago pendiente */
.fv2-alert {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-bottom: var(--fv2-gutter);
	padding: 14px;
	background: var(--fv2-error-container);
	color: var(--fv2-on-error-cont);
	border-radius: var(--fv2-radius-card);
	text-decoration: none;
}
.fv2-alert-icon { font-size: 26px; flex: 0 0 auto; }
.fv2-alert-body { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.fv2-alert-title { font-family: var(--fv2-font-head); font-weight: 600; font-size: 15px; }
.fv2-alert-sub { font-size: 12.5px; opacity: .8; }
.fv2-alert-go { font-size: 22px; opacity: .7; flex: 0 0 auto; }

/* Próxima sesión */
.fv2-next {
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 14px;
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	box-shadow: var(--fv2-shadow-card);
	text-decoration: none;
	color: inherit;
}
/*
 * Ancho por CONTENIDO con un mínimo, no fijo. Con los 64px de antes y 4px de
 * relleno lateral quedaban 56px útiles, y el día de la semana más largo
 * ("MIÉRCOLES", "DIMECRES") ocupa ~62: el texto llegaba pegado a los bordes.
 */
.fv2-next-date {
	flex: 0 0 auto;
	min-width: 68px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: 10px 12px;
	background: var(--fv2-accent-soft);
	color: var(--fv2-accent-strong);
	border-radius: var(--fv2-radius-sm);
	line-height: 1.15;
}
.fv2-next-badge { font-family: var(--fv2-font-head); font-weight: 700; font-size: 15px; text-transform: uppercase; }
.fv2-next-dow { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
.fv2-next-daynum { font-family: var(--fv2-font-head); font-weight: 700; font-size: 26px; }
.fv2-next-month { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
.fv2-next-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.fv2-next-time { display: flex; align-items: center; gap: 6px; font-family: var(--fv2-font-head); font-weight: 600; font-size: 17px; }
.fv2-next-time .fv2-ms { font-size: 18px; color: var(--fv2-accent); }
.fv2-next-serv { font-size: 14px; color: var(--fv2-on-surface-var); }
.fv2-next-pro { display: flex; align-items: center; gap: 5px; font-size: 13px; color: var(--fv2-muted); }
.fv2-next-pro .fv2-ms { font-size: 16px; }
.fv2-next-go { flex: 0 0 auto; color: var(--fv2-chevron); font-size: 24px; }

/* Próxima sesión — estado vacío (socio sin reservas) */
.fv2-next--empty { justify-content: flex-start; gap: 10px; color: var(--fv2-muted); box-shadow: none; }
.fv2-next-emptyicon { font-size: 24px; }
.fv2-next-emptytxt { font-size: 14px; }

/* Stats rápidas */
.fv2-stats { display: flex; gap: 10px; margin-top: var(--fv2-gutter); }
.fv2-stat {
	flex: 1 1 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	padding: 12px 6px;
	background: var(--fv2-accent-soft);
	border-radius: var(--fv2-radius-sm);
	text-align: center;
}
.fv2-stat-num { font-family: var(--fv2-font-head); font-weight: 700; font-size: 22px; color: var(--fv2-accent-strong); }
.fv2-stat-lbl { font-size: 11px; color: var(--fv2-muted); text-transform: uppercase; letter-spacing: .03em; }

/* =============================================================================
 * CALENDARIOS (body.fv2-cal .fv2-fc) — SÓLO TIPOGRAFÍA Y COLOR
 * -----------------------------------------------------------------------------
 * calendario.tpl es únicamente <div id="calendar"></div>: la interfaz entera la
 * dibuja FullCalendar 6 por JS (843 líneas en modules/js/calendario.tpl.js).
 * Aquí no hay maquetación que rediseñar, y además es la herramienta con la que
 * recepción trabaja todo el día: romperla sale caro.
 *
 * ⚠️ REGLA DE ESTE BLOQUE: nada que afecte al COMPORTAMIENTO. Ni display, ni
 * position, ni width/height, ni overflow, ni z-index. Sólo color y tipografía.
 *
 * El retinte se hace con las VARIABLES QUE FULLCALENDAR EXPONE (--fc-*), que es
 * su vía de tematización soportada. Sobreescribir sus clases una a una sería
 * pelearse con la librería y romperse en la próxima actualización.
 *
 * Va sobre body.fv2-cal y NO sobre .fv2-page a propósito: así no le caen encima
 * las reglas de maquetación de #middle. Ver el comentario en layout/base.tpl.
 *
 * ⚠️ EL GANCHO ES LA CLASE .fv2-fc, NO EL id #calendar. Hay más de un
 * FullCalendar en la app (#calendar en calendario.tpl y #calendar-horariofijo en
 * horariofijo.tpl) y los dos tienen que retiñirse igual. Quien añada una tercera
 * vista de calendario sólo tiene que ponerle class="fv2-fc" al contenedor.
 * ========================================================================== */
body.fv2-cal .fv2-fc {
	/* Superficies y líneas */
	--fc-page-bg-color:            var(--fv2-card);
	--fc-neutral-bg-color:         var(--fv2-card-alt);
	--fc-border-color:             var(--fv2-border);

	/* El día de hoy: un tinte del acento, no el amarillo de serie */
	--fc-today-bg-color:           var(--fv2-accent-soft);
	--fc-highlight-color:          var(--fv2-accent-soft);

	/* Botones de la barra de herramientas */
	--fc-button-bg-color:          var(--fv2-accent);
	--fc-button-border-color:      var(--fv2-accent);
	--fc-button-text-color:        var(--fv2-on-accent);
	--fc-button-hover-bg-color:    var(--fv2-accent-strong);
	--fc-button-hover-border-color:var(--fv2-accent-strong);
	--fc-button-active-bg-color:   var(--fv2-accent-strong);
	--fc-button-active-border-color:var(--fv2-accent-strong);

	/*
	 * Color por defecto de evento. La mayoría llegan con su propio color desde
	 * el servidor (cada servicio tiene el suyo), así que esto sólo afecta a los
	 * que no lo traen.
	 */
	--fc-event-bg-color:           var(--fv2-accent);
	--fc-event-border-color:       var(--fv2-accent);
	--fc-event-text-color:         var(--fv2-on-accent);

	/* La línea de "ahora" tiene que cantar: es información, no decoración */
	--fc-now-indicator-color:      var(--fv2-error);

	--fc-list-event-hover-bg-color:var(--fv2-card-alt);
	--fc-small-font-size:          12px;

	font-family: var(--fv2-font-body);
}

/* Titular del mes/semana */
body.fv2-cal .fv2-fc .fc-toolbar-title {
	font-family: var(--fv2-font-head);
	font-weight: 700;
	letter-spacing: -.01em;
	color: var(--fv2-on-surface);
}

/* Cabeceras de día y horas del lateral */
body.fv2-cal .fv2-fc .fc-col-header-cell-cushion,
body.fv2-cal .fv2-fc .fc-timegrid-axis-cushion,
body.fv2-cal .fv2-fc .fc-timegrid-slot-label-cushion {
	font: 600 11.5px/1.3 var(--fv2-font-body);
	letter-spacing: .04em;
	text-transform: uppercase;
	text-decoration: none;
}

/* Número de día en la vista de mes */
body.fv2-cal .fv2-fc .fc-daygrid-day-number {
	font: 600 12.5px/1 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
	text-decoration: none;
}

body.fv2-cal .fv2-fc .fc-day-today .fc-daygrid-day-number { color: var(--fv2-accent-strong); }

/* Texto dentro de los eventos */
body.fv2-cal .fv2-fc .fc-event-title,
body.fv2-cal .fv2-fc .fc-event-time {
	font-family: var(--fv2-font-body);
	font-weight: 600;
}

/* Botones: sólo la forma y el tipo de letra (el color va por las variables) */
body.fv2-cal .fv2-fc .fc-button {
	font: 600 12.5px/1 var(--fv2-font-body);
	border-radius: 9px;
	text-transform: none;
	box-shadow: none !important;
}

body.fv2-cal .fv2-fc .fc-button-group > .fc-button:not(:first-child) { border-radius: 0 9px 9px 0; }
body.fv2-cal .fv2-fc .fc-button-group > .fc-button:not(:last-child)  { border-radius: 9px 0 0 9px; }

/* La lista (vista listWeek) */
body.fv2-cal .fv2-fc .fc-list-day-cushion {
	background: var(--fv2-card-alt);
	font: 600 11.5px/1.3 var(--fv2-font-body);
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--fv2-outline);
}

body.fv2-cal .fv2-fc .fc-list-event-title a { color: var(--fv2-on-surface); text-decoration: none; }

/* -----------------------------------------------------------------------------
 * HORARIO FIJO (/horariofijo) — el poco cromo que hay ENCIMA del calendario
 * -----------------------------------------------------------------------------
 * A diferencia de calendario.tpl, esta vista sí tiene HTML propio: el aviso de
 * "vista estática". Con el calendario ya retiñido, dejarlo con el azul de
 * Bootstrap canta. Es un gancho de página (.hf-aviso) y NO un componente del
 * design system, por eso no lleva prefijo .fv2-: la plantilla tiene que seguir
 * siendo válida para un cliente sin home_diseno="v2", que verá el alert normal.
 *
 * Los filtros ya NO viven aquí: han pasado al menú "Filtros" de la cabecera del
 * calendario (burger), como en calendario.tpl. Ese menú lo pinta el propio
 * plugin contextMenu y se retiñe con el resto del calendario (bloque de arriba),
 * así que no necesita reglas propias.
 * -------------------------------------------------------------------------- */
body.fv2-cal .hf-aviso {
	background: var(--fv2-accent-soft);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	color: var(--fv2-on-surface-var);
	font: 400 13px/1.5 var(--fv2-font-body);
	padding: 11px 14px;
	box-shadow: var(--fv2-shadow-card);
}

/* =============================================================================
 * RESERVAR CITA (.fv2-reserva)
 * -----------------------------------------------------------------------------
 * El flujo con el que un socio reserva: servicio → centro → día → profesional →
 * hora. Todo es CSS: los dos parciales (reserva.servicio.tpl y
 * reserva.fecha.tpl) los COMPARTE el diálogo de reserva, así que tocarlos
 * saldría también dentro de la modal.
 *
 * ⚠️ CONTRATOS DE modules/js/reservas.tpl.js QUE NO SE PUEDEN ROMPER:
 *
 *   #horas div.hora        el click está delegado sobre esa clase
 *   .hora > div.data       $(this).children('div.data') lee el id de la reserva
 *   .select_empleado.show  el selector de profesional se muestra AÑADIENDO .show
 *                          (style.css:318 lo tiene en display:none). Aquí no se
 *                          puede tocar su display o se ve siempre.
 *   #centro_reservar, #empleado, #datetimepicker, #reservas_fechas,
 *   #form-nouser, #b-descripcion, #shadowCollapseOne
 *
 * Se deja en COLUMNA a propósito, sin rejilla: es un flujo por pasos y así se
 * lee igual en móvil y en escritorio, sin depender del ancho disponible.
 * ========================================================================== */
.fv2-reserva {
	max-width: 760px;
	padding-bottom: 40px;
}

/* Los col-* de los parciales están pensados para la modal: aquí se apilan */
.fv2-reserva [class*="col-"] {
	width: 100%;
	max-width: none;
	flex: 0 0 auto;
}

.fv2-reserva .row { margin: 0; }
.fv2-reserva .row > * { padding-left: 0; padding-right: 0; }

/* --- Campos --------------------------------------------------------------- */
.fv2-reserva .form-select,
.fv2-reserva .form-control {
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-sm);
	font: 400 14px/1.4 var(--fv2-font-body);
	color: var(--fv2-on-surface);
	background-color: var(--fv2-card);
	min-height: 52px;
}

.fv2-reserva .form-select:focus,
.fv2-reserva .form-control:focus {
	border-color: var(--fv2-accent);
	box-shadow: 0 0 0 3px var(--fv2-accent-soft);
}

.fv2-reserva .form-floating > label {
	font: 400 12.5px/1.2 var(--fv2-font-body);
	color: var(--fv2-muted);
}

/* Aviso de "elige un centro": el tema lo hace parpadear en rojo */
.fv2-reserva .animate-pulse-danger { animation: none !important; border-color: var(--fv2-error) !important; }

/* --- Descripción del servicio (acordeón) ---------------------------------- */
.fv2-reserva .accordion .card {
	background: var(--fv2-card-alt);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-sm);
	box-shadow: none;
}

.fv2-reserva .accordion .btn {
	font: 600 13px/1.3 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
	text-align: left;
}

.fv2-reserva #b-descripcion {
	font: 400 13px/1.55 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
}

/* --- Horas disponibles ---------------------------------------------------- */
/*
 * Las pinta el JS así:
 *   <div class="form-floating border border-primary p-3 hora">
 *     <div class="data" data-r="123">08:00</div><label>Hora</label>
 *   </div>
 * La etiqueta "Hora" se repite en cada pastilla y no aporta nada cuando hay
 * doce seguidas: se oculta y manda el propio dato.
 */
.fv2-reserva #horas {
	display: flex !important;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 4px;
}

.fv2-reserva #horas > div.hora {
	padding: 0 !important;
	border: 1px solid var(--fv2-border) !important;
	border-radius: var(--fv2-radius-sm);
	background: var(--fv2-card);
	min-width: 84px;
	transition: border-color .15s ease;
}

.fv2-reserva #horas > div.hora:hover { border-color: var(--fv2-accent) !important; }

.fv2-reserva #horas .hora > label { display: none; }

.fv2-reserva #horas .hora > div.data {
	padding: 13px 14px;
	text-align: center;
	font: 600 15px/1 var(--fv2-font-head);
	color: var(--fv2-on-surface);
}

/*
 * Hora elegida. Los !important son porque #horas > div trae
 * "border: ... !important" de style.css:300.
 */
.fv2-reserva #horas > div.hora.hora-actv {
	background: var(--fv2-accent) !important;
	border-color: var(--fv2-accent) !important;
}

.fv2-reserva #horas .hora-actv > div.data { color: var(--fv2-on-accent); }

/* Sin horas: el contenedor vacío no debe dejar un hueco */
.fv2-reserva #horas:empty { display: none !important; }

/* --- Formulario rápido de quien no ha entrado ----------------------------- */
.fv2-reserva #form-nouser { max-width: 100% !important; margin-top: 14px; }

/* --- Calendario de días --------------------------------------------------- */
.fv2-reserva #reservas_fechas {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	padding: 8px;
	margin-bottom: 14px;
}

/* --- Mis citas ------------------------------------------------------------ */
.fv2-reserva h2,
.fv2-reserva h5 {
	font: 600 11px/1.4 var(--fv2-font-body) !important;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--fv2-outline);
	margin: 22px 0 10px;
}

/*
 * Las citas usan modules/sesion.tpl, la misma plantilla que la ficha. Se hereda
 * su piel repitiendo aquí lo justo: la tarjeta y el bloque de fecha.
 */
.fv2-reserva .cita {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border) !important;
	border-radius: var(--fv2-radius-card);
	box-shadow: var(--fv2-shadow-card);
	margin-bottom: 12px !important;
	overflow: hidden;
}

.fv2-reserva .cita p { font-size: 13.5px; }
.fv2-reserva .cita p strong { font-family: var(--fv2-font-head); font-size: 15.5px; }

.fv2-reserva .cita > div:last-child {
	background: var(--fv2-card-alt);
	justify-content: center !important;
}

.fv2-reserva .cita > div:last-child > div:first-child {
	font-family: var(--fv2-font-head) !important;
	font-weight: 700;
	color: var(--fv2-accent);
	line-height: 1;
}

.fv2-reserva .cita > div:last-child > div:last-child {
	font: 600 11px/1.4 var(--fv2-font-body);
	letter-spacing: .1em;
	color: var(--fv2-outline);
}

/* =============================================================================
 * SUGERENCIAS (#sugerencias-page)
 * -----------------------------------------------------------------------------
 * Aquí NO se duplica la plantilla: la tabla tiene contratos con
 * modules/js/sugerencias.tpl.js que hay que respetar tal cual —
 *
 *     tbody#sugerencias           marcar_sugerencia() cuenta ':checked' dentro
 *     tr[data-id]                 ocultar_sugerencias() y delete_sugerencia()
 *                                 hacen $(this).parents('tr').data('id')
 *     td.texto > p                mostrar_sugerencia() lee $(_this).children().text()
 *     #button-ocultar             se muestra/oculta con .css('display')
 *
 * Sólo cambia el contenedor (que pasa a .fv2) y se le pone un id; el resto es
 * piel sobre el HTML que ya había.
 * ========================================================================== */
.fv2-suger { padding-bottom: 40px; }

/* La cabecera clásica (<header><h1 class="h4">) se lee como el saludo de la portada */
.fv2-suger > header {
	margin: 0 var(--fv2-gutter) 16px;
}

.fv2-suger > header h1 {
	font: 700 26px/1.15 var(--fv2-font-head) !important;
	color: var(--fv2-on-surface);
	letter-spacing: -.02em;
	margin: 0 0 4px;
}

.fv2-suger > header p {
	margin: 0;
	font: 400 13px/1.5 var(--fv2-font-body);
	color: var(--fv2-muted);
}

.fv2-suger > header small { font-size: inherit; }

/* Las dos secciones (el botón y la tabla) son tarjetas */
.fv2-suger .section {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	box-shadow: var(--fv2-shadow-card);
	margin: 0 var(--fv2-gutter) 14px;
}

.fv2-suger .card-body { padding: 14px 16px; }

.fv2-suger .btn-primary {
	background: var(--fv2-accent);
	border-color: var(--fv2-accent);
	color: var(--fv2-on-accent);
	border-radius: 10px;
	font: 600 13px/1 var(--fv2-font-body);
	padding: 11px 16px;
}

.fv2-suger .btn-primary:hover {
	background: var(--fv2-accent-strong);
	border-color: var(--fv2-accent-strong);
}

/* --- La tabla ------------------------------------------------------------- */
.fv2-suger table { font-size: 13.5px; margin-bottom: 0; }

.fv2-suger thead th {
	font: 600 11px/1.3 var(--fv2-font-body);
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--fv2-outline) !important;
	border-bottom: 1px solid var(--fv2-border);
	white-space: nowrap;
}

.fv2-suger tbody td { border-color: var(--fv2-divider); vertical-align: middle; }
.fv2-suger tbody tr:hover > td { background: var(--fv2-card-alt); }

/* El nombre del socio era un botón azul; es un enlace a su ficha */
.fv2-suger td .btn-soft {
	background: transparent !important;
	border: 0 !important;
	padding: 0 !important;
	font: 600 13.5px/1.3 var(--fv2-font-body);
	color: var(--fv2-on-surface) !important;
	white-space: normal;
	text-align: left;
}

.fv2-suger td .btn-soft:hover { color: var(--fv2-accent) !important; }

/*
 * El texto de la sugerencia. La plantilla le pone al <p> un width fijo de 260px
 * (style en sugerencias.tpl) con nowrap y ellipsis, y al pulsar se abre entero.
 * Se conserva el recorte —es lo que hace que la tabla no explote— pero el ancho
 * pasa a ser flexible en vez de 260px clavados.
 */
.fv2-suger td.texto { max-width: 0; width: 45%; }

.fv2-suger td.texto p {
	width: auto !important;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	color: var(--fv2-on-surface-var);
}

.fv2-suger td.texto:hover p { color: var(--fv2-accent); }

/* Sin transition: en esta capa el color no se anima nunca (ver el aviso de .fv2-tab) */
.fv2-suger .sugerencia-trash {
	cursor: pointer;
	color: var(--fv2-muted);
}

.fv2-suger .sugerencia-trash:hover { color: var(--fv2-error); }

/* Estado vacío */
.fv2-suger .card-body > .table-responsive-md > p {
	margin: 0;
	padding: 6px 0;
	font: 400 13.5px/1.5 var(--fv2-font-body);
	color: var(--fv2-muted);
}

/*
 * Móvil: la tabla pasa a tarjetas. Sin etiquetas generadas —esta tabla no lleva
 * data-content— el titular es el nombre y debajo el texto y la fecha.
 */
@media (max-width: 700px) {

	.fv2-suger thead { display: none; }

	.fv2-suger tbody,
	.fv2-suger tbody tr,
	.fv2-suger tbody td { display: block; }

	.fv2-suger tbody tr {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		column-gap: 10px;
		row-gap: 3px;
		padding: 12px 0;
		border-bottom: 1px solid var(--fv2-divider);
	}

	.fv2-suger tbody tr:last-child { border-bottom: 0; }

	.fv2-suger tbody td {
		border: 0 !important;
		padding: 0 !important;
		width: auto;
	}

	/* La primera celda va vacía en la plantilla: no ocupa sitio */
	.fv2-suger tbody td:first-child:empty { display: none; }

	.fv2-suger td.texto { width: 100%; max-width: none; }
	.fv2-suger td.texto p { white-space: normal; }
}

/* -------------------------------------------------- 10. Artículo / CMS -----
 * Vista de contenido (cms.tpl). El cuerpo estiliza el HTML del editor Quill.
 * -------------------------------------------------------------------------- */
.fv2-article { max-width: 720px; margin: 0 auto; padding: 8px 18px 40px; }
.fv2-article-back {
	display: inline-flex; align-items: center; gap: 4px;
	margin: 4px 0 8px; padding: 6px 0;
	color: var(--fv2-accent); font-size: 14px; font-weight: 500; text-decoration: none;
}
.fv2-article-back .fv2-ms { font-size: 20px; }
.fv2-article-head { padding: 6px 0 16px; border-bottom: 1px solid var(--fv2-divider); margin-bottom: 20px; }
.fv2-article-title { font-family: var(--fv2-font-head); font-weight: 700; font-size: 26px; line-height: 1.15; color: var(--fv2-on-surface); margin: 0; }
.fv2-article-body { font-size: 15.5px; line-height: 1.7; color: var(--fv2-on-surface-var); }
.fv2-article-body > :first-child { margin-top: 0; }
.fv2-article-body p { margin: 0 0 14px; }
.fv2-article-body h1, .fv2-article-body h2, .fv2-article-body h3, .fv2-article-body h4 { font-family: var(--fv2-font-head); color: var(--fv2-on-surface); line-height: 1.2; margin: 24px 0 10px; }
.fv2-article-body h1 { font-size: 22px; }
.fv2-article-body h2 { font-size: 19px; }
.fv2-article-body h3 { font-size: 17px; }
.fv2-article-body a { color: var(--fv2-accent); text-decoration: underline; }
.fv2-article-body img { max-width: 100%; height: auto; border-radius: var(--fv2-radius-sm); margin: 12px 0; display: block; }
.fv2-article-body ul, .fv2-article-body ol { margin: 0 0 14px; padding-left: 22px; }
.fv2-article-body li { margin: 4px 0; }
.fv2-article-body blockquote { margin: 14px 0; padding: 10px 16px; border-left: 3px solid var(--fv2-accent); background: var(--fv2-card-alt); border-radius: 0 var(--fv2-radius-sm) var(--fv2-radius-sm) 0; color: var(--fv2-on-surface); }
.fv2-article-body strong, .fv2-article-body b { color: var(--fv2-on-surface); }
.fv2-article-body hr { border: none; border-top: 1px solid var(--fv2-divider); margin: 20px 0; }
.fv2-article-body table { width: 100%; border-collapse: collapse; margin: 14px 0; font-size: 14px; }
.fv2-article-body th, .fv2-article-body td { border: 1px solid var(--fv2-border); padding: 6px 10px; text-align: left; }

/* -------------------------------------------------- 11. Acerca de ---------- */
.fv2-about-app {
	display: flex; align-items: center; gap: 12px;
	padding: 14px; margin-bottom: 8px;
	background: var(--fv2-card); border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card); box-shadow: var(--fv2-shadow-card);
}
.fv2-about-logo { width: 46px; height: 46px; object-fit: contain; flex: 0 0 auto; }
.fv2-about-appinfo { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; }
.fv2-about-appname { font-family: var(--fv2-font-head); font-weight: 700; font-size: 16px; color: var(--fv2-on-surface); }
.fv2-about-appver { font-size: 13px; color: var(--fv2-muted); }
.fv2-about-check {
	display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto;
	border: 0; padding: 8px 12px; border-radius: 999px;
	background: var(--fv2-accent-soft); color: var(--fv2-accent-strong);
	font-family: var(--fv2-font-body); font-size: 13px; font-weight: 600; cursor: pointer;
}
.fv2-about-check .fv2-ms { font-size: 18px; }
.fv2-about-kd { font-weight: 600; color: var(--fv2-on-surface); font-size: 13px; margin: 0 0 8px; }

/* Timeline de novedades — acordeón por año (<details>) + item compacto de 2 líneas */
.fv2-tl-years { margin: 4px 0 8px; }
.fv2-tl-year { border-bottom: 1px solid var(--fv2-divider); }
.fv2-tl-year:last-child { border-bottom: 0; }
.fv2-tl-year-sum {
	display: flex; align-items: center; gap: 8px;
	padding: 12px 4px; cursor: pointer;
	list-style: none; /* oculta el triángulo nativo */
	font-family: var(--fv2-font-head); font-weight: 700; font-size: 15px; color: var(--fv2-on-surface);
}
.fv2-tl-year-sum::-webkit-details-marker { display: none; }
.fv2-tl-year-sum:hover { color: var(--fv2-accent-strong); }
.fv2-tl-year-chev { font-size: 20px; color: var(--fv2-muted); transition: transform .15s ease; }
.fv2-tl-year[open] > .fv2-tl-year-sum > .fv2-tl-year-chev { transform: rotate(90deg); }
.fv2-tl-year-num { flex: 1 1 auto; }
.fv2-tl-year-n {
	flex: 0 0 auto; min-width: 22px; padding: 1px 7px; border-radius: 999px;
	background: var(--fv2-accent-soft); color: var(--fv2-accent-strong);
	font-family: var(--fv2-font-body); font-size: 11.5px; font-weight: 600; text-align: center;
}
.fv2-timeline { list-style: none; margin: 0 0 10px; padding: 0 0 0 6px; }
.fv2-tl-item { position: relative; display: flex; gap: 11px; padding: 0 0 12px 4px; }
.fv2-tl-item:last-child { padding-bottom: 4px; }
.fv2-tl-dot { flex: 0 0 auto; width: 9px; height: 9px; margin-top: 5px; border-radius: 50%; background: var(--fv2-accent); position: relative; z-index: 1; }
.fv2-tl-item:not(:last-child)::before { content: ""; position: absolute; left: 8px; top: 13px; bottom: 0; width: 2px; background: var(--fv2-divider); }
.fv2-tl-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.fv2-tl-head { display: flex; align-items: baseline; gap: 8px; }
.fv2-tl-ver { font-family: var(--fv2-font-head); font-weight: 700; font-size: 13.5px; color: var(--fv2-on-surface); }
.fv2-tl-date { font-size: 11.5px; color: var(--fv2-muted); }
.fv2-tl-desc { font-size: 13.5px; color: var(--fv2-on-surface-var); line-height: 1.45; }

/* Filas de info (soporte) */
.fv2-about-rows { display: flex; flex-direction: column; margin: 4px 0 8px; }
.fv2-inforow { display: flex; align-items: center; gap: 10px; padding: 11px 4px; color: var(--fv2-on-surface); text-decoration: none; border-bottom: 1px solid var(--fv2-divider); font-size: 14.5px; }
.fv2-inforow:last-child { border-bottom: 0; }
.fv2-inforow .fv2-ms { font-size: 21px; color: var(--fv2-accent); flex: 0 0 auto; }
.fv2-about-legal { font-size: 11.5px; color: var(--fv2-muted); line-height: 1.6; margin-top: 20px; }

/* =============================================================================
 * ENTRADA — login, pre-login, registro y recuperar contraseña
 * -----------------------------------------------------------------------------
 * EL PROBLEMA QUE ARREGLA (medido en el navegador, no supuesto):
 *
 *   1. En móvil la foto se pintaba con width:100vw; height:100vh. `100vw`
 *      INCLUYE el ancho de la barra de desplazamiento, así que en cuanto había
 *      barra vertical la capa sobresalía y aparecía scroll HORIZONTAL. Y `100vh`
 *      no sigue al contenido: con un mensaje de error el formulario crecía y la
 *      foto se quedaba corta, dejando una banda blanca abajo. Ahora es
 *      inset:0 sobre la fila (position-relative), que es exactamente la caja.
 *
 *   2. Los enlaces "¿Has olvidado la contraseña?" y "¿No tienes una cuenta?"
 *      son .link-muted (#506690) y caían encima de la foto — sobre la ropa
 *      oscura de la gente el contraste bajaba a ~1.5:1 y no se leían.
 *
 * POR QUÉ UNA TARJETA Y NO "OSCURECER UN POCO LA FOTO":
 *
 *   Desde ago-2026 el cliente puede SUBIR su propia imagen de fondo desde
 *   Configuración > Empresa. O sea que no sabemos qué foto habrá ahí: puede ser
 *   clara, oscura, con caras justo detrás del formulario. Cualquier ajuste
 *   calibrado contra la foto actual se rompe con la siguiente que suban.
 *   Con el formulario sobre una superficie sólida, la legibilidad deja de
 *   depender de la imagen. Es la única solución que no caduca.
 *
 * ESCRITORIO (>= lg) NO SE TOCA: sigue partido en dos, blanco a la izquierda y
 * foto a la derecha con la cuña. Todo lo de aquí abajo va dentro de la media
 * query de móvil salvo la propia foto.
 *
 * Sólo se aplica al cliente en v2 ($fv2_entrada en layout/base.tpl).
 * ========================================================================== */

/*
 * La foto ya no se lava con opacity: para eso está el velo de abajo, que oscurece
 * de forma uniforme y predecible. El .tpl escribe opacity:var(--fv2-entrada-op,.6),
 * así que a los clientes que NO cargan esta hoja les sigue valiendo el .6 de antes
 * y aquí sólo hay que redefinir el token. Sin !important y sin tocar el .tpl.
 */
body.fv2-entrada .fv2-entrada-bg {
	--fv2-entrada-op: 1;
	/*
	 * El encuadre venía fijado a "85% 100%" (esquina inferior derecha), elegido a
	 * ojo para la foto actual. Ahora la sube el cliente y no sabemos qué habrá:
	 * centrado es lo único que no destroza un encuadre cualquiera, y además deja
	 * ver la parte alta de la imagen, que es donde suele estar el rótulo.
	 * Mismo truco que la opacidad: el .tpl lo escribe con var(..., 85% 100%).
	 */
	--fv2-entrada-pos: center;
}

/*
 * La franja blanca de arriba en móvil NO es de la foto: base.tpl mete siempre,
 * como primer hijo de #middle, un <div class="breadcrumb-mobile-version mb-3">
 * que en estas pantallas va VACÍO. Al estar vacío colapsa sus márgenes, y al ser
 * el primer hijo ese margin-bottom (mb-3 = 16px) se propaga hacia arriba a través
 * de #middle y del body y empuja todo el documento 16px hacia abajo, dejando ver
 * el fondo blanco del <html> por encima de la foto.
 *
 * En las pantallas de entrada el breadcrumb no tiene nada que mostrar, así que se
 * oculta y con él desaparece el margen que se propagaba.
 */
body.fv2-entrada .breadcrumb-mobile-version {
	display: none;
}

/* El velo. Más denso abajo, que es donde caen los enlaces pequeños. */
body.fv2-entrada .fv2-entrada-bg::after {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(18, 28, 44, .30) 0%, rgba(18, 28, 44, .34) 45%, rgba(18, 28, 44, .58) 100%);
}

@media (max-width: 991.98px) {

	body.fv2-entrada {
		font-family: var(--fv2-font-body);
	}

	/*
	 * La columna del formulario traía px-3 py-6 (96px arriba y abajo) pensados
	 * para la mitad izquierda del escritorio. En un móvil eso es media pantalla
	 * de aire antes de ver nada.
	 */
	body.fv2-entrada .fv2-entrada-col > div {
		padding: 24px 16px !important;
	}

	/*
	 * Tarjeta translúcida ("frosted glass"): deja entrever la foto sin renunciar
	 * a la legibilidad. La clave es el backdrop-filter: blur() difumina lo que
	 * hay detrás, así que el texto se lee igual de bien caiga sobre una cara o
	 * sobre el rótulo — que es justo lo que no podíamos garantizar dejando la
	 * foto nítida, porque ahora la sube el cliente. Sin el blur, un 0.82 de
	 * blanco sobre una foto clara bajaría el contraste y volveríamos al problema
	 * de origen.
	 *
	 * El -webkit- va primero para el WebKit de iOS, que es justo el target de
	 * esta media query (móvil). Si el navegador no soporta backdrop-filter,
	 * degrada a un blanco casi opaco: se ve bien igual, solo sin el efecto.
	 */
	body.fv2-entrada .fv2-entrada-card {
		background: rgba(255, 255, 255, .82);
		-webkit-backdrop-filter: blur(16px);
		backdrop-filter: blur(16px);
		border-radius: 22px;
		padding: 26px 20px 22px;
		box-shadow: 0 18px 44px rgba(18, 28, 44, .30);
		text-align: left;
	}

	/* Sin soporte de backdrop-filter, subir la opacidad para no perder contraste */
	@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
		body.fv2-entrada .fv2-entrada-card {
			background: rgba(255, 255, 255, .95);
		}
	}

	body.fv2-entrada .fv2-entrada-card h1 {
		font-family: var(--fv2-font-head);
		font-weight: 700;
		font-size: 25px;
		line-height: 1.15;
		color: var(--fv2-on-surface);
		margin-bottom: 20px !important;   /* el mb-5 de Bootstrap son 48px */
	}

	/*
	 * mt-4 + mt-4 entre los dos enlaces son 48px que en la tarjeta sobran, y
	 * además separan de más el enlace de su pregunta.
	 */
	body.fv2-entrada .fv2-entrada-card form > .text-center.mt-4 {
		margin-top: 18px !important;
	}

	body.fv2-entrada .fv2-entrada-card .form-control {
		border-radius: var(--fv2-radius-sm);
	}

	body.fv2-entrada .fv2-entrada-card .btn-primary {
		border-radius: var(--fv2-radius-sm);
		padding-top: 12px;
		padding-bottom: 12px;
		font-weight: 600;
	}

	/*
	 * El logo Centraline/SoftLine iba suelto sobre la foto. Dentro de la tarjeta
	 * se lee, pero es el elemento menos importante de la pantalla: se separa con
	 * una línea y se baja la opacidad para que no compita con el botón.
	 */
	body.fv2-entrada .fv2-entrada-logos {
		margin-top: 18px;
		padding-top: 16px;
		border-top: 1px solid var(--fv2-divider);
		opacity: .75;
	}

	/*
	 * Los dos logos vienen con width="150" fijo (300px + margen) y en una tarjeta
	 * de móvil se salen o se parten en dos líneas. Se dejan encoger.
	 */
	body.fv2-entrada .fv2-entrada-logos img {
		width: auto;
		max-width: 44%;
		height: auto;
	}
}

/* =============================================================================
 * LISTADOS DE GESTIÓN (.fv2-listado)
 * -----------------------------------------------------------------------------
 * La primera pantalla de BACKOFFICE que entra en el rediseño (/usuarios). Se
 * escribe como componente y no como reglas de "la pantalla de usuarios" porque
 * detrás vienen las demás tablas de gestión (bonos, caja, facturas, stock...).
 *
 * Tres decisiones que conviene entender antes de tocar nada:
 *
 *   1. ANCHO COMPLETO. .fv2 limita a 640px porque nació para el móvil del socio.
 *      Un listado de gestión tiene ocho columnas y se consulta en un portátil,
 *      así que se libera el tope igual que ya hace .fv2-ficha. El aire lateral
 *      lo pone el propio contenedor, que en .fv2 va a cero.
 *
 *   2. LA TABLA SIGUE SIENDO UNA TABLA en escritorio. Aquí no se gana nada
 *      convirtiéndola en fichas: el personal compara filas de un vistazo y
 *      necesita las columnas alineadas. Lo que se rediseña es la piel.
 *
 *   3. EN MÓVIL SE PARTE EN TARJETAS, y de eso NO se encarga este archivo: lo
 *      hace responsive-table.css (cargado en head.tpl para todas las páginas)
 *      a partir de la clase table-mobile-responsive y del data-content de cada
 *      celda. Aquí sólo se le da forma de tarjeta v2, exactamente igual que ya
 *      se hizo para la tabla de bonos de la ficha. Los dos comentarios largos
 *      que explican POR QUÉ hacen falta el !important del padding y el
 *      position:static de la etiqueta están en esa sección (buscar
 *      "Bonos: tarjetas en móvil/tablet"); no se repiten aquí.
 * ========================================================================== */

/* El tope de 640px se escribe con DOBLE clase, igual que .fv2.fv2-ficha, porque
 * compite con el max-width de .fv2 (misma especificidad, gana el último). */
.fv2.fv2-listado {
	max-width: none;
	padding: 0 var(--fv2-gutter) 40px;
}

/*
 * ...Y ADEMÁS HAY QUE GANARLE AL ANCHO DE PANTALLA DEL .INI.
 *
 * La regla `body.layout-ancho .fv2 { max-width: 1400px }` de más arriba es
 * (0,2,1) y le gana a `.fv2.fv2-listado` (0,2,0): en un cliente con
 * ancho_pantalla="ancho" —que es el caso de fisic— el listado se quedaba en
 * 1400px con bandas de vacío a los lados, aunque #middle sí estuviera a ancho
 * completo. El síntoma engaña, porque en pantallas de menos de 1400px no se
 * nota nada.
 *
 * Es exactamente el mismo caso que la ficha, que ya lo resuelve así unas líneas
 * más arriba. Si se añade una tercera pantalla de ancho libre, necesitará su
 * propia línea aquí.
 */
@media (min-width: 1200px) {
	body.layout-ancho .fv2.fv2-listado,
	body.layout-full  .fv2.fv2-listado { max-width: none; }
}

/* -------------------------------------------------- Migas (sólo móvil) ---- */
/*
 * EL BREADCRUMB DE MÓVIL, QUE REPETÍA EL TÍTULO.
 *
 * Hay DOS breadcrumbs en el documento: uno dentro del <header> (el que se ve en
 * escritorio) y otro en `<div class="breadcrumb-mobile-version">`, primer hijo de
 * #middle, que el tema esconde a partir de md. O sea que todo lo de aquí abajo
 * sólo se ve en móvil — comprobado: en escritorio ese envoltorio computa
 * display:none.
 *
 * Dos problemas en móvil:
 *
 *   1. El último eslabón ES el título de la página, y el <h1> lo repite palabra
 *      por palabra tres píxeles más abajo. En 390px eso es una línea entera
 *      gastada en decir dos veces lo mismo.
 *   2. Venía con la tipografía del tema (16px, color de texto normal), o sea con
 *      el mismo peso visual que el contenido, cuando es navegación secundaria.
 *
 * Se resuelve dejándolo como lo que de verdad hace falta en un móvil: un enlace
 * de VUELTA. Se oculta el eslabón activo y el primero recibe un chevron ‹.
 *
 * Ojo con ocultar el activo: sólo es seguro porque TODOS los breadcrumbs de la
 * app llevan al menos dos eslabones (el primero siempre es "Inicio") — se
 * auditaron todas las llamadas a breadcrumbs.tpl. Las tres vistas v2 que no
 * tendrían nada que mostrar (home, cms y reservas) directamente no pintan
 * breadcrumb. Si algún día se añade uno de un solo eslabón, ahí quedaría una
 * barra vacía con su margen.
 *
 * En un breadcrumb de tres niveles (p.ej. Inicio › Configuración › Acerca de) se
 * oculta sólo el último, así que queda "‹ Inicio › Configuración", que sigue
 * siendo un rastro útil.
 */
/*
 * El margen va en el <ol>, NO en el envoltorio. Hay vistas que no pintan migas
 * (acerca_de, por ejemplo) y dejan el <div class="breadcrumb-mobile-version mb-3">
 * vacío: con el margen en el envoltorio queda una franja en blanco sin nada
 * dentro. Poniéndolo en la lista, si no hay lista no hay margen. Es el mismo
 * problema que en las pantallas de entrada, allí resuelto ocultando el envoltorio.
 */
body.fv2-page .breadcrumb-mobile-version {
	margin-bottom: 0 !important;
}

body.fv2-page .breadcrumb-mobile-version .breadcrumb {
	margin-bottom: 10px;
	/* '›' en vez del '>' que la plantilla pone en línea sobre el <nav>: aquí se
	   declara sobre el <ol>, que es más específico que heredarlo del padre. */
	--bs-breadcrumb-divider: '\203A';
	font: 500 12.5px/1.3 var(--fv2-font-body);
	align-items: center;
	flex-wrap: nowrap;
	min-width: 0;
}

body.fv2-page .breadcrumb-mobile-version .breadcrumb-item,
body.fv2-page .breadcrumb-mobile-version .breadcrumb-item a,
body.fv2-page .breadcrumb-mobile-version .breadcrumb-item::before {
	color: var(--fv2-outline);
}

/* El chevron de vuelta. No choca con el separador del tema, que lo pinta
   `.breadcrumb-item + .breadcrumb-item::before` y por tanto nunca en el primero. */
body.fv2-page .breadcrumb-mobile-version .breadcrumb-item:first-child::before {
	content: '\2039';
	float: none;
	padding-right: 0;
	margin-right: 5px;
	font-size: 15px;
	line-height: 1;
}

/* El eslabón activo es el título de la página, que ya está en el <h1> de debajo */
body.fv2-page .breadcrumb-mobile-version .breadcrumb-item.active {
	display: none;
}

/* Si un rastro largo no cabe, que se recorte el intermedio y no rompa la línea */
body.fv2-page .breadcrumb-mobile-version .breadcrumb-item:not(:first-child) {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
/* -------------------------------------------------- Cabecera de página ---- */
/*
 * El título vive FUERA del panel, sobre el fondo de la página. Su aire inferior
 * (16px) es el mismo que el relleno lateral del panel, para que la distancia del
 * título al panel y la del panel a su contenido se lean como una sola retícula.
 */
.fv2-listado > header {
	padding: 0 2px 16px;
}

.fv2-listado > header h1 {
	font: 700 24px/1.25 var(--fv2-font-head);
	color: var(--fv2-on-surface);
	margin: 0;
}

/* -------------------------------------------------- Panel ----------------- */
/*
 * .section es la tarjeta del tema. Se le da la forma del sistema y SIN SOMBRA:
 * el panel ocupa toda la pantalla, así que la sombra no separa nada de nada y
 * sólo ensucia el borde. Se define con el borde y el blanco sobre el gris de la
 * página, igual que las tarjetas de la lista en móvil.
 *
 * ⚠️ EL SELECTOR LARGO ES OBLIGATORIO, no es paranoia. El tema declara
 * (core.css:19883):
 *
 *     body.layout-admin #middle .section:not(.section-clean) {
 *         padding: 15px; background-color: #fff;
 *         box-shadow: 0 0 25px rgba(140,152,164,.1); border-radius: .35rem; }
 *
 * ...que es (1,3,1). Escrito como `.fv2-listado .section` esto es (0,2,0) y
 * PIERDE ENTERO: se comprobó midiendo el estilo calculado y del bloque sólo
 * llegaba el fondo — el panel seguía con la sombra del tema, borde 0, radio de
 * 5,6px y 30px de margen inferior. Con `.fv2-listado` delante queda en (1,4,1)
 * y gana. Si alguien lo acorta, la sombra vuelve sin que nada avise.
 *
 * El margen inferior va a cero porque el contenedor .fv2 ya trae 40px de aire
 * abajo; con los 30px del tema quedaban 70px de vacío al final de la página.
 */
body.fv2-page #middle .fv2-listado .section:not(.section-clean) {
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	box-shadow: none;
	margin-bottom: 0;
}

.fv2-listado .card-header {
	border-bottom: 1px solid var(--fv2-divider);
	padding: 18px var(--fv2-gutter) !important;
}

.fv2-listado .card-body {
	padding: 14px var(--fv2-gutter) 6px;
}

/* -------------------------------------------------- Barra de herramientas - */
/* El buscador lleva .bg-gray-100 del tema: se reemplaza por la superficie alterna */
.fv2-listado .form-control,
.fv2-listado .form-select {
	background-color: var(--fv2-card-alt);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-sm);
	font: 400 14px/1.4 var(--fv2-font-body);
	color: var(--fv2-on-surface);
}

.fv2-listado .form-control:focus,
.fv2-listado .form-select:focus {
	background-color: var(--fv2-card);
	border-color: var(--fv2-accent);
	box-shadow: none;
}

/*
 * ICONO Y TEXTO CENTRADOS.
 *
 * El <a class="btn"> del tema compone sus hijos EN LÍNEA y alineados por línea
 * base. Con `line-height: 1` (13px) y un <span> que ocupa 16px, la caja de línea
 * no coincide con la del botón: el conjunto icono+texto quedaba unos 3px por
 * encima del centro, y el icono medio píxel descolgado respecto al texto. Medido:
 * centro del contenido en 16px, centro del botón en 19px.
 *
 * Con inline-flex el centrado no depende de la tipografía ni del alto del icono,
 * y el hueco entre icono y texto pasa a ser un valor explícito en vez del espacio
 * en blanco del HTML, que además desaparece al hacer flex.
 */
.fv2-listado .btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	border-radius: 10px;
	font: 600 13px/1.2 var(--fv2-font-body);
	padding: 9px 14px;
}

/*
 * El botón redondo de acciones es la excepción: sólo lleva icono, el tema le fija
 * ancho y alto (.btn.btn-sm.rounded-circle) y no necesita hueco entre hijos.
 */
.fv2-listado .btn.rounded-circle {
	gap: 0;
}

.fv2-listado .btn-primary {
	background: var(--fv2-accent);
	border-color: var(--fv2-accent);
	color: var(--fv2-on-accent);
}

.fv2-listado .btn-primary:hover {
	background: var(--fv2-accent-strong);
	border-color: var(--fv2-accent-strong);
}

.fv2-listado .btn-light {
	background: var(--fv2-card-alt);
	border-color: var(--fv2-border);
	color: var(--fv2-on-surface-var);
}

/*
 * EL PARCHE BLANCO DE LAS ETIQUETAS FLOTANTES.
 *
 * El tema pinta un rectángulo opaco detrás del texto de la etiqueta flotante
 * (core.css:2102):
 *
 *     .form-floating > .form-select ~ label:after {
 *         background-color: var(--bs-body-bg); ... z-index: -1; }
 *
 * Existe para tapar el borde del campo por detrás de la etiqueta cuando el campo
 * es blanco. Aquí el campo tiene fondo propio (--fv2-card-alt), así que ese
 * rectángulo blanco se ve como un recorte mal hecho alrededor del texto.
 * Transparente: la etiqueta se apoya directamente sobre el campo.
 */
.fv2-listado .form-floating > .form-select ~ label::after,
.fv2-listado .form-floating > .form-control ~ label::after {
	background-color: transparent;
}

/* El desplegable de filtros */
.fv2-listado .dropdown-menu {
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-card);
	box-shadow: var(--fv2-shadow-hero);
}

/* -------------------------------------------------- Filtros en uso -------- */
/* Píldoras: el tema las pinta cuadradas y con el azul de Bootstrap */
.fv2-listado .list-inline-item.badge {
	border-radius: 999px;
	font: 600 11.5px/1 var(--fv2-font-body);
	padding: 8px 12px !important;
}

.fv2-listado .list-inline-item.badge.bg-primary {
	background: var(--fv2-accent) !important;
}

.fv2-listado .list-inline-item.badge.bg-light {
	background: var(--fv2-card-alt) !important;
	border: 1px solid var(--fv2-border);
}

/*
 * ⚠️ EL TEXTO DE LA PÍLDORA ACTIVA HAY QUE FORZARLO.
 *
 * El tema trae (core.css):
 *
 *     ul.list-inline .bg-primary span { color: var(--bs-body-color) !important; }
 *
 * ...que es (0,2,2) CON !important y le gana al .text-white (0,1,0) que la
 * plantilla pone en el propio span. Con el índigo de fábrica se quedaba en azul
 * marino sobre índigo —mal contraste, pero se leía—; en cuanto el acento del
 * cliente es oscuro (fisic lo tiene en negro) el texto DESAPARECE. Hay que
 * ganarle con más especificidad y también con !important.
 */
.fv2-listado ul.list-inline .badge.bg-primary span,
.fv2-listado ul.list-inline .badge.bg-primary a {
	color: var(--fv2-on-accent) !important;
}

/*
 * EL COLOR DE MARCADO ES EL DEL CLIENTE, TAMBIÉN EN LO QUE PINTA EL TEMA.
 *
 * El identificador de app de cada socio se pinta con .btn-soft.btn-primary, o
 * sea con el azul de Bootstrap del tema, que NO tiene nada que ver con
 * color_acento del .ini. Al ser el elemento más repetido del listado, era lo
 * que más delataba que la pantalla no iba teñida del color del cliente.
 *
 * Se reasigna al par acento/acento-suave, que es el mismo que usan las tiles y
 * las píldoras de la portada. El !important es porque el tema declara el suyo
 * con las variables --bs-btn-* del propio componente.
 */
.fv2-listado .btn-soft.btn-primary {
	background-color: var(--fv2-accent-soft) !important;
	border-color: var(--fv2-accent-soft) !important;
	color: var(--fv2-accent) !important;
	font-weight: 600;
}

/* La casilla de marcado, por lo mismo: es una marca, va del color del cliente */
.fv2-listado .form-check-input:checked {
	background-color: var(--fv2-accent);
	border-color: var(--fv2-accent);
}

/* -------------------------------------------------- Tabla (escritorio) ---- */
.fv2-listado .table > thead th {
	font: 600 11px/1.4 var(--fv2-font-body) !important;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--fv2-outline) !important;
	border-bottom: 1px solid var(--fv2-border);
	padding-bottom: 10px;
}

.fv2-listado .table > tbody > tr {
	border-bottom: 1px solid var(--fv2-divider);
}

.fv2-listado .table > tbody > tr:hover {
	background: var(--fv2-card-alt);
}

.fv2-listado .table > tbody > tr > td {
	font: 400 14px/1.45 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
	padding-top: 12px;
	padding-bottom: 12px;
	vertical-align: middle;
}

.fv2-listado .fv2-cell-title {
	font-weight: 600;
	color: var(--fv2-on-surface);
}

/*
 * Los tics y aspas de Cliente y Activo son <i class="fa fa-2x">. A 2x pesan más
 * que el dato al que acompañan y descuadran el alto de la fila; se bajan al
 * tamaño del texto y se tiñen con los colores de estado del sistema, en vez del
 * verde y el rojo puros que llevan escritos en línea. Ese style="color:..." es
 * un atributo y gana a cualquier selector: por eso hace falta el !important.
 */
.fv2-listado .table .fa-2x {
	font-size: 1.15em;
}

.fv2-listado .table .fa-check {
	color: var(--fv2-ok) !important;
}

.fv2-listado .table .fa-xmark {
	color: var(--fv2-error) !important;
}

/* El aviso "Pasar a usuario" y el contador de candidatos */
.fv2-listado .badge.bg-soft-warning,
.fv2-listado .badge.bg-warning {
	background: var(--fv2-warn) !important;
	color: var(--fv2-on-surface) !important;
	border-radius: 999px;
	font: 600 11px/1 var(--fv2-font-body);
	padding: 7px 11px;
}

/* -------------------------------------------------- Paginación ------------ */
.fv2-listado .html-pagination {
	padding: 16px 0 4px;
}

.fv2-listado .html-pagination .pagination {
	gap: 6px;
	flex-wrap: wrap;
	justify-content: center;
	margin: 0;
}

.fv2-listado .html-pagination .page-link {
	border: 1px solid var(--fv2-border);
	border-radius: 10px;
	color: var(--fv2-on-surface-var);
	font: 600 13px/1 var(--fv2-font-body);
	padding: 9px 13px;
}

.fv2-listado .html-pagination .active .page-link {
	background: var(--fv2-accent);
	border-color: var(--fv2-accent);
	color: var(--fv2-on-accent);
}

/* -------------------------------------------------- Tarjetas en móvil ----- */
/*
 * Mismo umbral que la tabla de bonos de la ficha, para que las dos pantallas
 * cambien de forma a la vez. La segunda condición cubre las tablets, que tienen
 * ancho de sobra en píxeles pero se usan en vertical.
 *
 * EL GANCHO ES LA CLASE .fv2-tbody DEL <tbody>, y el selector va cualificado con
 * `table.table-mobile-responsive` a propósito. Las dos cosas tienen motivo:
 *
 *   1. Era `#checkall-list`, el id que /usuarios necesita para su marcar-todos.
 *      Al llegar /servicios, que trae CUATRO tablas en una página, ese id no podía
 *      seguir siendo la llave: las tres pestañas clásicas ya lo repetían tal cual
 *      (tres elementos con el mismo id) sin usar el marcar-todos para nada.
 *
 *   2. ⚠️ PERO NO BASTA CON CAMBIAR EL ID POR LA CLASE. `responsive-table.css`
 *      declara `.table-mobile-responsive tr:not(.bg-light-blue) { border-bottom:
 *      2px solid #3490dc }`, que es (0,2,1) y se carga DESPUÉS que este archivo
 *      (head.tpl:181 frente a :156). Con `.fv2-listado .fv2-tbody > tr` habría
 *      empate a (0,2,1) y ganaría el otro: cada tarjeta saldría con una raya azul
 *      de 2px debajo. Con el `table.table-mobile-responsive` de por medio queda en
 *      (0,3,2) y gana. Si alguien acorta el selector, vuelve la raya.
 */
@media only screen and (max-width: 760px),
       (min-device-width: 768px) and (max-device-width: 1024px) {

	.fv2-listado table.table-mobile-responsive {
		border: 0;
	}

	/*
	 * Cada fila pasa a ser una tarjeta.
	 *
	 * ⚠️ NO LE PONGAS box-shadow A ESTA REGLA. El tema trae en core.css:19830:
	 *
	 *     .table:not(.table-striped):not(.table-hover) > :not(caption) > * > * {
	 *         box-shadow: inherit; }
	 *
	 * ...que está ahí para anular el sombreado inset con el que Bootstrap 5 pinta
	 * las filas alternas, y lo hace haciendo que CADA CELDA herede la sombra de su
	 * fila —normalmente `none`—. En cuanto la fila tiene sombra, las ocho celdas se
	 * la copian entera y la tarjeta sale con ocho sombras superpuestas pegadas al
	 * texto: parecen bandas grises de fondo y quedan muy sucias en una lista larga.
	 *
	 * La tarjeta se define con el borde y el blanco sobre el gris de la página, que
	 * además es lo coherente con el listado en escritorio, que tampoco lleva relieve.
	 * El único elevado es el panel .section que las contiene.
	 */
	.fv2-listado table.table-mobile-responsive .fv2-tbody > tr {
		display: block;
		background: var(--fv2-card);
		border: 1px solid var(--fv2-border);
		border-radius: var(--fv2-radius-card);
		box-shadow: none;
		padding: 18px 18px 14px;
		margin-bottom: 14px;
	}

	.fv2-listado table.table-mobile-responsive .fv2-tbody > tr:hover {
		background: var(--fv2-card);   /* el hover de escritorio aquí no aporta */
	}

	/* Etiqueta a la izquierda, valor a la derecha (ver la sección de bonos) */
	/*
	 * ⚠️ LAS DOS ÚLTIMAS DECLARACIONES SON LAS QUE EVITAN QUE SE SALGA EL CORREO.
	 *
	 * Un correo no tiene espacios (aina.galmes.panades@gmail.com), así que el
	 * navegador no encuentra dónde partirlo; y como elemento de una fila flexible
	 * su min-width es `auto`, o sea que tampoco se deja encoger por debajo de su
	 * contenido. Resultado medido a 390px: la celda se desbordaba 87px
	 * (scrollWidth 335 contra clientWidth 248).
	 *
	 * La solución NO es dejar que encoja: partido por la mitad quedaba
	 * "diamante181250@" / "gmail.com", que se lee fatal. Lo que se quiere es que
	 * el valor BAJE ENTERO a su propia línea, y para eso:
	 *
	 *   - `flex-wrap: wrap` permite que el valor pase a la línea siguiente, donde
	 *     dispone de los 248px completos y cabe de sobra (mide 189).
	 *   - `overflow-wrap: break-word` y NO `anywhere`: `anywhere` reduce el ancho
	 *     mínimo del contenido a casi cero, así que flexbox prefiere encogerlo y
	 *     partirlo antes que saltar de línea — justo lo contrario de lo que se
	 *     busca. Con `break-word` el mínimo sigue siendo la palabra entera, la
	 *     línea salta, y el corte sólo actúa si un valor no cupiera ni él solo.
	 *   - Y por eso mismo NO se pone `min-width: 0` en la celda.
	 *
	 * No se veía a 500px de ancho, que es donde se probó al principio. Para
	 * comprobarlo hay que emular un móvil de verdad: la ventana del navegador no
	 * baja de ~500px y un simple redimensionado engaña.
	 */
	.fv2-listado table.table-mobile-responsive .fv2-tbody > tr > td {
		border: 0;
		padding: 7px 0 !important;
		display: flex;
		align-items: baseline;
		justify-content: space-between;
		gap: 18px;
		text-align: right !important;
		flex-wrap: wrap;
		overflow-wrap: break-word;
	}

	/* La etiqueta no se parte: es corta y no tiene por qué heredar el corte libre */
	.fv2-listado table.table-mobile-responsive .fv2-tbody > tr > td::before {
		overflow-wrap: normal;
	}

	.fv2-listado table.table-mobile-responsive .fv2-tbody > tr > td:before {
		position: static;
		top: auto;
		left: auto;
		width: auto;
		font: 400 11.5px/1.3 var(--fv2-font-body);
		color: var(--fv2-outline);
		text-align: left;
		flex: 0 0 auto;
		white-space: normal;
	}

	/* El nombre es el titular de la tarjeta, sin etiqueta */
	.fv2-listado table.table-mobile-responsive .fv2-tbody > tr > td.fv2-cell-title {
		font: 700 17px/1.2 var(--fv2-font-head);
		color: var(--fv2-on-surface);
		border-bottom: 1px solid var(--fv2-divider);
		padding-bottom: 12px !important;
		margin-bottom: 6px;
		text-align: left !important;
	}

	.fv2-listado table.table-mobile-responsive .fv2-tbody > tr > td.fv2-cell-title:before {
		display: none;
	}

	/*
	 * Las celdas SIN data-content son las dos que no son un dato: la casilla de
	 * marcado (que sólo aparece si hay candidatos en la página) y el menú de
	 * acciones. Sin etiqueta al lado, se alinean a los extremos.
	 */
	.fv2-listado table.table-mobile-responsive .fv2-tbody > tr > td:not([data-content]) {
		justify-content: flex-end;
	}

	/*
	 * El menú de acciones sube a la esquina de la tarjeta, a la altura del nombre.
	 * Dejándolo donde cae por orden de columnas queda un botón redondo de 41px
	 * suelto debajo del último dato, más alto que las filas de datos (32px), con un
	 * hueco que parece un error de maquetación. Arriba a la derecha es además donde
	 * se espera encontrarlo.
	 *
	 * El menú desplegable que cuelga de él no se recorta: la tarjeta no tiene
	 * overflow y Bootstrap lo posiciona con Popper.
	 */
	.fv2-listado table.table-mobile-responsive .fv2-tbody > tr {
		position: relative;
	}

	.fv2-listado table.table-mobile-responsive .fv2-tbody > tr > td:last-child {
		position: absolute;
		top: 10px;
		right: 10px;
		padding: 0 !important;
	}

	/* La casilla de marcado va pegada al nombre, no en una fila suya con aire */
	.fv2-listado table.table-mobile-responsive .fv2-tbody > tr > td:not([data-content]):first-child {
		justify-content: flex-start;
		padding: 0 !important;
	}

	/* La cabecera de la tabla la esconde responsive-table.css; el envoltorio de
	 * scroll horizontal ya no pinta nada y sólo añade un borde. */
	.fv2-listado .table-responsive-md {
		overflow: visible;
	}
}

/* =============================================================================
 * PESTAÑAS DE LISTADO (.fv2-listado > .nav-tabs)
 * -----------------------------------------------------------------------------
 * /servicios es la segunda pantalla de backoffice que entra en el rediseño y la
 * primera que trae PESTAÑAS: cuatro (bonos, servicios, ubicaciones,
 * integraciones), cada una con su propio panel .section. .fv2-listado no las
 * contemplaba porque /usuarios es una tabla sola.
 *
 * Se pintan como CHIPS y no como solapas, calcadas de las sub-pestañas de la
 * ficha del socio (.fv2-ficha-body .nav-tabs, más arriba en este archivo). El
 * motivo no es estético: una solapa necesita apoyarse en el borde superior del
 * panel para leerse como solapa, y aquí el panel es una tarjeta despegada del
 * fondo, con borde en las cuatro caras y esquinas redondeadas. Una solapa
 * flotando sobre eso no se apoya en nada y queda como un botón mal puesto.
 *
 * NO se reusa el selector de la ficha: comparten la idea, no el contexto — allí
 * las pestañas van DENTRO del cuerpo de una tarjeta, aquí van FUERA del panel,
 * sobre el fondo de la página, y por tanto el aire de arriba y abajo es otro.
 *
 * Se escribe con `>` a propósito: dentro de los paneles hay más `.nav` (los
 * dropdowns de acciones) y alguna pestaña podría traer sub-pestañas propias en
 * el futuro. Esto es la barra de primer nivel y sólo esa.
 * ========================================================================== */
.fv2-listado > .nav-tabs {
	border-bottom: 0;
	gap: 8px;
	flex-wrap: nowrap;
	overflow-x: auto;
	scrollbar-width: none;
	/* 2px laterales: la misma sangría que <header>, para que el primer chip
	   quede a plomo con el título. */
	padding: 0 2px 2px;
	margin: 0 0 14px;
}

.fv2-listado > .nav-tabs::-webkit-scrollbar { display: none; }

.fv2-listado > .nav-tabs .nav-item { flex: 0 0 auto; }

.fv2-listado > .nav-tabs .nav-link {
	font: 600 13px/1 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
	background: var(--fv2-card);
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-sm);
	padding: 11px 16px;
	white-space: nowrap;
	/* El tema mete `margin-bottom: calc(-1 * 1px)` para que la solapa monte
	   sobre la línea inferior. Sin línea que montar, ese -1px sólo descuadra. */
	margin-bottom: 0;
	/* Anula el "transition: color, background-color, border-color" de Bootstrap:
	   con el fondo cambiando de blanco a acento, la transición del color de
	   texto pasa por un gris ilegible. */
	transition: border-color .15s ease;
}

.fv2-listado > .nav-tabs .nav-link:hover,
.fv2-listado > .nav-tabs .nav-link:focus {
	border-color: var(--fv2-accent);
	background: var(--fv2-card);
}

.fv2-listado > .nav-tabs .nav-link.active {
	color: var(--fv2-on-accent);
	background: var(--fv2-accent);
	border-color: var(--fv2-accent);
}

/* A partir de tablet las cuatro caben de sobra: se envuelven en vez de deslizarse */
@media (min-width: 768px) {
	.fv2-listado > .nav-tabs { flex-wrap: wrap; overflow-x: visible; }
}

/* =============================================================================
 * BONOS: "SE VE EN" Y LA BARRA DE FILTROS
 * -----------------------------------------------------------------------------
 * La tabla de bonos tenía una columna con TRES iconos por fila (check o aspa
 * para web, app y asignar) bajo un encabezado que además los nombraba en otro
 * orden. Tres aspas seguidas no dicen nada y en móvil, partida en tarjeta, la
 * celda quedaba sin forma de saber cuál era cuál.
 *
 * Pasa a ser una lista de lo que SÍ está: una etiqueta por sitio donde el bono
 * se ve, y un guión cuando no se ve en ninguno. Se lee de un tirón y sirve de
 * leyenda de la propia bandera, que es lo que filtra la barra de arriba.
 * ========================================================================== */
.fv2-listado .fv2-flags {
	display: flex;
	flex-wrap: wrap;
	gap: 5px;
}

/* La etiqueta base es un .badge del tema, para que en un cliente sin el
   rediseño (demo, bellesartspalma) siga siendo legible sin este archivo. */
.fv2-listado .fv2-flag {
	background: var(--fv2-accent-soft) !important;
	color: var(--fv2-accent) !important;
	border-radius: 999px;
	font: 600 11px/1 var(--fv2-font-body);
	padding: 6px 10px;
	white-space: nowrap;
}

/* El bono que no se ve en ningún sitio: un guión discreto, no un hueco vacío
   (un hueco se lee como "falta el dato", y aquí el dato es que no está). */
.fv2-listado .fv2-flag-none {
	color: var(--fv2-outline);
	font-size: 15px;
	line-height: 1;
}

/* Etiqueta neutra, para enumerar dentro de una celda sin recurrir a una lista con
   viñetas: los servicios de cada bono venían en un <ul><li> y en una tabla de
   siete columnas eso mete un salto de línea y una viñeta por servicio.
   NO se llama .fv2-chip: ese nombre ya es el del BOTÓN de fila de mi_cuenta.v2
   (más arriba en este archivo), que es pulsable y tiene otro tamaño. Aquí es un
   rótulo pasivo, y darles el mismo nombre habría hecho que un retoque en uno
   moviera el otro. */
.fv2-listado .fv2-tag {
	background: var(--fv2-card-alt) !important;
	color: var(--fv2-on-surface-var) !important;
	border: 1px solid var(--fv2-border);
	border-radius: 999px;
	font: 500 11px/1 var(--fv2-font-body);
	padding: 6px 10px;
}

/* La misma FORMA que .fv2-tag para un badge que lleva su propio color.

   No se puede usar .fv2-tag en un badge de color: esa regla fija tambien background y
   color con !important y gana por especificidad (.fv2-listado .fv2-tag son dos clases
   contra una), asi que dejaria gris un "Cambio de horario". Aqui va solo la geometria, y
   el color lo sigue poniendo la clase del tema.

   Sin esto, en v2 los badges de color conservaban el padding de Bootstrap y quedaban
   visiblemente mas pequenos y cuadrados al lado de los .fv2-tag de la misma celda. En
   clasico no se notaba porque alli .fv2-tag no hace nada y todos son badges de Bootstrap.

   Propiedades LARGAS y no el atajo `font:`: un var() indefinido dentro de un atajo
   invalida la declaracion entera, y eso ya costo una tarde en este mismo archivo. */
.fv2-listado .fv2-tag-color {
	border-radius: 999px;
	font-weight: 500;
	font-size: 11px;
	line-height: 1;
	font-family: var(--fv2-font-body);
	padding: 6px 10px;
}

/* -------------------------------------------------- Barra de filtros ------ */
/* La nota al pie de la cabecera (hoy sólo integraciones: el aviso de que la API
   key se ve una vez). Va en el tono secundario porque es una advertencia de
   contexto, no un dato de la lista. Sustituye al .text-muted del tema, que es un
   gris que no pertenece a la paleta del cliente. */
.fv2-listado .card-header .cab-nota {
	font: 400 12.5px/1.45 var(--fv2-font-body);
	color: var(--fv2-outline) !important;
	max-width: 76ch;
}

.fv2-listado .fv2-filtros {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px 16px;
}

.fv2-listado .fv2-filtros-titulo {
	font: 600 11px/1.4 var(--fv2-font-body);
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--fv2-outline);
}

.fv2-listado .fv2-filtros .form-check {
	margin: 0;
	min-height: 0;
	display: flex;
	align-items: center;
	gap: 7px;
	padding-left: 0;
}

.fv2-listado .fv2-filtros .form-check-input {
	margin: 0;
	float: none;
	flex: 0 0 auto;
}

.fv2-listado .fv2-filtros .form-check-label {
	font: 500 12.5px/1.2 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
	cursor: pointer;
	margin: 0;
}

/* El recuento de lo que se está viendo. Va en tono secundario: es una nota al
   pie de la barra, no un dato de la tabla. */
.fv2-listado .fv2-filtros-count {
	font: 500 12.5px/1.2 var(--fv2-font-body);
	color: var(--fv2-outline);
	margin-left: auto;
}

/* En móvil el recuento no se empuja a la derecha: cae debajo, alineado con las
   casillas, porque el `margin-left:auto` en una barra envuelta lo dejaba solo
   en una línea propia y descolgado. */
@media (max-width: 575px) {
	.fv2-listado .fv2-filtros-count { margin-left: 0; }
}

/* =============================================================================
 * ASISTENTE DE DOMICILIACIONES (/asistente_domiciliaciones)
 * -----------------------------------------------------------------------------
 * Tres pasos que se recorren una vez al mes. El marcado sigue siendo el de
 * Bootstrap (tarjetas con borde de color e icono fa-2x) y el rediseño se hace
 * AQUÍ, por CSS, en lugar de cambiar las plantillas.
 *
 * ⚠️ El motivo no es pereza: este archivo SOLO se sirve a los clientes con
 * home_diseno="v2" (ver layout/head.tpl). Si las plantillas pintaran marcado
 * propio de v2 —.fv2-stat y compañía—, en demo y bellesartspalma esas cifras
 * saldrían sin una sola regla que las estilase. Con este enfoque, un cliente sin
 * v2 sigue viendo exactamente las tarjetas de Bootstrap de siempre.
 * ========================================================================== */

/* ---------------------------------------------------- Cifras del paso ------ */
/*
 * .asist-cifras es el gancho que ponen los tres pasos sobre su `row g-3`. Aquí
 * la fila se convierte en la tira de .fv2-stat que ya usan la portada y la ficha
 * del socio: fondo de acento suave, sin borde, número grande en la tipografía de
 * titulares. Se aplanan las dos capas de .card que hay dentro.
 */
.fv2 .asist-cifras { display: flex; flex-wrap: wrap; gap: 10px; }

/* Bootstrap reparte con `flex: 1 0 0%` y padding lateral; aquí manda el gap. */
.fv2 .asist-cifras > .col {
	flex: 1 1 140px;
	padding-left: 0;
	padding-right: 0;
}

.fv2 .asist-cifras .card {
	border: 0;
	background: var(--fv2-accent-soft);
	border-radius: var(--fv2-radius-sm);
	box-shadow: none;
	height: 100%;
}

.fv2 .asist-cifras .card-body {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 2px;
	padding: 12px 6px;
}

/*
 * El icono se va. En una tira de cuatro cifras, cuatro iconos de 2em compiten
 * con los números, que son el dato. .fv2-stat nunca los ha llevado.
 */
.fv2 .asist-cifras .card-body > i.fa,
.fv2 .asist-cifras .card-body > i[class*="fa-"] { display: none; }

/*
 * Longhands y no el shorthand `font:`. Es la regla de la casa: una variable
 * --fv2-* que no exista invalida la declaración `font:` ENTERA y se pierden de
 * golpe tamaño, peso e interlineado. Aquí el archivo solo se sirve con v2 y la
 * variable existe siempre, pero no merece la pena tener dos criterios.
 */
.fv2 .asist-cifras h3 {
	margin: 0;
	font-family: var(--fv2-font-head);
	font-weight: 700;
	font-size: 22px;
	line-height: 1.2;
	color: var(--fv2-accent-strong);
}

.fv2 .asist-cifras small {
	font-size: 11px;
	line-height: 1.3;
	color: var(--fv2-muted);
	text-transform: uppercase;
	letter-spacing: .03em;
	text-align: center;
}

/* El aviso conserva su color: es lo único de la tira que pide una acción. */
.fv2 .asist-cifras .border-danger  h3 { color: var(--fv2-error); }
.fv2 .asist-cifras .border-danger      { background: var(--fv2-error-container); }
.fv2 .asist-cifras .border-warning h3 { color: var(--fv2-warn); }

/* ---------------------------------------------------- Ayuda plegada -------- */
/*
 * <details> nativo, no el collapse de Bootstrap: no necesita jQuery (que en un
 * .tpl no existe todavía cuando corre su JS en línea) y funciona sin JS alguno.
 * Arranca cerrado siempre; no se recuerda el estado, así que no parpadea.
 */
.fv2 .asist-ayuda {
	border-top: 1px solid var(--fv2-divider);
	padding-top: 12px;
}

.fv2 .asist-ayuda-sum {
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-family: var(--fv2-font-body);
	font-weight: 600;
	font-size: 13px;
	color: var(--fv2-accent);
	list-style: none;              /* Firefox: quita el triángulo por defecto */
	user-select: none;
}

/* WebKit usa un pseudo-elemento propio para el triángulo */
.fv2 .asist-ayuda-sum::-webkit-details-marker { display: none; }

/* Chevron propio, que gira al abrir. Es el mismo gesto que el resto de v2. */
.fv2 .asist-ayuda-sum::after {
	content: "";
	width: 7px;
	height: 7px;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(45deg) translate(-2px, -2px);
	transition: transform .15s ease;
}
.fv2 .asist-ayuda[open] > .asist-ayuda-sum::after {
	transform: rotate(-135deg) translate(-2px, -2px);
}

.fv2 .asist-ayuda-sum:hover { color: var(--fv2-accent-strong); }

.fv2 .asist-ayuda-body {
	margin-top: 12px;
	font-size: 14px;
	line-height: 1.45;
	color: var(--fv2-on-surface-var);
}

.fv2 .asist-ayuda-body .card {
	border-radius: var(--fv2-radius-sm);
	box-shadow: none;
}

/* ---------------------------------------------------- Barra de pasos ------- */
/*
 * process-steps es un componente del tema clásico (core.css). No se sustituye
 * —funciona y es accesible— sino que se le cambia la tinta para que el paso
 * activo use el acento del cliente en lugar del azul de fábrica.
 */
.fv2 .process-steps .process-step-item.active,
.fv2 .process-steps .process-step-item.complete { color: var(--fv2-accent-strong); }

.fv2 .process-steps .process-step-item.active::before,
.fv2 .process-steps .process-step-item.complete::before {
	background-color: var(--fv2-accent);
	border-color: var(--fv2-accent);
}

/* ---------------------------------------------------- Barra de acciones ---- */
/*
 * La barra del asistente se queda pegada arriba mientras se recorre la tabla. En el
 * paso 2 son 149 filas: sin esto, para pulsar "Crear los bonos" había que bajar la
 * pantalla entera, y el botón que quedaba a mano arriba era "Siguiente", o sea el que
 * NO hace el trabajo.
 *
 * ⚠️ Tres cosas de las que depende que esto funcione, y ninguna se ve en el CSS:
 *
 *   1. La barra vive FUERA de la tarjeta de progreso. `sticky` pega el elemento dentro
 *      de su bloque contenedor, no de la ventana: metida en la tarjeta se despegaría en
 *      cuanto la tarjeta saliera de vista.
 *   2. NINGÚN ancestro puede tener `overflow` distinto de `visible`, o la barra pasa a
 *      pegarse a ese contenedor en silencio. Comprobado en su día: el `overflow:hidden`
 *      de style.css está en el `footer`, y ni core.css ni fisic-v2.css lo ponen en
 *      #wrapper ni en #middle.
 *   3. `top: 0` es correcto porque la cabecera del tema NO es fija: `header-sticky`
 *      está comentado en layout/base.tpl. Si algún día se activa, esto necesita el
 *      alto de esa cabecera.
 *
 * El fondo es obligatorio y opaco: sin él se ven las filas pasando por debajo.
 */
.fv2 .asist-barra {
	position: sticky;
	top: 0;
	z-index: 10;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	padding: 10px 0;
	margin-bottom: var(--fv2-gutter);
	background: var(--fv2-surface);
	border-bottom: 1px solid var(--fv2-divider);
}

/*
 * El ms-auto va en ESTE contenedor y no en un botón suelto. Antes lo llevaba el de
 * "Visualizar un Q19", así que era una utilidad la que partía la fila en dos y acababa
 * sentada junto al botón primario.
 */
.fv2 .asist-barra-acciones {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
}

/*
 * En pantalla estrecha se retira la utilidad. Con ella, la barra salta a dos líneas
 * justo donde menos alto sobra — y es lo único de la barra que no hace falta para
 * terminar el ciclo del mes.
 */
@media (max-width: 575px) {
	.fv2 .asist-barra-util { display: none; }
}

/* ---------------------------------------------------- Cobros heredados ---- */
/*
 * El aviso de un cobro que se va a hacer este mes porque asi se pago el mes pasado, pero
 * que NO esta en la ficha de domiciliacion de la persona. Vive dentro de la celda del
 * cliente, no como fila aparte: en el paso 1 sigue habiendo DataTables, y una fila sin
 * <select name="bono"> la escondería el filtro por bono y la ordenación la separaría de
 * su dueño.
 *
 * Sin v2 (demo, bellesartspalma) esto queda como texto llano: se lee igual, sin el tinte.
 */
.fv2 .asist-heredada {
	font-size: 12px;
	line-height: 1.4;
	padding: 8px 10px;
	border-radius: var(--fv2-radius-sm);
	border-left: 3px solid var(--fv2-accent);
	background: var(--fv2-accent-soft);
	color: var(--fv2-on-surface-var);
}

/*
 * La variante de bono RETIRADO no es un aviso mas: casi siempre significa que a esa
 * persona se le esta cobrando dos veces. Se tinta de error para que no se lea como una
 * sugerencia, y a proposito NO lleva boton de accion.
 */
.fv2 .asist-heredada--retirada {
	border-left-color: var(--fv2-error);
	background: var(--fv2-error-container);
	color: var(--fv2-on-error-cont);
}

.fv2 .asist-heredada .btn { margin-top: 6px; }

/* ---------------------------------------------------- El mes pasado ------- */
/* Lo que se cobro el mes pasado: contexto para ver si la ficha esta al dia. */
.fv2 .asist-mes-pasado { font-size: 11px; line-height: 1.4; color: var(--fv2-muted); }
.fv2 .asist-mes-pasado-tit { text-transform: uppercase; letter-spacing: .03em; }
/* Lo que NO esta en la ficha es lo que hay que mirar: se destaca. */
.fv2 .asist-mp--fuera { color: var(--fv2-warn); font-weight: 600; }

/* =============================================================================
 * PANTALLA DE AJUSTES (.fv2-ajustes)
 * -----------------------------------------------------------------------------
 * /opciones es la TERCERA pantalla de backoffice que entra en el rediseño, y la
 * primera que no es un listado sino un FORMULARIO: 49 ajustes repartidos en 8
 * grupos, con un solo botón de guardar para todos.
 *
 * Se escribe como MODIFICADOR de .fv2-listado, no como componente aparte: el
 * contenedor lleva las dos clases. De .fv2-listado hereda tal cual el ancho
 * completo, el panel .section, la barra de cabecera, la piel de los campos y las
 * pestañas en forma de chip. Aquí abajo sólo está lo que es propio de un
 * formulario de ajustes: la fila etiqueta/control y los distintivos de
 * diagnóstico que ve SLADMIN.
 *
 * La ESTRUCTURA de esas filas (display:flex, la columna de 340px, el salto en
 * móvil) NO está aquí sino en el <style> de opciones.tpl, y es deliberado: esa
 * pantalla tiene un markup único para los tres clientes de la flota, y demo y
 * bellesartspalma no cargan este archivo. Aquí va la PIEL; allí, la maqueta que
 * tiene que funcionar sin piel.
 * ========================================================================== */

/* Igual que .fv2.fv2-listado: doble clase para poder con el max-width de .fv2 */
.fv2.fv2-ajustes { max-width: none; }

@media (min-width: 1200px) {
	body.layout-ancho .fv2.fv2-ajustes,
	body.layout-full  .fv2.fv2-ajustes { max-width: none; }
}

/* ---------------------------------------------------- La fila de opción --- */
.fv2-ajustes .opc-fila {
	border-bottom: 1px solid var(--fv2-divider);
	padding: 12px 0;
}

.fv2-ajustes .opc-label {
	font: 600 14px/1.45 var(--fv2-font-body);
	color: var(--fv2-on-surface);
	margin: 0;
}

/* Un <label> con `for` es pulsable: se nota al pasar por encima. */
.fv2-ajustes label.opc-label { cursor: pointer; }

.fv2-ajustes .opc-desc {
	font: 400 12.5px/1.45 var(--fv2-font-body);
	color: var(--fv2-outline);
	opacity: 1;
	max-width: 62ch;
}

/* El valor en modo consulta: mismo peso que un campo, sin caja. */
.fv2-ajustes .opc-valor {
	font: 400 14px/1.45 var(--fv2-font-body);
	color: var(--fv2-on-surface);
}

.fv2-ajustes .opc-aviso-grupo {
	font: 500 13px/1.5 var(--fv2-font-body);
	color: var(--fv2-on-surface-var);
	background: var(--fv2-card-alt);
	border-radius: var(--fv2-radius-sm);
	padding: 10px 14px;
	margin: 4px 0 6px;
}

/* La chapa de "Novedad" reusa el par de acento, como las píldoras de la portada,
   en vez del rojo de Bootstrap: es una novedad, no un error. */
.fv2-ajustes .opc-novedad.badge {
	background: var(--fv2-accent-soft) !important;
	color: var(--fv2-accent) !important;
	font: 600 10px/1 var(--fv2-font-body);
	letter-spacing: .04em;
	text-transform: uppercase;
	padding: 5px 8px;
	vertical-align: 2px;
	margin-right: 6px;
}

/* ---------------------------------------------------- El interruptor ------ */
/*
 * OJO: el interruptor de esta aplicacion NO es el de Bootstrap. core.css:16588
 * redefine .form-switch por encima del de Bootstrap (core.css:1920) con un markup
 * propio —<input> + <i> hermano— y esconde el input con
 * `.form-switch > input { display: none !important }`. Lo que se ve es el <i>: la
 * pista es el propio elemento y la bolita su ::after.
 *
 * Aqui solo se retinta. El tema lo pinta gris #B5C1C7 apagado y #333 encendido, o
 * sea negro para todos los clientes; se reasigna al acento, igual que ya se hizo
 * con las casillas del listado de usuarios. (0,3,0) contra el (0,2,0) del tema, asi
 * que gana sin !important — salvo el display del input, que el tema marca
 * !important y no hay que tocar.
 */
.fv2-ajustes .form-switch > i {
	background: var(--fv2-border);
	border-color: var(--fv2-border);
	border-radius: 999px;
}

.fv2-ajustes .form-switch > i:after {
	border-radius: 50%;
	box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}

.fv2-ajustes .form-switch > input:checked + i {
	background: var(--fv2-accent);
	border-color: var(--fv2-accent);
}

.fv2-ajustes .form-switch > input:focus + i {
	background: var(--fv2-accent-soft);
	border-color: var(--fv2-accent);
}

.fv2-ajustes .form-switch > input:checked:focus + i {
	background: var(--fv2-accent);
}

/*
 * El tema no contempla el estado deshabilitado en su interruptor. Sin esto, una
 * opcion que el usuario NO puede tocar se ve exactamente igual que una que si, y
 * el unico aviso llega al pulsarla y no pasar nada.
 */
.fv2-ajustes .form-switch > input:disabled + i {
	opacity: .4;
	cursor: not-allowed;
}

.fv2-ajustes .form-switch > input:disabled ~ i,
.fv2-ajustes label.form-switch:has(> input:disabled) {
	cursor: not-allowed;
}

/* ---------------------------------------------------- Color y números ----- */
.fv2-ajustes .opc-color {
	height: 34px;
	padding: 3px;
	cursor: pointer;
}

.fv2-ajustes .opc-num { text-align: right; }

/*
 * La muestra de color en modo consulta. El código se lee encima del propio color
 * recortando el fondo al texto e invirtiéndolo, que es el truco que ya traía la
 * plantilla: así se lee tanto sobre un color claro como sobre uno oscuro, sin
 * tener que calcular la luminancia en PHP.
 */
.fv2-ajustes .opc-muestra {
	display: inline-block;
	min-width: 84px;
	text-align: center;
	padding: 5px 8px;
	border: 1px solid var(--fv2-border);
	border-radius: var(--fv2-radius-sm);
}

.fv2-ajustes .opc-muestra-txt {
	font: 600 11px/1.2 var(--fv2-font-body);
	background: inherit;
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	filter: invert(1) grayscale(1) contrast(10);
}

/* Módulos en modo consulta: sí/no como marca, no como texto */
.fv2-ajustes .opc-si { color: var(--fv2-ok); }
.fv2-ajustes .opc-no { color: var(--fv2-outline); }

/* ---------------------------------------------------- Diagnóstico --------- */
/* Todo lo de aquí abajo sólo lo ve SLADMIN. Va en el tono secundario y a tamaño
   pequeño porque es instrumental: no debe competir con el ajuste en sí. */
.fv2-ajustes .opc-clave {
	font: 400 10px/1.35 var(--fv2-font-body);
	color: var(--fv2-outline);
	opacity: 1;
	white-space: nowrap;
}

/*
 * ANCHO FIJO, Y NO ES COSMETICA: la columna de diagnostico mide lo que mida su
 * texto ([redsys_real] 35 o1 son 80px, [tpv_url_notificacion] 40 o12 son 107px), y
 * como es la ultima de una fila flex, esa diferencia EMPUJA la columna de campos.
 * Medido: los <input> de TPV empezaban en 1026, 1039, 1047, 1050 y 1053px, o sea
 * que la columna de campos bailaba 27px de una fila a la siguiente. Con un ancho
 * fijo, todos los campos quedan a plomo.
 *
 * 200px es lo que ocupaba el <td> de diagnostico de la tabla anterior. Si un texto
 * no cabe, se corta con puntos suspensivos: es informacion instrumental y el dato
 * completo sigue en el title.
 */
@media (min-width: 768px) {
	.fv2-ajustes .opc-diag {
		flex: 0 0 200px;
		justify-content: flex-end;
		overflow: hidden;
	}

	.fv2-ajustes .opc-diag .opc-clave {
		overflow: hidden;
		text-overflow: ellipsis;
	}
}

.fv2-ajustes .opc-sladmin { color: var(--fv2-error); font-weight: 600; }

.fv2-ajustes .opc-dep-ok     { color: var(--fv2-ok); }
.fv2-ajustes .opc-dep-falta  { color: var(--fv2-warn); }
.fv2-ajustes .opc-dep-choca  { color: var(--fv2-error); font-size: 11px; }

.fv2-ajustes .opc-dep-permisos {
	color: var(--fv2-accent);
	background: var(--fv2-accent-soft);
	border-radius: var(--fv2-radius-sm);
	padding: 5px;
	cursor: help;
}

/* ---------------------------------------------------- Cron ---------------- */
.fv2-ajustes .opc-cron-url {
	font-size: 12px;
	color: var(--fv2-on-surface-var);
	background: var(--fv2-card-alt);
	border-radius: var(--fv2-radius-sm);
	padding: 2px 6px;
}

/* ---------------------------------------------------- Estado vacío -------- */
.fv2-ajustes .opc-vacio {
	font: 400 13.5px/1.5 var(--fv2-font-body);
	color: var(--fv2-outline);
}

/* ---------------------------------------------------- Móvil --------------- */
/*
 * Por debajo de 768px el control ya cae a su propia línea (lo hace el <style> de
 * la plantilla). Lo que falta aquí es separar visualmente una opción de la
 * siguiente, porque etiqueta y control dejan de estar en la misma línea y el
 * bloque se lee como una lista corrida.
 */
@media (max-width: 767.98px) {
	.fv2-ajustes .opc-fila { padding: 14px 0; }
	.fv2-ajustes .opc-diag { padding-top: 4px; }
}
