/* ==========================================================================
   Orby Bots — Portal
   --------------------------------------------------------------------------
   Dirección «Marino» sobre un sistema de diseño con tokens.

   Todo el espaciado sale de una escala de base 4, la tipografía escala con
   clamp() entre móvil y escritorio, y los controles tienen tres tamaños
   fijos. Nada de valores sueltos: si un número no está en la escala, es un
   error, no una decisión.

   Cinco puntos de corte, todos justificados por el contenido:
     base   < 480   una o dos columnas, navegación inferior
     sm     480     tres columnas de indicadores
     md     768     raíl lateral, cuatro columnas
     lg     1024    barra lateral completa, seis columnas
     xl     1440    ancho máximo del contenido
   ========================================================================== */

/* ------------------------------------------------- Página del portal */

/* Se recorta con «clip» y no con «hidden»: hidden convierte al elemento en
   contenedor de desplazamiento y anula el comportamiento pegajoso de sus
   descendientes, que es lo que dejaba la barra lateral a medias. */
html:has(body.obb-pagina) { overflow-x: clip; }

body.obb-pagina {
	margin: 0;
	padding: 0;
	background: #f5f7fb;
	/* La página solo se desplaza en vertical: en móvil debe comportarse
	   como una aplicación, no como una web que se arrastra a los lados. */
	overflow-x: clip;
	max-width: 100%;
	min-height: 100dvh;
	display: flex;
	flex-direction: column;
}

body.obb-pagina.admin-bar { min-height: calc(100dvh - 32px); }

@media screen and (max-width: 782px) {
	body.obb-pagina.admin-bar { min-height: calc(100dvh - 46px); }
}

body.obb-pagina > :not(script):not(style):not(template):not(noscript):not(link):not(meta):not(iframe):not(svg),
body.obb-pagina .entry-content,
body.obb-pagina .elementor,
body.obb-pagina .elementor-section,
body.obb-pagina .elementor-section-wrap,
body.obb-pagina .elementor-container,
body.obb-pagina .elementor-column,
body.obb-pagina .elementor-column-wrap,
body.obb-pagina .elementor-widget-wrap,
body.obb-pagina .elementor-widget-shortcode,
body.obb-pagina .elementor-widget-container,
body.obb-pagina #obb-app {
	margin: 0;
	padding: 0;
	max-width: none;
	width: 100%;
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	min-height: 0;
}

body.obb-pagina script,
body.obb-pagina style,
body.obb-pagina template,
body.obb-pagina noscript,
body.obb-pagina link,
body.obb-pagina meta {
	display: none !important;
}

body.obb-pagina p:empty { display: none; }

/* ==========================================================================
   Tokens
   ========================================================================== */

.obb {

	/* --------------------------------------------------- Color */
	--navy: #02174b;
	--azul: #0a57eb;
	--azul-osc: #0a45c0;
	--azul-suave: #e4edfe;

	--verde: #087443;
	--verde-suave: #dcf5e9;
	--ambar: #8a6100;
	--ambar-suave: #fdf1cf;
	--rojo: #b3261e;
	--rojo-suave: #fce9e7;
	--morado: #4b3fc4;
	--morado-suave: #e9e7fb;

	/* Los tres niveles de tinta cumplen contraste AA sobre blanco: 17,1 el
	   principal, 6,1 el secundario y 4,9 el terciario. El terciario era
	   #8994a8 y daba 3,06, por debajo del mínimo de 4,5: los códigos, las
	   fechas y los textos de ayuda no se leían con el móvil al sol. */
	--tinta: #02174b;
	--tinta-2: #54627d;
	--tinta-3: #667287;

	/* Gris más claro, solo para lo que no es texto: bordes, líneas y
	   marcadores de posición. Nunca para contenido que haya que leer. */
	--apagado: #8994a8;

	--linea: #e3e9f2;
	--linea-2: #cfd8e6;
	--fondo: #f5f7fb;
	--fondo-2: #f2f5fa;
	--blanco: #fff;

	/* Superficies de interacción: el fondo de un campo, el gris de un
	   botón al pasar por encima, el marco de carga. */
	--campo: #fbfcfe;
	--realce: #fbfcff;
	--gris: #eef2f8;
	--gris-2: #e7ecf5;
	--hueso: #e9eef6;

	/* Sobre el azul marino de la navegación. */
	--sobre-navy: #93a3c4;

	/* Variantes fuertes de los botones de acción. */
	--naranja: #b8590a;
	--whatsapp: #1faa54;
	--rojo-osc: #8f1f18;

	/* Cada familia de color aporta su pareja para el degradado de los
	   indicadores: el tono base y su versión clara. */
	--azul-claro: #6ba3ff;
	--rojo-claro: #e0574e;
	--oro: #c98f10;
	--oro-claro: #edc158;
	--morado-claro: #8b82e8;
	--verde-claro: #35b57c;
	--gris-claro: #c2cad6;

	/* Colores de las acciones rápidas: cada tarjeta tiene el suyo. */
	--a1: #0a57eb;   --a1-suave: #e4edfe;
	--a2: #12a05f;   --a2-suave: #dcf5e9;
	--a3: #e0921a;   --a3-suave: #fdf1cf;
	--a4: #7b4fd8;   --a4-suave: #ece7fb;
	--a5: #0f9aa5;   --a5-suave: #dcf3f5;

	/* ------------------------------------ Espaciado, base 4 */
	--e-1: 4px;
	--e-2: 8px;
	--e-3: 12px;
	--e-4: 16px;
	--e-5: 24px;
	--e-6: 32px;
	--e-7: 40px;
	--e-8: 48px;
	--e-9: 64px;

	/* --------------------------------------------- Tipografía
	   Escala entre 390 px y 1440 px. Ningún campo de formulario baja
	   de 16 px: por debajo, Safari amplía la página al enfocarlo. */
	/* Por debajo de 12px la lectura se resiente, así que este es el suelo
	   y solo se usa en cabeceras de tabla y etiquetas de navegación. */
	--t-2xs: 11.5px;
	--t-xs: 12px;
	--t-sm: clamp(13px, 12.2px + 0.2vw, 14px);
	--t-base: clamp(15px, 14.2px + 0.2vw, 16px);
	--t-md: clamp(16px, 15.2px + 0.2vw, 17px);
	--t-lg: clamp(18px, 16.4px + 0.4vw, 20px);
	--t-xl: clamp(22px, 18.8px + 0.8vw, 26px);
	--t-2xl: clamp(25px, 19.4px + 1.4vw, 32px);
	--t-campo: 16px;

	/* ------------------------------------- Tamaños de control
	   Por encima del mínimo legal de 24 px de WCAG 2.2 y alineados con
	   las recomendaciones de Apple (44) y Material (48), porque quien
	   usa esto lo hace en la calle y a menudo con guantes. */
	--c-sm: 44px;
	--c-md: 50px;
	--c-lg: 56px;

	/* ------------------------------------------------- Formas */
	--r-card: 14px;
	--r-input: 10px;
	--r-pill: 999px;
	--sombra: 0 1px 3px rgba(2, 23, 75, .07), 0 8px 24px rgba(2, 23, 75, .05);

	/* ------------------------------------------------ Capas */
	--z-cabecera: 20;
	--z-nav: 30;
	--z-modal: 80;
	--z-aviso: 90;

	/* -------------------------------------- Áreas seguras */
	--seg-izq: env(safe-area-inset-left, 0px);
	--seg-der: env(safe-area-inset-right, 0px);
	--seg-abajo: env(safe-area-inset-bottom, 0px);

	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif;
	color: var(--tinta);
	font-size: var(--t-base);
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
}

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

/* ==========================================================================
   Aislamiento del tema
   --------------------------------------------------------------------------
   El portal vive dentro de un WordPress con tema y Elementor, que dan
   estilo a botones, enlaces y negritas. El reinicio de tipografía y caja
   usa :where() para no pesar más que los componentes: gana al tema, pero
   cada pieza sigue mandando sobre su propio aspecto.
   ========================================================================== */

.obb :where(button, input, select, textarea) {
	font-family: inherit;
	font-size: inherit;
	font-weight: inherit;
	line-height: inherit;
	letter-spacing: normal;
	text-transform: none;
	text-align: inherit;
	white-space: normal;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	box-shadow: none;
}

.obb button,
.obb button:hover,
.obb button:focus,
.obb button:active,
.obb button:visited {
	background-color: transparent;
	background-image: none;
	color: inherit;
	text-decoration: none;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
	-webkit-tap-highlight-color: transparent;
}

.obb :where(a),
.obb a:hover,
.obb a:focus,
.obb a:visited { text-decoration: none; }

.obb b,
.obb strong { color: inherit; }

.obb h1, .obb h2, .obb h3, .obb h4, .obb h5 {
	font-family: inherit;
	color: inherit;
	text-transform: none;
	letter-spacing: normal;
}

.obb :where(table) { border: 0; }
.obb :where(th, td) { border-color: var(--linea); }

.obb a { color: var(--azul-osc); }

/* ==========================================================================
   Iconos
   ========================================================================== */

.obb-ico {
	width: 20px;
	height: 20px;
	flex: 0 0 auto;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.7;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.obb-ico-sm { width: 17px; height: 17px; }
.obb-ico-lg { width: 24px; height: 24px; }

.obb-cargando {
	padding: var(--e-9) var(--e-5);
	text-align: center;
	color: var(--tinta-3);
}

/* ==========================================================================
   Acceso
   ========================================================================== */

.obb-login-wrap {
	flex: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--e-6) max(var(--e-4), var(--seg-izq)) var(--e-6) max(var(--e-4), var(--seg-der));
	background: var(--fondo);
}

.obb-login {
	width: 100%;
	max-width: 400px;
	background: var(--blanco);
	border-radius: 18px;
	box-shadow: var(--sombra);
	padding: var(--e-6) var(--e-5) var(--e-5);
}

.obb-login-marca { text-align: center; margin-bottom: var(--e-5); }

.obb-logo-iniciales {
	margin: 0 auto var(--e-3);
	border-radius: 26%;
	background: var(--navy);
	color: var(--blanco);
	font-weight: 700;
	letter-spacing: .5px;
	display: flex;
	align-items: center;
	justify-content: center;
}

.obb-logo-img { display: block; margin: 0 auto var(--e-3); height: auto; }

.obb-logo-defecto {
	margin: 0 auto var(--e-3);
	border-radius: 26%;
	background: var(--azul);
	color: var(--blanco);
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
}

.obb-logo-defecto .obb-ico { stroke-width: 1.9; }

.obb-icono-marca {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
}

.obb-login-marca .obb-icono-marca { margin: 0 auto var(--e-3); }

.obb-login-marca h1 { margin: 0; font-size: var(--t-xl); font-weight: 700; letter-spacing: -.01em; }
.obb-login-marca p { margin: var(--e-1) 0 0; color: var(--tinta-3); font-size: var(--t-sm); }
.obb-login-pie { margin: var(--e-4) 0 0; text-align: center; font-size: var(--t-sm); }
.obb-login-aviso { color: var(--rojo); font-size: var(--t-sm); text-align: center; }

.obb-sello {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--e-2);
	margin-top: var(--e-5);
	padding-top: var(--e-4);
	border-top: 1px solid var(--linea);
	color: var(--tinta-3);
	font-size: var(--t-xs);
}

.obb-sello svg { flex: 0 0 auto; }

/* ==========================================================================
   Formulario
   ========================================================================== */

.obb-campo { display: block; margin-bottom: var(--e-4); }

.obb-campo > span {
	display: block;
	font-size: var(--t-sm);
	font-weight: 650;
	color: var(--tinta-2);
	margin-bottom: var(--e-2);
}

.obb-campo input,
.obb-campo select,
.obb-campo textarea {
	display: block;
	width: 100%;
	/* Sin esto, iOS da a los campos de fecha un ancho mínimo propio que
	   se salta el contenedor y ensancha la página entera. */
	min-width: 0;
	max-width: 100%;
	padding: var(--e-3) var(--e-4);
	border: 1px solid var(--linea-2);
	border-radius: var(--r-input);
	/* 16 px exactos: por debajo, Safari amplía la página al enfocar. */
	font-size: var(--t-campo);
	font-family: inherit;
	color: var(--tinta);
	background: var(--campo);
	min-height: var(--c-md);
	-webkit-appearance: none;
	appearance: none;
}

.obb-campo textarea { min-height: 104px; resize: vertical; line-height: 1.5; }

.obb-campo input[type="date"],
.obb-campo input[type="datetime-local"],
.obb-campo input[type="time"] {
	-webkit-appearance: none;
	appearance: none;
	min-width: 0;
	width: 100%;
	text-align: left;
}

.obb-campo select {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2354627d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right var(--e-3) center;
	background-size: 18px;
	padding-right: var(--e-7);
}

.obb-campo input:focus,
.obb-campo select:focus,
.obb-campo textarea:focus {
	border-color: var(--azul);
	background: var(--blanco);
	box-shadow: 0 0 0 3px rgba(10, 87, 235, .15);
}

.obb-campo input:disabled { background: var(--gris); color: var(--tinta-3); }

/* Un campo con su acción al lado, como el teléfono con «Llamar».
   Va con el mismo peso que la regla de la etiqueta: si no, «.obb-campo >
   span» le impone display block y el botón cae debajo del campo. */
.obb-campo > .obb-campo-accion {
	display: flex;
	gap: var(--e-2);
	align-items: stretch;
	margin-bottom: 0;
	font-size: inherit;
	font-weight: inherit;
	color: inherit;
}

.obb-campo-accion input { flex: 1 1 auto; min-width: 0; }
.obb-campo-accion .obb-btn { flex: 0 0 auto; }

.obb-fila { display: flex; gap: var(--e-3); width: 100%; }
.obb-fila > * { flex: 1 1 0; min-width: 0; max-width: 100%; }

.obb-check {
	display: flex;
	align-items: center;
	gap: var(--e-3);
	margin: calc(var(--e-1) * -1) 0 var(--e-4);
	font-size: var(--t-base);
	color: var(--tinta-2);
	cursor: pointer;
	min-height: var(--c-sm);
}

.obb-check input { width: 20px; height: 20px; accent-color: var(--azul); }

.obb-ayuda {
	font-size: var(--t-sm);
	color: var(--tinta-3);
	line-height: 1.5;
	margin: calc(var(--e-2) * -1) 0 var(--e-3);
}

.obb-panel .obb-ayuda:last-child { margin: var(--e-3) 0 0; }

/* --------------------------------- Contraseña con botón de ver */

.obb-pass { position: relative; }
.obb-pass input { padding-right: var(--e-8); }

.obb-ver {
	position: absolute;
	right: var(--e-1);
	top: 50%;
	transform: translateY(-50%);
	width: var(--c-sm);
	height: var(--c-sm);
	border: 0;
	background: none;
	border-radius: 9px;
	color: var(--tinta-3);
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0;
}

.obb .obb-ver { background-color: transparent; color: var(--tinta-3); }
.obb .obb-ver:hover { color: var(--tinta-2); background-color: var(--gris); }
.obb-ver svg { width: 20px; height: 20px; display: block; }
.obb-ver .obb-ojo-off { display: none; }
.obb-ver[aria-pressed="true"] .obb-ojo-off { display: block; }
.obb-ver[aria-pressed="true"] .obb-ojo-on { display: none; }

/* ==========================================================================
   Botones
   ========================================================================== */

.obb-btn {
	border: 1px solid transparent;
	border-radius: var(--r-input);
	padding: var(--e-3) var(--e-5);
	min-height: var(--c-md);
	font-size: var(--t-base);
	font-weight: 650;
	background: var(--blanco);
	color: var(--tinta);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--e-2);
	text-decoration: none;
	transition: filter .15s, background .15s;
}

.obb-btn:active { filter: brightness(.94); }

@media (hover: hover) {
	.obb-btn:hover { filter: brightness(.96); }
}

.obb-btn:disabled { opacity: .5; cursor: not-allowed; filter: none; }
.obb-btn-bloque { display: flex; width: 100%; }

/* Botón secundario: 44 px, el mínimo recomendado por Apple. */
.obb-btn-sm {
	padding: var(--e-2) var(--e-3);
	min-height: var(--c-sm);
	font-size: var(--t-sm);
}

/* Acción principal en formularios largos. */
.obb-btn-lg { min-height: var(--c-lg); font-size: var(--t-md); }

/* El fondo y el color se repiten en los estados para que el tema no los
   sustituya al pasar el dedo o el ratón. */
.obb .obb-btn { background-color: var(--blanco); color: var(--tinta); }
.obb .obb-btn:hover, .obb .obb-btn:focus, .obb .obb-btn:active { background-color: var(--blanco); color: var(--tinta); }

.obb .obb-btn-primario,
.obb .obb-btn-primario:hover,
.obb .obb-btn-primario:focus,
.obb .obb-btn-primario:active { background-color: var(--azul); color: var(--blanco); }

/* --------------------------------- [P08-HF2] Acceso global «+Servicio»
 *
 * No trae colores ni tipografia propios: usa `obb-btn-primario` -el azul de
 * la marca- y `obb-btn-sm` -44 px, el minimo tactil-, para no abrir un
 * lenguaje visual nuevo.
 *
 * Aqui solo se declara como pieza: no se encoge y su rotulo no se parte en
 * dos lineas. Donde va en cada anchura se decide mas abajo.
 *
 * EL ROTULO VA EN CAJA MIXTA, Y ES UNA EXCEPCION DELIBERADA. [rev2]
 *
 * La regla «Mayusculas de interfaz» alcanza a `.obb-btn` y pintaria
 * «+SERVICIO». El rotulo pedido es exactamente «+Servicio», asi que se
 * revierte AQUI Y SOLO AQUI, sobre esta clase. El bloque global no se toca:
 * BUSCAR, GUARDAR y DESCARGAR PDF siguen en mayusculas.
 *
 * Se devuelve tambien el espaciado entre letras a su valor normal: el .03em
 * de aquella regla existe para que una palabra en caja alta no se lea como
 * un bloque, y en caja mixta solo separa de mas. */
.obb .obb-nuevo {
	flex: 0 0 auto;
	white-space: nowrap;
	text-transform: none;
	letter-spacing: normal;
}

/* En escritorio y tablet manda el de la cabecera; la zona de movil y su
   boton no existen. */
.obb-zona-nuevo,
.obb .obb-nuevo-zona { display: none; }

.obb .obb-btn-navy,
.obb .obb-btn-navy:hover,
.obb .obb-btn-navy:focus,
.obb .obb-btn-navy:active { background-color: var(--navy); color: var(--blanco); }

.obb .obb-btn-verde,
.obb .obb-btn-verde:hover,
.obb .obb-btn-verde:focus,
.obb .obb-btn-verde:active { background-color: var(--verde); color: var(--blanco); }

.obb .obb-btn-naranja,
.obb .obb-btn-naranja:hover,
.obb .obb-btn-naranja:focus,
.obb .obb-btn-naranja:active { background-color: var(--naranja); color: var(--blanco); }

.obb .obb-btn-wa,
.obb .obb-btn-wa:hover,
.obb .obb-btn-wa:focus,
.obb .obb-btn-wa:active { background-color: var(--whatsapp); color: var(--blanco); }

.obb .obb-btn-linea,
.obb .obb-btn-linea:hover,
.obb .obb-btn-linea:focus,
.obb .obb-btn-linea:active { background-color: var(--blanco); color: var(--tinta-2); border-color: var(--linea-2); }

/* ==========================================================================
   Estructura
   ========================================================================== */

.obb-app {
	background: var(--fondo);
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	max-width: 100%;
	min-width: 0;
	overflow-x: clip;
}

.obb-top {
	position: sticky;
	top: 0;
	z-index: var(--z-cabecera);
	display: flex;
	align-items: center;
	gap: var(--e-3);
	padding: var(--e-3) max(var(--e-4), var(--seg-der)) var(--e-3) max(var(--e-4), var(--seg-izq));
	background: var(--blanco);
	border-bottom: 1px solid var(--linea);
}

.obb-top h1 {
	margin: 0;
	font-size: var(--t-lg);
	font-weight: 700;
	letter-spacing: -.01em;
	flex: 0 1 auto;
	min-width: 0;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	/* Cuando no hay saludo al lado, empuja el botón de salir a la derecha. */
	margin-right: auto;
}

/* Separador entre el título de la pantalla y el saludo. */
.obb-top-sep {
	flex: 0 0 auto;
	width: 1px;
	align-self: stretch;
	margin: 2px 0;
	background: var(--linea-2);
}

.obb-top-saludo {
	flex: 1 1 auto;
	min-width: 0;
	line-height: 1.25;
}

.obb-top-saludo strong {
	display: block;
	font-size: var(--t-base);
	font-weight: 700;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.obb-top-saludo > span {
	display: block;
	font-size: var(--t-xs);
	color: var(--tinta-2);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.obb-top-saludo b { color: var(--rojo); }

.obb-atras,
.obb-salir {
	border: 0;
	background: none;
	color: var(--tinta-2);
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--c-sm);
	height: var(--c-sm);
	border-radius: var(--r-input);
	padding: 0;
	flex: 0 0 auto;
}

.obb .obb-atras,
.obb .obb-salir { background-color: transparent; color: var(--tinta-2); }

@media (hover: hover) {
	.obb .obb-atras:hover,
	.obb .obb-salir:hover { background-color: var(--gris); color: var(--tinta); }
}

.obb-vista {
	flex: 1 1 auto;
	min-width: 0;
	max-width: 100%;
	padding:
		var(--e-4)
		max(var(--e-4), var(--seg-der))
		calc(var(--e-9) + var(--e-6) + var(--seg-abajo))
		max(var(--e-4), var(--seg-izq));
}

/* ==========================================================================
   Indicadores
   --------------------------------------------------------------------------
   Barra de acento a la izquierda, icono en pastilla, separador vertical y
   cifra grande. La etiqueta va abajo, separada por una línea: así el ojo
   lee primero el número, que es lo que se viene a mirar.
   ========================================================================== */

/* Cada estado aporta su pareja de colores a la barra y a la pastilla. */
.obb .k-azul   { --acento: var(--azul);    --acento-2: var(--azul-claro); --tono: var(--azul-suave);   --tinta-tono: var(--azul); }
.obb .k-rojo   { --acento: var(--rojo);    --acento-2: var(--rojo-claro); --tono: var(--rojo-suave);   --tinta-tono: var(--rojo); }
.obb .k-ambar  { --acento: var(--oro);        --acento-2: var(--oro-claro); --tono: var(--ambar-suave);  --tinta-tono: var(--ambar); }
.obb .k-morado { --acento: var(--morado);  --acento-2: var(--morado-claro); --tono: var(--morado-suave); --tinta-tono: var(--morado); }
.obb .k-verde  { --acento: var(--verde);   --acento-2: var(--verde-claro); --tono: var(--verde-suave);  --tinta-tono: var(--verde); }
.obb .k-gris   { --acento: var(--tinta-3); --acento-2: var(--gris-claro); --tono: var(--gris);             --tinta-tono: var(--tinta-2); }

.obb-kpis {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--e-3);
	margin-bottom: var(--e-5);
	/* Separa el bloque de accesos del desglose por estados: son dos
	   cosas distintas y conviene que se lean como tales. */
	margin-top: var(--e-5);
	padding-top: var(--e-5);
	border-top: 1px solid var(--linea-2);
}

.obb-kpis > * { min-width: 0; }

.obb-kpi {
	position: relative;
	overflow: hidden;
	background: var(--blanco);
	border: 0;
	border-radius: var(--r-card);
	padding: var(--e-3) var(--e-3) 0 var(--e-4);
	box-shadow: var(--sombra);
	text-align: left;
	width: 100%;
	display: flex;
	flex-direction: column;
	min-height: 118px;
}

/* Barra de acento del borde izquierdo. */
.obb-kpi::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	width: 5px;
	background: linear-gradient(to bottom, var(--acento), var(--acento-2));
}

.obb .obb-kpi,
.obb .obb-kpi:hover,
.obb .obb-kpi:focus,
.obb .obb-kpi:active { background-color: var(--blanco); color: var(--tinta); }

@media (hover: hover) {
	.obb .obb-kpi:hover { background-color: var(--realce); }
}

.obb .obb-kpi.act,
.obb .obb-kpi.act:hover,
.obb .obb-kpi.act:focus { background-color: var(--azul-suave); }

.obb-kpi-fila {
	display: flex;
	align-items: center;
	gap: var(--e-3);
	flex: 1;
	padding-bottom: var(--e-3);
	min-width: 0;
}

.obb-kpi-ico {
	width: var(--c-sm);
	height: var(--c-sm);
	flex: 0 0 var(--c-sm);
	border-radius: 13px;
	background: var(--tono);
	color: var(--tinta-tono);
	display: flex;
	align-items: center;
	justify-content: center;
}

/* Separador vertical entre el icono y la cifra. */
.obb-kpi-n {
	flex: 1;
	min-width: 0;
	text-align: center;
	border-left: 1px solid var(--linea);
	padding-left: var(--e-2);
	font-size: var(--t-2xl);
	font-weight: 700;
	line-height: 1.05;
	letter-spacing: -.03em;
	color: var(--tinta);
	font-variant-numeric: tabular-nums;
	overflow: hidden;
	text-overflow: ellipsis;
}

.obb-kpi-t {
	display: block;
	border-top: 1px solid var(--linea);
	padding: var(--e-3) 0;
	text-align: center;
	font-size: var(--t-sm);
	font-weight: 700;
	color: var(--tinta);
	line-height: 1.2;
	overflow-wrap: break-word;
}

/* ---------------------------------- Cabecera: total y acceso directo */

.obb-cabecera {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: var(--e-3);
	/* Más aire entre filas: el círculo del icono asoma por encima. */
	row-gap: var(--e-6);
	align-items: stretch;
	margin-bottom: 0;
	padding-top: var(--e-5);
}

.obb-cabecera > * { min-width: 0; }
.obb-cabecera .obb-accion { margin-top: 0; }

/* El orden lo decide el tamaño de pantalla, no el marcado. En móvil y
   tablet el total va con Datos de la Empresa y el resto de accesos baja
   bajo su encabezado. */
.obb-cabecera .obb-kpi { order: 0; }
.obb-cabecera .o-5 { order: 1; }
.obb-cabecera-titulo { order: 2; }
.obb-cabecera .o-1 { order: 3; }
.obb-cabecera .o-2 { order: 4; }
.obb-cabecera .o-3 { order: 5; }
.obb-cabecera .o-4 { order: 6; }

.obb-cabecera-titulo {
	grid-column: 1 / -1;
	/* Compensa el hueco entre filas, que aquí sobra: el título ya separa. */
	margin: calc(var(--e-3) * -1) 0 calc(var(--e-4) * -1);
	font-size: var(--t-md);
	font-weight: 700;
}

/* El importe cobrado, como segunda línea de la etiqueta del total. */
.obb-total-importe {
	display: block;
	margin-top: var(--e-1);
	font-size: var(--t-xs);
	font-weight: 700;
	color: var(--verde);
	line-height: 1.3;
}

/* ==========================================================================
   Títulos y acciones rápidas
   ========================================================================== */

.obb-titulo {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--e-3);
	margin: var(--e-5) 0 var(--e-3);
}

.obb-titulo h3 { margin: 0; font-size: var(--t-md); font-weight: 700; }

.obb-titulo button {
	border: 0;
	background: none;
	color: var(--azul-osc);
	font-size: var(--t-sm);
	font-weight: 650;
	display: inline-flex;
	align-items: center;
	gap: var(--e-1);
	/* Zona de toque cómoda aunque el texto sea corto. */
	padding: var(--e-3) var(--e-1);
	margin: calc(var(--e-3) * -1) calc(var(--e-1) * -1);
	min-height: var(--c-sm);
}

.obb .obb-titulo button,
.obb .obb-titulo button:hover,
.obb .obb-titulo button:focus { background-color: transparent; color: var(--azul-osc); }

.obb-acciones {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--e-3);
	/* El icono asoma por encima del borde: hace falta hueco arriba. */
	padding-top: var(--e-5);
}

.obb-acciones > * { min-width: 0; }

/* Cada acción tiene su color propio. */
.obb .a-1 { --tinte: var(--a1); --tinte-suave: var(--a1-suave); }
.obb .a-2 { --tinte: var(--a2); --tinte-suave: var(--a2-suave); }
.obb .a-3 { --tinte: var(--a3); --tinte-suave: var(--a3-suave); }
.obb .a-4 { --tinte: var(--a4); --tinte-suave: var(--a4-suave); }
.obb .a-5 { --tinte: var(--a5); --tinte-suave: var(--a5-suave); }

.obb-accion {
	position: relative;
	/* Sin separación silábica: una palabra larga baja entera a la línea
	   siguiente en lugar de partirse con guion. «Registrar servicio» se
	   lee mal como «Registrar servi-cio». */
	hyphens: none;
	overflow-wrap: break-word;
	background: var(--blanco);
	border: 1.5px solid var(--tinte, var(--linea-2));
	border-radius: var(--r-card);
	/* El hueco superior deja sitio al círculo del icono, que asoma por
	   encima del borde y ocupa la mitad de su alto por fuera. */
	padding: 30px var(--e-3) var(--e-4);
	margin-top: var(--e-5);
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	min-height: 90px;
}

.obb .obb-accion,
.obb .obb-accion:hover,
.obb .obb-accion:focus,
.obb .obb-accion:active { background-color: var(--blanco); color: var(--tinta); }

@media (hover: hover) {
	.obb .obb-accion:hover { background-color: var(--tinte-suave); }
}

/* Círculo del icono, montado sobre el borde superior. */
.obb-accion-ico {
	position: absolute;
	top: 0;
	left: 50%;
	transform: translate(-50%, -50%);
	width: var(--c-sm);
	height: var(--c-sm);
	border-radius: 50%;
	background: var(--tinte, var(--azul));
	color: var(--blanco);
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 0 0 4px var(--blanco);
}

.obb-accion-ico .obb-ico { width: 21px; height: 21px; stroke-width: 2; }

.obb-accion-txt {
	display: block;
	font-size: var(--t-sm);
	font-weight: 700;
	color: var(--tinta);
	line-height: 1.3;
	text-align: center;
	hyphens: none;
	/* Reparte las palabras entre las dos líneas en lugar de dejar una
	   línea llena y otra con una sola palabra. */
	text-wrap: balance;
}

/* Barra de acento al pie. */
.obb-accion::after {
	content: "";
	position: absolute;
	left: 50%;
	/* Justo dentro del borde inferior, no encima de él. */
	bottom: 3px;
	transform: translateX(-50%);
	width: 42px;
	height: 4px;
	border-radius: var(--r-pill);
	background: var(--tinte, var(--azul));
}

/* ==========================================================================
   Tarjeta de servicio
   ========================================================================== */

.obb-lista { display: flex; flex-direction: column; gap: var(--e-3); }

.obb-tarjeta {
	background: var(--blanco);
	border-radius: var(--r-card);
	box-shadow: var(--sombra);
	overflow: hidden;
	border: 0;
	width: 100%;
	text-align: left;
	padding: 0;
	display: block;
}

.obb-tarjeta-cuerpo {
	display: flex;
	gap: var(--e-3);
	padding: var(--e-4);
	align-items: flex-start;
	width: 100%;
	text-align: left;
	border: 0;
}

.obb .obb-tarjeta-cuerpo,
.obb .obb-tarjeta-cuerpo:hover,
.obb .obb-tarjeta-cuerpo:focus,
.obb .obb-tarjeta-cuerpo:active { background-color: transparent; color: var(--tinta); }

@media (hover: hover) {
	.obb .obb-tarjeta-cuerpo:hover { background-color: var(--realce); }
}
.obb-tarjeta-cuerpo > span:last-child { flex: 0 0 auto; }

.obb-tarjeta-ico {
	width: var(--c-sm);
	height: var(--c-sm);
	flex: 0 0 var(--c-sm);
	border-radius: 12px;
	background: var(--azul-suave);
	color: var(--azul);
	display: flex;
	align-items: center;
	justify-content: center;
}

.obb-tarjeta-datos { flex: 1; min-width: 0; display: block; }

.obb-tarjeta-cliente { display: block; font-size: var(--t-md); font-weight: 700; margin-bottom: 2px; line-height: 1.3; }
.obb-tarjeta-dir { display: block; font-size: var(--t-sm); color: var(--tinta-2); margin-bottom: var(--e-2); line-height: 1.35; }

.obb-dato { display: flex; gap: var(--e-2); font-size: var(--t-sm); margin-bottom: 2px; line-height: 1.4; }
.obb-dato-k { color: var(--tinta-3); flex: 0 0 auto; }
.obb-dato-v { color: var(--tinta-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.obb-tarjeta-pie {
	display: flex;
	align-items: center;
	gap: var(--e-3);
	flex-wrap: wrap;
	padding: var(--e-3) var(--e-4);
	border-top: 1px solid var(--linea);
	font-size: var(--t-xs);
	color: var(--tinta-2);
}

.obb-tarjeta-pie small { color: var(--tinta-3); font-size: var(--t-xs); }
.obb-tarjeta-pie .obb-mono { color: var(--tinta-3); }

/* Rejilla en lugar de fila: a 320 px las tres acciones bajan a dos filas
   en vez de salirse de la pantalla. */
.obb-acciones-tarjeta {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
	gap: var(--e-2);
	padding: 0 var(--e-3) var(--e-3);
}

.obb-acciones-tarjeta > * { min-width: 0; }

.obb-economico {
	display: flex;
	flex-wrap: wrap;
	gap: var(--e-2) var(--e-4);
	padding: var(--e-3) var(--e-4);
	border-top: 1px solid var(--linea);
	font-size: var(--t-xs);
	color: var(--tinta-3);
}

.obb-economico b { display: block; color: var(--tinta); font-size: var(--t-sm); font-weight: 700; }
.obb-economico .obb-total b { color: var(--verde); }

/* ==========================================================================
   Pastillas de estado
   ========================================================================== */

.obb-badge {
	display: inline-flex;
	align-items: center;
	gap: var(--e-1);
	padding: 6px var(--e-3);
	border-radius: var(--r-pill);
	font-size: var(--t-xs);
	font-weight: 700;
	white-space: nowrap;
}

.obb-badge .obb-ico { width: 14px; height: 14px; }

.obb-badge-pendiente_asignar { background: var(--rojo-suave); color: var(--rojo); }
.obb-badge-asignado { background: var(--azul-suave); color: var(--azul-osc); }
.obb-badge-con_cita { background: var(--ambar-suave); color: var(--ambar); }
.obb-badge-ppto_enviado { background: var(--morado-suave); color: var(--morado); }
.obb-badge-cobrado { background: var(--verde-suave); color: var(--verde); }
.obb-badge-nulo { background: var(--gris); color: var(--tinta-2); }

/* [LOCAL-61] Estado operativo + espera de aceptación: DOS píldoras juntas.
   Desde el modelo de dos dimensiones un servicio puede estar COBRADO y a la
   vez esperando que el operario acepte, así que junto a la píldora de estado
   aparece un segundo aviso. Sin envolverlas, la medición en navegador (320,
   390, 820 y 1440 px) dio dos defectos: las cabeceras que reparten el espacio
   libre (.obb-ficha-cab con space-between, .obb-ac-cab con margin-left:auto)
   separaban las píldoras hasta 313 px, y la columna de estado del listado
   desbordaba. Envueltas son UN solo hijo y el contenedor las coloca como
   siempre. La envoltura NO se emite cuando no hay oferta: el caso normal
   sigue siendo exactamente la píldora suelta de antes. */
.obb-badge-par {
	display: inline-flex;
	align-items: center;
	gap: var(--e-2);
	min-width: 0;
	/* A 320 px la pareja no cabe en una línea -se midió: 310 px de píldoras
	   para 288 px de cabecera-, así que el aviso baja a la segunda línea en
	   vez de desbordar. Es la misma decisión que ya toma .obb-ac-cab. */
	flex-wrap: wrap;
	row-gap: var(--e-1);
	justify-content: center;
}

/* Aviso sin texto, para la columna estrecha del listado: solo el reloj, con
   el texto en `title` y `aria-label`. */
.obb-badge-solo-ico { padding: 6px; }

/* ==========================================================================
   Panel
   ========================================================================== */

.obb-panel {
	background: var(--blanco);
	border-radius: var(--r-card);
	box-shadow: var(--sombra);
	padding: var(--e-4);
	margin-bottom: var(--e-4);
	min-width: 0;
	max-width: 100%;
	overflow-wrap: break-word;
}

.obb-panel h3 { margin: 0 0 var(--e-4); font-size: var(--t-md); font-weight: 700; }

.obb-vacio { text-align: center; color: var(--tinta-3); padding: var(--e-7) var(--e-4); font-size: var(--t-base); }

.obb-logo-caja {
	display: flex;
	align-items: center;
	gap: var(--e-4);
	padding: var(--e-4);
	border: 1px dashed var(--linea-2);
	border-radius: var(--r-input);
	margin-bottom: var(--e-4);
}

.obb-logo-caja .obb-logo-img,
.obb-logo-caja .obb-logo-iniciales,
.obb-logo-caja .obb-logo-defecto { margin: 0; }

.obb-logo-caja > div:last-child { flex: 1; min-width: 0; }

/* ==========================================================================
   Pendientes de aceptar
   ========================================================================== */

.obb-pendientes {
	background: var(--blanco);
	border-radius: var(--r-card);
	box-shadow: var(--sombra);
	border-left: 4px solid var(--ambar);
	overflow: hidden;
	margin-bottom: var(--e-5);
}

.obb-pendientes-cab { padding: var(--e-4) var(--e-4) var(--e-3); }
.obb-pendientes-cab strong { display: block; font-size: var(--t-md); }
.obb-pendientes-cab span { font-size: var(--t-sm); color: var(--tinta-2); }

.obb-pendiente { padding: var(--e-3) var(--e-4); border-top: 1px solid var(--linea); }

.obb-pendiente-tipo {
	font-size: var(--t-sm);
	color: var(--tinta-2);
	margin-bottom: var(--e-1);
	display: flex;
	align-items: center;
	gap: var(--e-2);
}

.obb-pendiente-datos strong { display: block; font-size: var(--t-md); }
.obb-pendiente-dir { font-size: var(--t-sm); color: var(--tinta-2); margin-bottom: var(--e-1); }

.obb-pendiente-botones {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
	gap: var(--e-3);
	margin-top: var(--e-3);
}

.obb-pendiente-botones .obb-btn { min-height: var(--c-lg); }

/* ==========================================================================
   Filtros rápidos
   ========================================================================== */

.obb-rapidos {
	display: flex;
	gap: var(--e-2);
	margin-bottom: var(--e-4);
	overflow-x: auto;
	padding-bottom: 2px;
	scrollbar-width: none;
}

.obb-rapidos::-webkit-scrollbar { display: none; }

/*
 * [LOCAL-57 · CORRECCIÓN 5] Por debajo de 360 px los filtros BAJAN de
 * linea en vez de salirse.
 *
 * El contenedor era un carrusel horizontal con la barra de
 * desplazamiento oculta -`scrollbar-width: none`-, asi que a 340 y a
 * 320 px «Esta Semana» quedaba fuera de la pantalla y no habia ninguna
 * senal visible de que hubiera algo mas a la derecha. Se podia arrastrar,
 * pero nadie lo sabia.
 *
 * Aqui se desactiva el desplazamiento y se deja envolver. Los tres
 * botones quedan visibles y pulsables sin gestos ocultos.
 *
 * Solo por debajo de 360 px: en movil normal, tablet y escritorio los
 * tres caben en una linea y el comportamiento no cambia.
 */
@media (max-width: 359px) {

	.obb-rapidos {
		flex-wrap: wrap;
		overflow-x: visible;
		row-gap: var(--e-2);
	}

	/* Pueden encoger, pero nunca por debajo de lo que se lee. */
	.obb-rapido {
		flex: 1 1 auto;
		min-width: 0;
		padding-left: var(--e-3);
		padding-right: var(--e-3);
	}
}

.obb-rapido {
	flex: 0 0 auto;
	border: 1px solid var(--linea-2);
	background: var(--blanco);
	border-radius: var(--r-pill);
	padding: var(--e-3) var(--e-4);
	font-size: var(--t-sm);
	font-weight: 650;
	color: var(--tinta-2);
	min-height: var(--c-sm);
}

.obb .obb-rapido,
.obb .obb-rapido:hover,
.obb .obb-rapido:focus { background-color: var(--blanco); color: var(--tinta-2); }

.obb .obb-rapido.act,
.obb .obb-rapido.act:hover,
.obb .obb-rapido.act:focus { background-color: var(--navy); border-color: var(--navy); color: var(--blanco); }

/* ==========================================================================
   Ficha de solo lectura
   ========================================================================== */

.obb-ficha-fila { padding: var(--e-3) 0; border-bottom: 1px solid var(--linea); }

/* El teléfono comparte fila con su botón de llamar. */
.obb-ficha-tel {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--e-3);
	flex-wrap: wrap;
}

.obb-ficha-tel .obb-btn { flex: 0 0 auto; }
.obb-ficha-k { font-size: var(--t-sm); color: var(--tinta-3); margin-bottom: 2px; }
.obb-ficha-v { font-weight: 600; font-size: var(--t-base); }

/* ==========================================================================
   Selector de estado
   ========================================================================== */

.obb-estados {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--e-2);
	margin-bottom: var(--e-4);
}

.obb-estados > * { min-width: 0; }

.obb-estado-chip {
	background: var(--blanco);
	border: 1px solid var(--linea-2);
	border-radius: var(--r-input);
	padding: var(--e-4) var(--e-2);
	font-size: var(--t-base);
	font-weight: 650;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--e-2);
	color: var(--tinta);
	min-height: var(--c-lg);
}

.obb .obb-estado-chip,
.obb .obb-estado-chip:hover,
.obb .obb-estado-chip:focus { background-color: var(--blanco); color: var(--tinta); }

.obb .obb-estado-chip.act,
.obb .obb-estado-chip.act:hover,
.obb .obb-estado-chip.act:focus { background-color: var(--navy); color: var(--blanco); border-color: var(--navy); }

/* ==========================================================================
   Totales y saldos
   ========================================================================== */

.obb-totales {
	background: var(--fondo-2);
	border-radius: var(--r-input);
	padding: var(--e-3) var(--e-4);
	margin-bottom: var(--e-4);
}

.obb-totales div { display: flex; justify-content: space-between; font-size: var(--t-base); padding: var(--e-1) 0; color: var(--tinta-2); }

.obb-totales div:last-child {
	border-top: 1px solid var(--linea-2);
	margin-top: var(--e-1);
	padding-top: var(--e-2);
	font-weight: 700;
	color: var(--tinta);
	font-size: var(--t-md);
}

.obb-saldo {
	display: flex;
	flex-wrap: wrap;
	gap: var(--e-4);
	align-items: flex-end;
	justify-content: space-between;
	margin-top: var(--e-5);
	padding-top: var(--e-4);
	border-top: 1px solid var(--linea);
}

.obb-saldo-nota { font-size: var(--t-sm); color: var(--tinta-2); flex: 1; min-width: 190px; }

.obb-saldo-caja {
	border: 2px solid var(--navy);
	border-radius: var(--r-card);
	padding: var(--e-3) var(--e-5);
	text-align: right;
	min-width: 230px;
}

.obb-saldo-caja span {
	display: block;
	font-size: var(--t-2xs);
	letter-spacing: .07em;
	text-transform: uppercase;
	color: var(--tinta-3);
	font-weight: 650;
}

.obb-saldo-caja b { display: block; font-size: var(--t-2xl); font-weight: 700; letter-spacing: -.02em; margin: var(--e-1) 0; }
.obb-saldo-caja em { font-style: normal; font-size: var(--t-sm); color: var(--tinta-2); }

.obb-cuenta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--e-3);
	align-items: center;
	justify-content: space-between;
	padding: var(--e-3) 0;
	border-bottom: 1px solid var(--linea);
}

.obb-cuenta:last-child { border-bottom: 0; }
.obb-cuenta-datos { flex: 1; min-width: 200px; }
.obb-cuenta-datos strong { font-size: var(--t-md); }
.obb-cuenta-saldo { display: flex; align-items: center; gap: var(--e-3); }
.obb-cuenta-saldo b { font-size: var(--t-lg); font-weight: 700; }

/* ==========================================================================
   Fichas de registro
   ========================================================================== */

.obb-registros { display: flex; flex-direction: column; gap: var(--e-2); }

.obb-registro {
	border: 1px solid var(--linea);
	border-radius: var(--r-input);
	padding: var(--e-3);
	min-width: 0;
}

.obb-registro.inact { opacity: .55; }

.obb-registro-cab {
	display: flex;
	gap: var(--e-3);
	align-items: flex-start;
	justify-content: space-between;
	flex-wrap: wrap;
}

.obb-registro-id { min-width: 0; flex: 1; }

.obb-registro-id strong {
	display: inline-flex;
	align-items: center;
	gap: var(--e-2);
	font-size: var(--t-md);
	margin-right: var(--e-2);
}

.obb-registro-id .obb-mono { color: var(--tinta-3); margin-top: 2px; }

.obb-registro-tel {
	display: inline-flex;
	align-items: center;
	gap: var(--e-2);
	font-size: var(--t-sm);
	color: var(--azul-osc);
	flex: 0 0 auto;
	white-space: nowrap;
	min-height: var(--c-sm);
	padding: 0 var(--e-1);
}

.obb-dim { color: var(--tinta-3); font-size: var(--t-sm); }

.obb-registro-pct {
	display: flex;
	align-items: flex-end;
	gap: var(--e-3);
	flex-wrap: wrap;
	margin-top: var(--e-3);
	padding-top: var(--e-3);
	border-top: 1px solid var(--linea);
}

/* La etiqueta va encima del campo, no a su lado: en una ficha estrecha
   compiten por el mismo sitio y acaban solapándose. */
.obb-registro-pct label {
	display: flex;
	flex-direction: column;
	gap: var(--e-1);
	flex: 0 0 auto;
	font-size: var(--t-xs);
	color: var(--tinta-2);
	font-weight: 650;
}

.obb-registro-pct .obb-pct { margin: 0; }
.obb-registro-pct .obb-pct-resto { margin: 0 0 var(--e-3); flex: 1 1 auto; min-width: 90px; }
.obb-registro-pct .obb-btn { flex: 0 0 auto; }

.obb-registro-acciones {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
	gap: var(--e-2);
	margin-top: var(--e-3);
}

.obb-pct {
	width: 88px;
	padding: var(--e-2) var(--e-3);
	border: 1px solid var(--linea-2);
	border-radius: 9px;
	/* 16 px: por debajo, Safari amplía la página al enfocar. */
	font-size: var(--t-campo);
	font-family: inherit;
	background: var(--campo);
	min-height: var(--c-sm);
}

.obb-pct-resto { display: block; font-size: var(--t-2xs); color: var(--tinta-3); margin-top: var(--e-1); }

/* ==========================================================================
   Navegación
   ========================================================================== */

.obb-nav {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: var(--z-nav);
	display: flex;
	background: var(--navy);
	padding:
		var(--e-2)
		max(0px, var(--seg-der))
		max(var(--e-2), var(--seg-abajo))
		max(0px, var(--seg-izq));
	transition: transform .2s ease;
}

/*
 * El envoltorio existe para que en escritorio la columna azul se estire
 * mientras el menú se queda pegado arriba. En móvil no estorba: se
 * comporta como la fila que era, con los botones repartidos.
 */
.obb-nav-interior {
	display: flex;
	flex: 1 1 auto;
	min-width: 0;
}

/* Con el teclado abierto la barra se aparta: en iOS sube con él y tapa
   el campo que se está rellenando. */
.obb-app.obb-teclado .obb-nav { transform: translateY(100%); }

.obb-nav button {
	flex: 1;
	border: 0;
	background: none;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--e-1);
	font-size: var(--t-2xs);
	font-weight: 600;
	color: var(--sobre-navy);
	padding: var(--e-2) var(--e-1);
	min-height: var(--c-sm);
}

.obb .obb-nav button,
.obb .obb-nav button:hover,
.obb .obb-nav button:focus { background-color: transparent; color: var(--sobre-navy); }

.obb .obb-nav button.act,
.obb .obb-nav button.act:hover,
.obb .obb-nav button.act:focus { color: var(--blanco); }

.obb-nav-marca,
.obb-nav-pie { display: none; }

/* ==========================================================================
   Avisos y notificaciones
   ========================================================================== */

.obb-alerta {
	padding: var(--e-3) var(--e-4);
	border-radius: var(--r-input);
	font-size: var(--t-sm);
	margin-bottom: var(--e-4);
	line-height: 1.5;
}

.obb-alerta-error { background: var(--rojo-suave); color: var(--rojo-osc); }

/* Aviso que se queda hasta que el usuario lo cierra o lo resuelve. */
.obb-aviso-fijo {
	display: flex;
	align-items: flex-start;
	gap: var(--e-3);
	border-left: 4px solid var(--rojo);
}

.obb-aviso-fijo > span { flex: 1; min-width: 0; }
.obb-aviso-fijo .obb-ico { flex: 0 0 auto; margin-top: 2px; }

.obb .obb-aviso-fijo button {
	flex: 0 0 auto;
	color: inherit;
	opacity: .6;
	padding: 0;
	background: transparent;
}

.obb .obb-aviso-fijo button:hover { opacity: 1; }
.obb-alerta-ok { background: var(--verde-suave); color: var(--verde); }
.obb-alerta-aviso { background: var(--ambar-suave); color: var(--ambar); }

.obb-toast {
	position: fixed;
	left: 50%;
	bottom: calc(var(--e-9) + var(--e-5) + var(--seg-abajo));
	transform: translateX(-50%);
	z-index: var(--z-aviso);
	background: var(--navy);
	color: var(--blanco);
	padding: var(--e-3) var(--e-5);
	border-radius: var(--r-pill);
	font-size: var(--t-base);
	box-shadow: 0 8px 28px rgba(2, 23, 75, .3);
	max-width: 90vw;
}

.obb-toast.err { background: var(--rojo); }

/* ==========================================================================
   Marco de carga
   ========================================================================== */

.obb-esqueleto {
	background: var(--blanco);
	border-radius: var(--r-card);
	box-shadow: var(--sombra);
	padding: var(--e-4);
	display: flex;
	gap: var(--e-3);
	align-items: flex-start;
}

.obb-esq-ico {
	width: var(--c-sm);
	height: var(--c-sm);
	flex: 0 0 var(--c-sm);
	border-radius: 12px;
	background: var(--hueso);
	animation: obb-latir 1.3s ease-in-out infinite;
}

.obb-esq-txt { flex: 1; display: flex; flex-direction: column; gap: var(--e-2); padding-top: var(--e-1); }

.obb-esq-txt span {
	display: block;
	height: 12px;
	border-radius: 6px;
	background: var(--hueso);
	animation: obb-latir 1.3s ease-in-out infinite;
}

.obb-esq-txt span:nth-child(2) { animation-delay: .12s; }
.obb-esq-txt span:nth-child(3) { animation-delay: .24s; }

@keyframes obb-latir {
	0%, 100% { opacity: 1; }
	50% { opacity: .45; }
}

/* ==========================================================================
   Tablas
   ========================================================================== */

/* La tabla se desplaza dentro de su caja, nunca arrastra la página. El
   degradado del borde avisa de que hay más columnas a la derecha. */
.obb-tabla-caja {
	width: 100%;
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	background:
		linear-gradient(to right, var(--blanco) 30%, rgba(255, 255, 255, 0)),
		linear-gradient(to right, rgba(255, 255, 255, 0), var(--blanco) 70%) 100% 0,
		radial-gradient(farthest-side at 0 50%, rgba(2, 23, 75, .14), transparent),
		radial-gradient(farthest-side at 100% 50%, rgba(2, 23, 75, .14), transparent) 100% 0;
	background-repeat: no-repeat;
	background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
	background-attachment: local, local, scroll, scroll;
}

.obb-tabla { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }

.obb-tabla th {
	text-align: left;
	font-size: var(--t-2xs);
	text-transform: uppercase;
	letter-spacing: .05em;
	color: var(--tinta-3);
	padding: var(--e-3);
	border-bottom: 1px solid var(--linea);
	font-weight: 700;
	background: var(--fondo-2);
	white-space: nowrap;
}

.obb-tabla td { padding: var(--e-3); border-bottom: 1px solid var(--linea); }
.obb-tabla tr.inact { opacity: .5; }
.obb-mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--t-xs); }

/* ==========================================================================
   Pestañas
   ========================================================================== */

.obb-tabs {
	display: flex;
	gap: var(--e-1);
	background: var(--gris-2);
	padding: var(--e-1);
	border-radius: var(--r-input);
	margin-bottom: var(--e-4);
}

.obb-tabs button {
	flex: 1 1 0;
	min-width: 0;
	border: 0;
	background: none;
	padding: var(--e-3) var(--e-2);
	border-radius: var(--e-2);
	font-size: var(--t-sm);
	font-weight: 650;
	color: var(--tinta-2);
	min-height: var(--c-sm);
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--e-2);
	overflow: hidden;
	text-overflow: ellipsis;
}

.obb .obb-tabs button,
.obb .obb-tabs button:hover,
.obb .obb-tabs button:focus { background-color: transparent; color: var(--tinta-2); }

.obb .obb-tabs button.act,
.obb .obb-tabs button.act:hover,
.obb .obb-tabs button.act:focus { background-color: var(--azul); color: var(--blanco); }

/* En pantallas muy estrechas el icono cede su sitio al texto. */
@media (max-width: 399px) {
	.obb-tabs button .obb-ico { display: none; }
	.obb-tabs button { padding-left: var(--e-1); padding-right: var(--e-1); font-size: var(--t-xs); }
}

.obb-linea-acciones { display: flex; gap: var(--e-2); flex-wrap: wrap; }

/* ==========================================================================
   Modal
   ========================================================================== */

.obb-modal-fondo {
	position: fixed;
	/*
	 * [LOCAL-48] `row` explicito. El fondo cuelga del body, y la regla
	 * de `body.obb-pagina > :not(script)` le imponia `flex-direction:
	 * column`. Eso invertia los ejes: `justify-content: center` centraba
	 * en vertical y `align-items: flex-end` empujaba el modal al borde
	 * DERECHO en vez de al inferior. Se veia en tablet.
	 */
	flex-direction: row;
	inset: 0;
	z-index: var(--z-modal);
	background: rgba(2, 23, 75, .5);
	display: flex;
	align-items: flex-end;
	justify-content: center;
	padding: 0;
}

.obb-modal {
	background: var(--blanco);
	width: 100%;
	max-width: 540px;
	border-radius: 20px 20px 0 0;
	padding: var(--e-5) max(var(--e-5), var(--seg-der)) calc(var(--e-5) + var(--seg-abajo)) max(var(--e-5), var(--seg-izq));
	/* dvh y no vh: con el teclado abierto, vh se calcula sobre la altura
	   completa y los botones quedan fuera de alcance. */
	max-height: 90dvh;
	overflow-y: auto;
}

.obb-modal h3 { margin: 0 0 var(--e-3); font-size: var(--t-lg); font-weight: 700; }

/* ==========================================================================
   sm · 480 px — el móvil grande deja de desperdiciar ancho
   ========================================================================== */

@media (min-width: 480px) {
	.obb-kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.obb-cabecera { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.obb-acciones { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.obb-estados { grid-template-columns: repeat(4, minmax(0, 1fr)); }
	.obb-vista { padding-left: max(var(--e-5), var(--seg-izq)); padding-right: max(var(--e-5), var(--seg-der)); }
	.obb-top { padding-left: max(var(--e-5), var(--seg-izq)); padding-right: max(var(--e-5), var(--seg-der)); }
}

/* ==========================================================================
   [P08-HF2 · rev2] «+Servicio» en móvil — ZONA RESERVADA, no acción flotante
   --------------------------------------------------------------------------
   LO QUE SE CORRIGE Y POR QUÉ.

   La revisión 1 anclaba el botón con `position: fixed` sobre el contenido.
   Medido a 390 y 430 px, al desplazar tapaba el nombre y la dirección de una
   tarjeta: 102 × 44 px sobre la cabecera de una ficha plegada. Eso no se
   arregla con márgenes, porque con el desplazamiento de PÁGINA cualquier
   elemento fijo tiene contenido pasando por detrás, siempre.

   LA SOLUCIÓN ES ESTRUCTURAL: hasta 767 px la aplicación deja de ser una
   página que se arrastra y pasa a ser tres franjas apiladas que ocupan
   exactamente la ventana:

       ┌──────────────────────────────┐
       │ cabecera                     │  alto propio
       ├──────────────────────────────┤
       │ CONTENIDO  ↕ se desplaza     │  ocupa lo que sobra · overflow-y
       ├──────────────────────────────┤
       │ [+Servicio]                  │  zona reservada · alto propio
       ├──────────────────────────────┤
       │ Inicio Servicios Usuarios …  │  navegación · alto propio
       └──────────────────────────────┘

   El desplazamiento ya NO es el de la página: es el de `.obb-vista`, cuya
   caja TERMINA donde empieza la zona reservada. Por eso ninguna tarjeta
   puede pasar por detrás del botón — no es que se evite, es que no hay
   sitio por donde pasar.

   `.obb-nav` deja de ser `fixed` y entra en el flujo como última franja; el
   orden lo da `order`, porque en el marcado la navegación va primero.

   POR QUÉ ESTO NO ROMPE NADA MÁS, comprobado antes de escribirlo:
     · el producto no lee `window.scrollY` ni llama a `window.scrollTo`: lo
       único que usa es `scrollIntoView`, que funciona igual dentro de un
       contenedor con desplazamiento propio;
     · ninguna batería certificada desplaza la página;
     · los elementos `sticky` de Porcentajes —la cabecera de la matriz y la
       barra de guardado— se pegaban al desplazamiento de la página y ahora
       se pegan al de `.obb-vista`, que ocupa el mismo hueco visual.

   La cadena de `min-height: 0` es obligatoria: sin ella un hijo flexible no
   puede encogerse por debajo de su contenido y la franja del contenido
   empujaría a las de abajo fuera de la ventana.
   ========================================================================== */

@media (max-width: 767px) {

	/* --- las tres franjas ------------------------------------------------ */

	/*
	 * ==================================================================
	 * [P08-HF3] EL ARMAZON SE ANCLA AL VIEWPORT, NO AL DOCUMENTO
	 * ==================================================================
	 *
	 * HF2 rev2 resolvio el solape sacando `.obb-nav` de `position: fixed`
	 * y metiendola en el flujo flexible, para que `.obb-vista` TERMINARA
	 * donde empieza la franja. Eso quito el solape -y con el, el anclaje
	 * de las franjas a la pantalla-. Desde entonces su posicion la decidia
	 * la caja del armazon, y la caja del armazon era:
	 *
	 *     body.obb-pagina { height: 100dvh; }
	 *
	 * `dvh` es una unidad REACTIVA: su valor cambia cada vez que el
	 * navegador movil muestra u oculta su barra de direcciones. MEDIDO en
	 * el banco: al reducir el viewport 60 px, `nav.bottom` pasa de 844 a
	 * 784. La franja se mueve EXACTAMENTE la altura del chrome, en cada
	 * toggle. Con `dvh` la variacion de 0 px es imposible por
	 * construccion.
	 *
	 * Y habia un segundo cabo: `overscroll-behavior` no aparecia ni una
	 * vez en toda la hoja, y en `html`/`body` solo estaba restringido el
	 * eje X. Asi que al llegar `.obb-vista` a su borde superior el gesto
	 * ENCADENABA al documento, que en un telefono es justo lo que hace
	 * reaparecer la barra del navegador. El gesto de subir era el
	 * disparador del cambio de `dvh`. De ahi que el defecto apareciera
	 * SOLO subiendo.
	 *
	 * Lo que NO era la causa, medido: el desplazamiento interno de
	 * `.obb-vista`. Con el viewport quieto, `nav.bottom` no se mueve ni un
	 * pixel a 0/25/50/75/100 % ni en la vuelta a 0, en los cuatro paneles.
	 *
	 * ------------------------------------------------------------------
	 * LA SOLUCION: anclar el ARMAZON, y dejar las franjas en su flujo.
	 * ------------------------------------------------------------------
	 *
	 * `position: fixed` + `inset: 0` da la caja del VIEWPORT sin usar
	 * ninguna unidad reactiva, y el navegador mantiene los elementos
	 * fijos pegados a la pantalla mientras su chrome entra y sale: es
	 * precisamente la propiedad por la que un pie `fixed` funciona en
	 * movil.
	 *
	 * Y como la navegacion y la zona del boton SIGUEN siendo hermanos
	 * flexibles dentro del armazon, `.obb-vista` sigue terminando donde
	 * empieza la franja. La garantia de HF2 -que ninguna tarjeta pasa por
	 * detras- se conserva ESTRUCTURALMENTE, no con `z-index`.
	 *
	 * Comprobado que es viable: la cadena de ancestros de `.obb-app` es
	 * `html -> body -> #obb-app -> .obb-app`, sin un solo `transform`,
	 * `filter`, `contain` ni `perspective`. Cualquiera de los cuatro
	 * convertiria a ese ancestro en bloque contenedor y el `fixed` dejaria
	 * de referirse al viewport. Es lo primero que hay que mirar si esto
	 * se comporta distinto bajo otro tema.
	 */

	/*
	 * 1 · El documento NO se desplaza.
	 *
	 * `clip` y no `hidden` a proposito: `hidden` convierte al elemento en
	 * contenedor de desplazamiento y anularia el comportamiento pegajoso
	 * de los `sticky` que hay dentro -la cabecera de la matriz de
	 * Porcentajes y su barra de guardado-. `clip` impide el
	 * desplazamiento sin crear contenedor.
	 *
	 * Y el alto desaparece, no pasa a `100%`.
	 *
	 * MEDIDO: con `height: 100%` el documento quedaba 46 px desplazable.
	 * WordPress pone `margin-top: 46px` en el `html` para dejar sitio a su
	 * barra de administracion, asi que un `html` al 100 % del viewport MAS
	 * ese margen suman 46 px de mas. Con el armazon ya anclado al
	 * viewport, ningun alto del `html` ni del `body` hace falta: lo unico
	 * que se les pide es NO DESPLAZARSE.
	 */
	html:has(body.obb-pagina) { overflow: clip; overscroll-behavior: none; }

	body.obb-pagina {
		overflow: clip;
		overscroll-behavior: none;
	}

	/*
	 * 2 · El armazon, anclado al viewport.
	 *
	 * La compensacion de la barra de administracion de WordPress hay que
	 * declararla AQUI: un elemento fijo cuelga del viewport, asi que el
	 * `margin-top: 46px` que WordPress pone en el `html` no le llega y sin
	 * esto el armazon quedaria por DEBAJO de la barra.
	 */
	.obb-app {
		position: fixed;
		inset: 0;
		min-height: 0;
	}

	body.obb-pagina.admin-bar .obb-app { top: 46px; }

	/*
	 * 3 · Con el TECLADO abierto si hay que seguir al viewport visual.
	 *
	 * Un elemento fijo se dimensiona con el viewport de maquetacion, que
	 * el teclado software no encoge; `dvh` si lo sigue. Aqui `dvh` es lo
	 * correcto, y es el unico estado en el que se usa. Las dos franjas se
	 * retiran igual que en HF2 -la regla esta mas abajo-, asi que el campo
	 * que se rellena recupera ese alto.
	 */
	.obb-app.obb-teclado {
		bottom: auto;
		height: 100dvh;
	}

	body.obb-pagina.admin-bar .obb-app.obb-teclado { height: calc(100dvh - 46px); }

	.obb-principal {
		order: 1;
		flex: 1 1 auto;
		min-height: 0;
		display: flex;
		flex-direction: column;
	}

	.obb-vista {
		flex: 1 1 auto;
		min-height: 0;
		overflow-y: auto;
		-webkit-overflow-scrolling: touch;
		/*
		 * [P08-HF3] EL GESTO NO ENCADENA AL DOCUMENTO.
		 *
		 * Sin esto, al llegar al borde -arriba o abajo- el desplazamiento
		 * se propaga al documento, y en un telefono eso hace reaparecer la
		 * barra del navegador y dispara el recalculo que movia las
		 * franjas. Es el disparador del defecto que corrige HF3.
		 *
		 * `contain` y no `none`: corta la propagacion, que es el defecto,
		 * pero deja el rebote local de la plataforma, que no molesta a
		 * nadie.
		 */
		overscroll-behavior: contain;
		/* Ya no hace falta reservar el alto del botón ni el de la barra: las
		   dos están FUERA de esta caja. Solo queda el respiro de siempre. */
		padding-bottom: var(--e-6);
	}

	.obb-zona-nuevo {
		flex: 0 0 auto;
		display: flex;
		align-items: center;
		padding:
			var(--e-2)
			max(var(--e-4), var(--seg-der))
			var(--e-2)
			max(var(--e-4), var(--seg-izq));
		background: var(--fondo);
		border-top: 1px solid var(--linea);
	}

	.obb .obb-nuevo-zona { display: inline-flex; }
	.obb .obb-nuevo-cab  { display: none; }

	.obb-nav {
		position: static;
		order: 2;
		flex: 0 0 auto;
		transition: none;
	}

	/* Con el teclado abierto la navegación se apartaba con un `transform`.
	   Ahora que está en el flujo, apartarla así dejaría su hueco vacío: se
	   retira de verdad, y el contenido recupera ese alto. La zona del botón
	   se va con ella, o quedaría flotando sobre el campo que se rellena. */
	.obb-app.obb-teclado .obb-nav,
	.obb-app.obb-teclado .obb-zona-nuevo { display: none; }
}

/* ==========================================================================
   md · 768 px — raíl lateral
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

	.obb-app { display: grid; grid-template-columns: 96px 1fr; align-items: stretch; }

	/*
	 * La barra ocupa toda la columna, no solo la altura de la ventana. Con
	 * «align-self: start» se quedaba a la altura del contenido visible y
	 * al bajar en una lista larga dejaba un hueco blanco a la izquierda.
	 *
	 * Estirando la columna y pegando el contenido por dentro, el azul
	 * llega siempre hasta abajo y los botones siguen a la vista.
	 */
	.obb-nav {
		position: static;
		min-height: 100dvh;
		flex-direction: column;
		padding: 0;
		transform: none;
	}

	.obb-nav-interior {
		position: sticky;
		top: 0;
		display: flex;
		flex-direction: column;
		gap: var(--e-1);
		padding: var(--e-4) var(--e-2);
		max-height: 100dvh;
		overflow-y: auto;
	}

	.obb-app.obb-teclado .obb-nav { transform: none; }

	.obb-nav button { flex: 0 0 auto; border-radius: var(--r-input); padding: var(--e-3) var(--e-1); }

	.obb .obb-nav button.act,
	.obb .obb-nav button.act:hover,
	.obb .obb-nav button.act:focus { background-color: var(--azul); color: var(--blanco); }

	.obb-principal { min-width: 0; display: flex; flex-direction: column; }
	.obb-vista { padding-bottom: var(--e-7); }
	.obb-kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); }
	.obb-cabecera { grid-template-columns: repeat(4, minmax(0, 1fr)); }
	.obb-acciones { grid-template-columns: repeat(4, minmax(0, 1fr)); }
	.obb-toast { bottom: var(--e-5); }
}

/* ==========================================================================
   lg · 1024 px — barra lateral completa
   ========================================================================== */

@media (min-width: 1024px) {

	.obb-app { display: grid; grid-template-columns: 244px 1fr; align-items: stretch; }

	.obb-nav {
		position: static;
		min-height: 100dvh;
		flex-direction: column;
		padding: 0;
		transform: none;
	}

	/* El contenido se queda pegado arriba mientras la columna azul se
	   estira hasta el final de la página. */
	.obb-nav-interior {
		position: sticky;
		top: 0;
		display: flex;
		flex-direction: column;
		gap: var(--e-1);
		max-height: 100dvh;
		overflow-y: auto;
		padding: var(--e-5) var(--e-3) var(--e-5) max(var(--e-3), var(--seg-izq));
	}

	.obb-app.obb-teclado .obb-nav { transform: none; }

	.obb-nav-marca {
		display: flex;
		align-items: center;
		gap: var(--e-3);
		font-size: var(--t-lg);
		font-weight: 700;
		letter-spacing: -.01em;
		padding: 2px var(--e-3) var(--e-5);
		color: var(--blanco);
		line-height: 1.2;
	}

	.obb-nav-marca .obb-logo-iniciales,
	.obb-nav-marca .obb-logo-defecto,
	.obb-nav-marca .obb-logo-img { margin: 0; }

	.obb-nav button {
		flex: 0 0 auto;
		flex-direction: row;
		justify-content: flex-start;
		gap: var(--e-3);
		padding: var(--e-3);
		border-radius: var(--r-input);
		font-size: var(--t-base);
		min-height: var(--c-sm);
	}

	.obb .obb-nav button.act,
	.obb .obb-nav button.act:hover,
	.obb .obb-nav button.act:focus { background-color: var(--azul); color: var(--blanco); }

	@media (hover: hover) {
		.obb .obb-nav button:hover { background-color: rgba(255, 255, 255, .08); color: var(--blanco); }
	}

	.obb-nav-pie {
		display: flex;
		margin-top: auto;
		padding: var(--e-3) var(--e-3) 0;
		border-top: 1px solid rgba(255, 255, 255, .12);
		align-items: center;
		gap: var(--e-2);
		color: var(--sobre-navy);
		font-size: var(--t-xs);
	}

	.obb-principal { min-width: 0; display: flex; flex-direction: column; }

	.obb-principal .obb-vista {
		flex: 1 1 auto;
		padding: var(--e-5) var(--e-6) var(--e-8);
	}

	.obb-top { padding: var(--e-4) var(--e-6); }

	.obb-kpis { grid-template-columns: repeat(6, minmax(0, 1fr)); }

	/* Misma rejilla que los indicadores: el total y los cinco accesos
	   ocupan una única fila alineada con la columna de abajo. */
	.obb-cabecera { grid-template-columns: repeat(6, minmax(0, 1fr)); }

	.obb-cabecera-titulo { display: none; }

	.obb-cabecera .obb-kpi { order: 0; }
	.obb-cabecera .o-1 { order: 1; }
	.obb-cabecera .o-2 { order: 2; }
	.obb-cabecera .o-3 { order: 3; }
	.obb-cabecera .o-4 { order: 4; }
	.obb-cabecera .o-5 { order: 5; }
	.obb-acciones { grid-template-columns: repeat(auto-fill, minmax(180px, 220px)); }
	.obb-estados { grid-template-columns: repeat(4, minmax(0, 1fr)); }

	.obb-solo-movil { display: none; }
	.obb-solo-escritorio { display: block; }

	.obb-modal-fondo { align-items: center; padding: var(--e-5); }
	.obb-modal { border-radius: 18px; max-height: 86dvh; }

	.obb-toast { bottom: var(--e-5); }
}

@media (max-width: 1023px) {
	.obb-solo-escritorio { display: none; }
}

/* ==========================================================================
   xl · 1440 px — el contenido deja de estirarse
   ========================================================================== */

@media (min-width: 1440px) {

	.obb-principal .obb-vista { max-width: 1440px; }
}

/* --------------------------------------------- Tabla de acuerdos */

.obb-ac-num { text-align: center; white-space: nowrap; }
.obb-ac-num .obb-pct { width: 72px; text-align: center; }

.obb-ac-resto { font-weight: 700; color: var(--verde); }
.obb-ac-resto.neg { color: var(--rojo); }

/* ==========================================================================
   Mayúsculas de interfaz
   --------------------------------------------------------------------------
   Todo lo que es etiqueta va en mayúsculas. Quedan fuera, a propósito:

   · los datos reales —cliente, dirección, notas, nombres de operarios—,
     porque un nombre propio en mayúsculas se lee peor y pierde la forma
     que ayuda a reconocerlo;
   · las opciones de los desplegables;
   · las frases explicativas y los mensajes.

   Las mayúsculas necesitan algo más de aire entre letras: sin el espaciado
   extra, una palabra larga en caja alta se lee como un bloque.
   ========================================================================== */

.obb-top h1,
.obb-panel h3,
.obb-titulo h3,
.obb h3.obb-cabecera-titulo,
.obb-titulo button,
.obb-modal h3,
.obb-campo > span,
.obb-check,
.obb-btn,
.obb-nav button,
.obb-tabs button,
.obb-rapido,
.obb-estado-chip,
.obb-badge,
.obb-accion-txt,
.obb-kpi-t,
.obb-total-importe,
.obb-ficha-k,
.obb-dato-k,
.obb-economico,
.obb-pendientes-cab strong,
.obb-registro-pct label,
.obb-pct-resto,
.obb-saldo-caja span,
.obb-saldo-caja em,
.obb-cuenta-datos,
.obb-pendiente-tipo,
.obb-login-marca p,
.obb-sello,
.obb-nav-pie {
	text-transform: uppercase;
	letter-spacing: .03em;
}

/* El campo de fecha muestra su marcador en mayúsculas: DD/MM/AAAA. */
.obb-campo input[type="date"],
.obb-campo input[type="datetime-local"],
.obb-campo input[type="time"] {
	text-transform: uppercase;
}

/* Excepciones dentro de zonas en mayúsculas. */
.obb-economico b,
.obb-cuenta-datos .obb-dim,
.obb-cuenta-datos div,
.obb-saldo-caja b {
	text-transform: none;
	letter-spacing: normal;
}

/* Los datos nunca se transforman. */
.obb-tarjeta-cliente,
.obb-tarjeta-dir,
.obb-dato-v,
.obb-ficha-v,
.obb-mono,
.obb-registro-id strong,
.obb-registro-tel,
.obb-ayuda,
.obb-vacio,
.obb-alerta,
.obb-toast,
.obb-pendiente-datos strong,
.obb-pendiente-dir,
.obb-pendientes-cab span,
.obb-saldo-nota,
.obb-campo input:not([type="date"]):not([type="datetime-local"]):not([type="time"]),
.obb-campo select,
.obb-campo textarea,
.obb-login-marca h1,
.obb-nav-marca {
	text-transform: none;
	letter-spacing: normal;
}

/* ==========================================================================
   Utilidades
   --------------------------------------------------------------------------
   Un puñado de clases para los ajustes que antes iban escritos a mano en
   cada elemento. Escribir el estilo dentro del HTML esquiva el sistema de
   diseño: quedan valores sueltos que no responden a los tokens y que hay
   que buscar uno a uno cuando algo cambia.
   ========================================================================== */

.obb-der { text-align: right; }
.obb-centro { text-align: center; }
.obb-oculto { display: none; }

.obb-sep-sm { margin-top: var(--e-2); }
.obb-sep { margin-top: var(--e-4); }
.obb-sep-izq { margin-left: var(--e-2); }
.obb-empuja { margin-left: auto; }
.obb-sin-margen { margin: 0; }

/* Texto auxiliar bajo un dato o un campo. */
.obb-nota {
	font-size: var(--t-sm);
	color: var(--tinta-2);
	margin-top: var(--e-3);
}

.obb-nota-sm {
	font-size: var(--t-xs);
	color: var(--tinta-3);
	margin-top: var(--e-3);
}

.obb-nota-aviso {
	font-size: var(--t-xs);
	color: var(--naranja);
	margin-top: var(--e-3);
}

/* Fila con los extremos separados. */
/* Cita dentro de una tarjeta, con su barra a la izquierda. */
.obb-cita {
	border-left: 3px solid var(--linea);
	padding: 2px 0 var(--e-2) var(--e-3);
	margin: var(--e-2) 0;
	color: var(--tinta-2);
	font-size: var(--t-sm);
}

/* Línea de un desglose, con separador inferior. */
.obb-linea-dato {
	font-size: var(--t-sm);
	color: var(--tinta-2);
	padding: var(--e-1) 0;
	border-bottom: 1px solid var(--linea);
}

/* Aclaración pegada al elemento anterior. */
.obb-nota-pegada {
	font-size: var(--t-sm);
	color: var(--tinta-3);
	margin: calc(var(--e-2) * -1) 0 var(--e-4);
}

/* Fila de totales de una tabla. */
.obb-tabla-total { font-weight: 700; background: var(--fondo-2); }

.obb-pulsable { cursor: pointer; }
.obb-normal { font-style: normal; }

.obb-extremos {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: var(--e-3);
}

/* ==========================================================================
   Accesibilidad
   ========================================================================== */

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

/* El foco se marca con contorno, no solo con color de borde: quien navega
   con teclado necesita ver dónde está sin depender de matices de tono. */
.obb :focus-visible { outline: 3px solid var(--azul); outline-offset: 2px; }

/* Los campos llevaban «outline: none» y quedaban sin marca al tabular: el
   resplandor azul no se ve en los de fecha, que pinta el navegador. */
.obb-campo input:focus:not(:focus-visible),
.obb-campo select:focus:not(:focus-visible),
.obb-campo textarea:focus:not(:focus-visible) {
	outline: none;
}

.obb-solo-lectores {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ==============================================================
   V3 · Modalidades de reparto
   ============================================================== */

.obb-modal-v3 .obb-modal-caja { max-width: 30rem; }

/* [LOCAL-45] Refinado del selector de asignación.
   Todo acotado a `.obb-modal-v3`: el modal genérico NO se toca. */
.obb-modal-v3 .obb-modal-caja { padding: var(--e-4) var(--e-4) calc(var(--e-4) + var(--seg-abajo)); }
.obb-modal-v3 .obb-modal-caja h3 { font-size: var(--t-md); margin-bottom: var(--e-2); }
.obb-modal-v3 .obb-modal-caja .obb-nota { font-size: var(--t-xs); margin-top: var(--e-1); }
.obb-modal-v3 .obb-modalidades-lista { gap: .4rem; margin: .5rem 0; }
.obb-modal-v3 .obb-modalidad-op { padding: .5rem .6rem; border-radius: .45rem; line-height: 1.25; }
.obb-modal-v3 .obb-modalidad-nombre { font-size: var(--t-sm); font-weight: 600; }
.obb-modal-v3 .obb-modalidad-pct { font-size: var(--t-xs); }
.obb-modal-v3 .obb-sep { margin-top: var(--e-3); }
.obb-modal-v3 .obb-btn { min-height: 40px; padding: var(--e-2) var(--e-4); font-size: var(--t-sm); }
.obb-modal-v3 .obb-btn-bloque + .obb-btn-bloque { margin-top: .4rem; }

.obb-modalidades-lista,
.obb-modo-asignacion { display: grid; gap: .5rem; margin: .75rem 0; }

.obb-modalidad-op,
.obb-modo-op {
  display: block;
  padding: .6rem .75rem;
  border: 1px solid var(--obb-borde, #d8dde3);
  border-radius: .5rem;
  cursor: pointer;
  line-height: 1.35;
}

.obb-modalidad-op:has(input:checked),
.obb-modo-op:has(input:checked) {
  border-color: var(--obb-primario, #1f6feb);
  box-shadow: inset 0 0 0 1px var(--obb-primario, #1f6feb);
}

.obb-modalidad-op .obb-pcts { font-variant-numeric: tabular-nums; opacity: .8; }

/* La asignacion directa salta la aceptacion del operario y congela el
   reparto en el acto. Se distingue en color para que no se active por
   descuido al pulsar deprisa. */
.obb-modo-directa { border-color: #b4741f; }

.obb-modo-directa:has(input:checked) {
  border-color: #b4741f;
  box-shadow: inset 0 0 0 1px #b4741f;
  background: #fff8ec;
}

.obb-modalidad-actual {
  font-variant-numeric: tabular-nums;
  font-size: .92em;
  opacity: .85;
}

.obb-modalidad-inactiva { opacity: .55; }

.obb-modalidad-default::after {
  content: 'predeterminada';
  margin-left: .4rem;
  padding: .05rem .4rem;
  font-size: .75em;
  border-radius: 1rem;
  background: var(--obb-suave, #eef3fa);
}

.obb-mod-nueva {
  display: grid;
  grid-template-columns: 1fr 5.5rem 5.5rem 3.5rem;
  gap: .4rem;
  align-items: center;
  margin: .5rem 0 .75rem;
}

.obb-mod-nueva .obb-ac-resto { text-align: right; font-variant-numeric: tabular-nums; }
.obb-mod-nueva .obb-ac-resto.neg { color: #c0392b; font-weight: 600; }

@media (max-width: 480px) {
  .obb-mod-nueva { grid-template-columns: 1fr 1fr; }
  .obb-mod-nueva input[type="text"] { grid-column: 1 / -1; }
}

/* ==========================================================================
   TARJETA DE SERVICIO · v2

   El diseño anterior ponía cliente, dirección y los tres campos al
   mismo peso visual, con las etiquetas y los valores en el mismo gris.
   No había dónde mirar primero.

   Aquí la cabecera azul separa identidad y estado, los valores van en
   negrita frente a etiquetas en mayúscula pequeña, cada fila lleva
   icono y las tres acciones tienen pesos distintos porque no son
   equivalentes.
   ========================================================================== */

.obb-tarjeta-v2 {
  /* [LOCAL-45] Radio y sombra más contenidos: pesa menos sin perder relieve. */
  border-radius: .8rem;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 1px 2px rgba(16, 24, 40, .05), 0 6px 16px rgba(16, 24, 40, .05);
  border: 0;
}

/* Zona pulsable: un enlace vacío que cubre la tarjeta.
   No envuelve contenido, así que el HTML es válido y el lector de
   pantalla anuncia un solo enlace con su etiqueta. */
.obb-tarjeta-v2 { position: relative; }

.obb-tj-abrir {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  text-decoration: none;
}

.obb-tj-abrir:focus-visible {
  outline: 3px solid #93b8f5;
  outline-offset: -3px;
}

/* Texto solo para lectores de pantalla. */
.obb-oculto {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Las acciones van POR ENCIMA del enlace: tocarlas no abre la ficha. */
.obb-tarjeta-v2 .obb-acciones-tarjeta,
.obb-tarjeta-v2 .obb-economico {
  position: relative;
  z-index: 2;
}

/* ------------------------------------------------------- cabecera */

/* Dos filas separadas por un divisor, con altura equilibrada.
   Nombre arriba a la izquierda; estado abajo a la derecha. */
.obb-tj-cab {
  padding: .5rem .9rem .55rem;
  background: linear-gradient(135deg, #1668e3 0%, #0d4fb8 100%);
  color: #fff;
}

/* Las dos zonas deben MEDIR lo mismo, no solo parecerlo.
   El badge hacía crecer la inferior: se le fija la caja para que su
   altura sea la misma que la del nombre, sin encoger el texto. */
.obb-tj-cab-alta,
.obb-tj-cab-baja {
  display: flex;
  align-items: center;
  /* [LOCAL-45] Altura NATURAL con un suelo común: ambas zonas siguen
     midiendo lo mismo, pero ya no reservan espacio de más. */
  min-height: 2rem;
  box-sizing: border-box;
}

.obb-tj-cab-alta { justify-content: flex-start; }
.obb-tj-cab-baja { justify-content: flex-end; }

.obb-tj-cab-div {
  height: 1px;
  margin: .3rem 0;
  background: rgba(255, 255, 255, .35);
}

.obb-tj-nombre {
  font-size: var(--t-lg);     /* [LOCAL-45] 18-20px · un solo nivel alto */
  font-weight: 700;
  letter-spacing: -.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* La píldora sobre azul necesita fondo propio para seguir legible. */
/* --------------------------------------------------------------------------
   CÁPSULA DE ESTADO EN LA CABECERA

   Fondo claro y texto oscuro, como la referencia. Pero el estado debe
   seguir siendo RECONOCIBLE: antes esta regla ganaba a las clases de
   estado y los siete acababan idénticos.

   El acento va en el ICONO y en el BORDE, no en el fondo: así la
   cabecera sigue siendo azul con cápsula clara, y de un vistazo se
   distingue un servicio sin asignar de uno cobrado.
   -------------------------------------------------------------------------- */
.obb .obb-tj-estado .obb-badge {
  background-color: rgba(255, 255, 255, .96);
  color: #0d2b57;
  flex: 0 0 auto;
  font-size: 1.25rem;          /* NULO grande, como la referencia */
  font-weight: 700;
  line-height: 1.1;
  padding: .32rem 1rem;
  border-radius: 999px;
  border: 2px solid transparent;
  box-sizing: border-box;
}

/* El icono acompaña al tamaño del texto. Solo aquí: los badges
   pequeños del resto del sistema no se tocan. */
.obb .obb-tj-estado .obb-badge .obb-ico {
  width: 1.25rem;
  height: 1.25rem;
  margin-right: .1rem;
}

/* Acentos por estado · paleta ya existente del sistema. */
.obb .obb-tj-estado .obb-badge-pendiente_asignar    { border-color: #b3261e; }
.obb .obb-tj-estado .obb-badge-pendiente_asignar .obb-ico { color: #b3261e; }

.obb .obb-tj-estado .obb-badge-pendiente_aceptacion { border-color: #8a6100; }
.obb .obb-tj-estado .obb-badge-pendiente_aceptacion .obb-ico { color: #8a6100; }

.obb .obb-tj-estado .obb-badge-asignado             { border-color: #0a57eb; }
.obb .obb-tj-estado .obb-badge-asignado .obb-ico    { color: #0a57eb; }

.obb .obb-tj-estado .obb-badge-con_cita             { border-color: #8a6100; }
.obb .obb-tj-estado .obb-badge-con_cita .obb-ico    { color: #8a6100; }

.obb .obb-tj-estado .obb-badge-ppto_enviado         { border-color: #6b3fa0; }
.obb .obb-tj-estado .obb-badge-ppto_enviado .obb-ico { color: #6b3fa0; }

.obb .obb-tj-estado .obb-badge-cobrado              { border-color: #087443; }
.obb .obb-tj-estado .obb-badge-cobrado .obb-ico     { color: #087443; }

.obb .obb-tj-estado .obb-badge-nulo                 { border-color: #54627d; }
.obb .obb-tj-estado .obb-badge-nulo .obb-ico        { color: #54627d; }

/* --------------------------------------------------------- datos */

.obb-tj-datos { padding: .55rem .9rem .5rem; }

.obb-tj-dir {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-size: var(--t-base);
  color: #1f2d3d;
  padding-bottom: .5rem;
  border-bottom: 1px solid #eef1f5;
}

.obb-tj-dir .obb-ico { color: #6b7a90; flex: 0 0 auto; }

.obb-tj-filas {
  margin: 0;
  padding: .5rem 0;
  border-bottom: 1px solid #eef1f5;
  display: grid;
  gap: .26rem;
}

/* Dos columnas: el icono ya viaja dentro del <dt>. */
.obb-tj-fila {
  display: grid;
  grid-template-columns: 8.2rem 1fr;
  align-items: center;
  gap: .5rem;
}

.obb-tj-fila dt .obb-ico { color: #3f4d61; flex: 0 0 auto; }

.obb-tj-fila dt {
  display: flex;
  align-items: center;
  gap: .45rem;
  margin: 0;
  font-size: var(--t-sm);     /* [LOCAL-45] 13-14px · EMPRESA / OPERARIO / TELÉFONO legibles */
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #7b8798;
}

.obb-tj-fila dd {
  margin: 0;
  font-size: var(--t-base);   /* [LOCAL-45] 15-16px · Magnolia, 627276513 */
  font-weight: 700;
  color: #16202e;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.obb-tj-tipo {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .3rem 0 .05rem;
  color: #5a6779;
  font-size: var(--t-sm);
}

/* --------------------------------------------------------- franja */

.obb-tj-franja {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin-top: .3rem;
  padding: .34rem .6rem;
  border-radius: .5rem;
  background: #f2f5f9;
  color: #47546a;
  font-size: var(--t-xs);
}

.obb-tj-franja span { display: flex; align-items: center; gap: .4rem; }
.obb-tj-franja b { font-weight: 600; color: #1f2d3d; }
.obb-tj-sep { width: 1px; height: .95rem; background: #d5dce6; }
.obb-tj-franja span:last-child { margin-left: auto; }

/* -------------------------------------------------------- acciones */

/* --------------------------------------------------------------------------
   REJILLA DE ACCIONES · por qué se declara explícitamente

   La regla general de `.obb-acciones-tarjeta` trae:

     grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));

   `grid-auto-columns` NO la anula: gobierna las pistas IMPLÍCITAS, y
   aquí las pistas son explícitas. A 320 px el navegador repartía
   96 + 96 + resto, y el tercer botón se quedaba con ~62 px para un
   contenido de ~70: ACTUALIZAR salía recortado.

   Aquí se declara la rejilla propia. `minmax(0, 1fr)` es lo que
   permite que las tres columnas se encojan por igual: con `1fr` a
   secas el mínimo automático es el tamaño del contenido y vuelve el
   desbordamiento.
   -------------------------------------------------------------------------- */
.obb-tarjeta-v2 .obb-acciones-tarjeta {
  display: grid;

  /* Se ANULA la rejilla explícita heredada. Sin esto, sus dos pistas
     de 96px sobreviven y solo la tercera se encoge. */
  grid-template-columns: none;

  /* Columnas implícitas, todas iguales. Vale para tres acciones y
     para dos, cuando el servicio no trae teléfono. */
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);

  gap: .5rem;
  padding: 0 1rem 1rem;
}

/* `minmax(0, ...)` arriba y `min-width: 0` aquí: las dos piezas que
   permiten que un elemento de rejilla se encoja por debajo del tamaño
   de su contenido en vez de desbordar. */
.obb-tarjeta-v2 .obb-acciones-tarjeta > * { min-width: 0; }

.obb-btn-t {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  min-height: 44px;          /* objetivo táctil, se usa en la calle */
  padding: 0 .55rem;
  border: 0;
  border-radius: .6rem;
  font: inherit;
  font-weight: 700;
  font-size: .92rem;
  cursor: pointer;
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   ESPECIFICIDAD · por qué van bajo `.obb`

   portal.css trae reglas globales del contenedor:

     .obb button, .obb button:hover, .obb button:focus,
     .obb button:active, .obb button:visited { background: transparent; color: inherit; }
     .obb a, .obb a:hover, .obb a:focus, .obb a:visited { color: var(--azul-osc); }

   Esas reglas pesan (0,1,1). Una clase suelta como `.obb-btn-t-verde` pesa
   (0,1,0) y PIERDE. El resultado real en el navegador era: Llamar verde con
   texto azul, Ruta con texto azul, y Actualizar con fondo transparente.

   Anteponer `.obb` sube a (0,2,0) y gana sin recurrir a !important.
   Se declaran también los estados, porque las globales los declaran: si
   solo se cubriera el estado base, el color volvería al pasar el ratón.
   -------------------------------------------------------------------------- */

.obb .obb-btn-t-verde,
.obb .obb-btn-t-verde:hover,
.obb .obb-btn-t-verde:focus,
.obb .obb-btn-t-verde:active,
.obb .obb-btn-t-verde:visited { background-color: #12a150; color: #fff; }

.obb .obb-btn-t-claro,
.obb .obb-btn-t-claro:hover,
.obb .obb-btn-t-claro:focus,
.obb .obb-btn-t-claro:active,
.obb .obb-btn-t-claro:visited { background-color: #e9eef5; color: #22304a; }

.obb .obb-btn-t-azul,
.obb .obb-btn-t-azul:hover,
.obb .obb-btn-t-azul:focus,
.obb .obb-btn-t-azul:active,
.obb .obb-btn-t-azul:visited { background-color: #1668e3; color: #fff; }

/* El matiz del hover se declara después, con el mismo peso. */
.obb .obb-btn-t-verde:hover { background-color: #0e8b45; }
.obb .obb-btn-t-claro:hover { background-color: #dde5ef; }
.obb .obb-btn-t-azul:hover  { background-color: #1259c6; }

.obb .obb-btn-t:focus-visible { outline: 3px solid #93b8f5; outline-offset: 2px; }

/* Estado derivado, en la píldora general del sistema -listas, filtros-.
   Se declara con `background-color`, no con el abreviado: dentro de la
   tarjeta manda `.obb .obb-tj-estado .obb-badge`, y para que la cascada
   las compare hay que hablar de la misma propiedad. Con el abreviado
   quedaban en planos distintos y el ámbar se colaba en la cabecera. */
.obb-badge-pendiente_aceptacion { background-color: #fff3d6; color: #8a5a00; }

/* --------------------------------------------------------------------------
   PANTALLAS ESTRECHAS · 320 a 390 px

   Antes se ocultaban las etiquetas de los botones por debajo de 380 px.
   Eso deja LLAMAR, RUTA y ACTUALIZAR como tres iconos sin nombre en los
   móviles de 375, 360 y 320, que son muchos, y no es la referencia
   aprobada.

   En su lugar se aprieta lo que se puede apretar: hueco, relleno y
   tamaño de letra. El texto se queda.
   -------------------------------------------------------------------------- */
@media (max-width: 390px) {

  .obb .obb-btn-t {
    gap: .3rem;
    padding: 0 .3rem;
    font-size: .82rem;
    letter-spacing: -.01em;
  }

  .obb-tarjeta-v2 .obb-acciones-tarjeta { gap: .35rem; padding: 0 .7rem .7rem; }

  .obb-tj-datos { padding-left: .7rem; padding-right: .7rem; }
  .obb-tj-cab   { padding-left: .7rem; padding-right: .7rem; }

  /* La etiqueta más larga es TELÉFONO: con icono ocupa unos 105 px.
     Se le da ancho de sobra en vez de encogerla. */
  .obb-tj-fila { grid-template-columns: 7.2rem 1fr; gap: .5rem; }
  .obb-tj-fila dt { font-size: var(--t-xs); }
  .obb-tj-fila dd { font-size: var(--t-base); }

  .obb-tj-nombre { font-size: var(--t-md); }
}

/* Muy estrecho: se aprieta un poco más, pero el texto sigue ahí. */
@media (max-width: 340px) {

  .obb .obb-btn-t { font-size: .72rem; gap: .18rem; padding: 0 .15rem; }
  .obb .obb-btn-t .obb-ico { width: .9rem; height: .9rem; }

  .obb-tarjeta-v2 .obb-acciones-tarjeta { gap: .28rem; padding: 0 .55rem .6rem; }

  /* NO se baja de 7rem: por debajo, "TELÉFONO:" con su icono invade la
     columna del valor y se lee "TELÉFONO:627276513" pegado. */
  .obb-tj-fila { grid-template-columns: 7rem 1fr; gap: .45rem; }
  .obb-tj-fila dt { font-size: .8rem; gap: .3rem; }

  .obb-tj-datos { padding-left: .55rem; padding-right: .55rem; }
  .obb-tj-cab   { padding-left: .55rem; padding-right: .55rem; }
}


/* ==========================================================================
   [LOCAL-62 · P03] LAS REJILLAS DE `.obb-lista` SE RETIRAN.
   --------------------------------------------------------------------------
   Aqui estaba la causa exacta de la desalineacion. `.obb-lista` llego a
   estar declarado CINCO veces: dos como `display:flex` y tres como rejilla,
   todas con la misma especificidad. Ganaba la ultima del fichero, que
   imponia `display:flex` pero NO reseteaba `align-items`, asi que seguia
   vigente el `align-items: start` declarado aqui para el componente
   `.obb-tarjeta-v2` -que no se pinta desde 2026-. Con `align-items: start`
   en un contenedor flex en columna, cada tarjeta se dimensiona por su
   contenido en lugar de estirarse al 100%: de ahi los anchos distintos, los
   bordes que no cuadraban y las tarjetas que sobresalian.

   `.obb-lista` queda declarado UNA sola vez, con el componente nuevo.
   ========================================================================== */


/* [LOCAL-45] Con puntero fino no hace falta el objetivo táctil de 44px.
   En pantallas táctiles NO se toca: se sigue usando en la calle. */
@media (pointer: fine) {
  .obb-btn-t { min-height: 38px; font-size: .88rem; }
}

@media (prefers-reduced-motion: reduce) {
  .obb-tarjeta-v2, .obb-btn-t { transition: none; }
}

/* ==========================================================================
   4.5.0 · REPARTO ECONÓMICO EN EL ALTA
   ========================================================================== */

/* Se muestra antes de confirmar: Empresa X%, Operario Y%, Administrador Z%. */
.obb-reparto {
  margin: var(--e-3) 0 var(--e-4);
  padding: var(--e-3) var(--e-4);
  border-radius: var(--r-md);
  background: #f2f5f9;
  border: 1px solid #d5dce6;
}

.obb-reparto-fila {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-3);
  padding: .25rem 0;
  font-size: var(--t-sm);
}

.obb-reparto-fila strong { font-size: 1.05rem; }

/* El margen del administrador es el resto: se separa para que se lea
   como consecuencia, no como un valor que se teclea. */
.obb-reparto-admin {
  margin-top: .3rem;
  padding-top: .45rem;
  border-top: 1px solid #d5dce6;
}

.obb-reparto-ok  { border-color: #a8d5bd; background: #f1f9f5; }
.obb-reparto-mal { border-color: #e8b4ae; background: #fdf2f1; }

/* Chips de estado de una modalidad. */
.obb-chip {
  display: inline-block;
  padding: .1rem .45rem;
  border-radius: 999px;
  background: #e3e9f1;
  color: #47546a;
  font-size: .72rem;
  font-weight: 700;
  vertical-align: middle;
}

.obb-chip-def { background: #d9ecdf; color: #14603a; }

.obb-modalidad-inactiva td { opacity: .6; }

/* --------------------------------------------------------------------------
   PORCENTAJES Y MODALIDADES EN MÓVIL

   La tabla se convierte en tarjetas: en un móvil de 390 px una tabla de
   tres columnas obliga a desplazamiento horizontal, que es justo lo que
   no debe pasar.
   -------------------------------------------------------------------- */
@media (max-width: 640px) {

  .obb-tabla-mod thead { display: none; }

  .obb-tabla-mod,
  .obb-tabla-mod tbody,
  .obb-tabla-mod tr,
  .obb-tabla-mod td { display: block; width: 100%; }

  .obb-tabla-mod tr {
    margin-bottom: var(--e-3);
    padding: var(--e-3);
    border: 1px solid #d5dce6;
    border-radius: var(--r-md);
    background: #fff;
  }

  .obb-tabla-mod td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--e-3);
    padding: .2rem 0;
    text-align: left;
  }

  /* La etiqueta de cada dato viaja en data-col. */
  .obb-tabla-mod td[data-col]::before {
    content: attr(data-col);
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .03em;
    text-transform: uppercase;
    color: #5a6779;
  }

  .obb-tabla-mod .obb-mod-acc {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .4rem;
    margin-top: .5rem;
  }

  .obb-tabla-mod .obb-mod-acc::before { content: none; }

  .obb-tabla-mod .obb-mod-acc .obb-btn { width: 100%; min-height: 44px; }
}

/* ==========================================================================
   4.5.0 · ACUERDOS POR MODALIDAD
   ========================================================================== */

/* Cada modalidad es un bloque con su propia tabla de operarios. */
.obb-ac-grupo { margin-bottom: var(--e-5); }

.obb-ac-grupo-tit {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .4rem;
  margin: 0 0 var(--e-2);
  font-size: 1rem;
}

/* El resto del administrador es CALCULADO: se presenta como tal. */
.obb-ac-resto { font-variant-numeric: tabular-nums; color: #47546a; }
.obb-ac-resto.neg { color: #b3261e; font-weight: 700; }

/* --------------------------------------------------------------------------
   PORCENTAJES EN MÓVIL

   La tabla pasa a tarjetas: cuatro columnas en 390 px obligan a
   desplazamiento horizontal, y el campo numérico queda fuera de vista
   justo cuando hay que teclearlo.
   -------------------------------------------------------------------- */
@media (max-width: 640px) {

  .obb-tabla-ac thead { display: none; }

  .obb-tabla-ac,
  .obb-tabla-ac tbody,
  .obb-tabla-ac tr,
  .obb-tabla-ac td { display: block; width: 100%; }

  .obb-tabla-ac tr {
    margin-bottom: var(--e-3);
    padding: var(--e-3);
    border: 1px solid #d5dce6;
    border-radius: var(--r-md);
    background: #fff;
  }

  .obb-tabla-ac td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--e-3);
    padding: .3rem 0;
    text-align: left;
  }

  .obb-tabla-ac td[data-col]::before {
    content: attr(data-col);
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .03em;
    text-transform: uppercase;
    color: #5a6779;
  }

  /* Objetivo táctil completo en el campo que se teclea. */
  .obb-tabla-ac .obb-pct {
    width: 5.5rem;
    min-height: 44px;
    text-align: right;
  }

  .obb-tabla-ac .obb-ac-acc { margin-top: .5rem; }
  .obb-tabla-ac .obb-ac-acc::before { content: none; }
  .obb-tabla-ac .obb-ac-acc .obb-btn { width: 100%; min-height: 44px; }
}

/* ==========================================================================
   4.5.0 · REPARTO OFRECIDO AL OPERARIO
   ========================================================================== */

/* Lo que se le ofrece, ANTES de aceptar. No es el snapshot: aún no
   existe. Por eso se presenta como propuesta, no como hecho. */
.obb-oferta-reparto {
  margin-top: var(--e-3);
  padding: var(--e-3);
  border-radius: var(--r-md);
  background: #f2f5f9;
  border: 1px solid #d5dce6;
}

.obb-oferta-mod {
  margin-bottom: .35rem;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: #5a6779;
}

.obb-oferta-fila {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-3);
  padding: .18rem 0;
  font-size: var(--t-sm);
}

/* El porcentaje del operario es el dato que le importa: destaca. */
.obb-oferta-fila strong { font-size: 1.15rem; color: #14603a; }

/* Empresa y administración son contexto, no protagonistas. */
.obb-oferta-otros { color: #5a6779; font-size: .82rem; }

/* ==========================================================================
   [LOCAL-46] Refinamiento del DETALLE y dos defectos del selector V3
   --------------------------------------------------------------------------
   Todo acotado a clases propias: `.obb-panel` NO se toca, porque lo
   comparten Usuarios, Cuentas, Empresa, Perfil y Tipos.
   ========================================================================== */

/* ---- Cabecera de la ficha · reconstruye el style en línea retirado ---- */
.obb-ficha-cab {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--e-2);
  margin-bottom: var(--e-3);
}

/* ---- Paneles del detalle · menos aire, sin tocar .obb-panel ---- */
.obb-panel-ficha,
.obb-panel-acciones,
.obb-panel-notas,
.obb-panel-historial { padding: var(--e-3) var(--e-4); }

.obb-panel-acciones h3,
.obb-panel-notas h3,
.obb-panel-historial h3 { font-size: var(--t-md); margin: 0 0 var(--e-2); }

/*
 * Rejilla interna de la ficha.
 *
 * `auto-fit` con un mínimo de 15rem decide solo: dos columnas cuando el
 * ancho útil da para ambas legibles, una cuando no. En móvil nunca hay
 * sitio para dos, así que queda en columna sin necesidad de un corte.
 */
.obb-ficha-datos {
  display: grid;
  /* El `max(...)` limita a DOS columnas: cada una pide al menos el 48%
     del contenedor, así que una tercera nunca cabe por ancha que sea la
     pantalla. Y con poco ancho, el mínimo de 15rem deja una sola. */
  grid-template-columns: repeat(auto-fit, minmax(max(15rem, 48%), 1fr));
  gap: 0 var(--e-4);
}

/* Lo que no es una fila de datos ocupa el ancho completo: avisos,
   el campo de teléfono pendiente y el botón de guardar. */
.obb-ficha-datos:not(.obb-ficha-datos-edit) > :not(.obb-ficha-fila) { grid-column: 1 / -1; }

.obb-panel-ficha .obb-ficha-fila { padding: var(--e-2) 0; }
.obb-panel-ficha .obb-ficha-k { font-size: var(--t-sm); margin-bottom: 1px; }
.obb-panel-ficha .obb-ficha-v { font-size: var(--t-base); }

/* ---- Ficha EDITABLE · los campos también en rejilla ---- */
.obb-ficha-datos-edit {
  grid-template-columns: repeat(auto-fit, minmax(max(16rem, 31%), 1fr));
  gap: var(--e-2) var(--e-4);
}

.obb-ficha-datos-edit > .obb-btn,
.obb-ficha-datos-edit > .obb-alerta { grid-column: 1 / -1; }

.obb-ficha-datos-edit .obb-campo { margin: 0; }

/* ---- Acciones · fila compacta, con suelo táctil ---- */
.obb-panel-acciones .obb-linea-acciones { gap: var(--e-2); }
.obb-panel-acciones .obb-btn { flex: 1 1 11rem; min-height: 44px; }

@media (pointer: fine) {
  .obb-panel-acciones .obb-btn { min-height: 40px; }
}

/* ---- Notas · el área de escritura arranca más baja, pero crece ---- */
.obb-panel-notas .obb-campo textarea { min-height: 72px; }
.obb-panel-notas .obb-campo { margin-bottom: var(--e-2); }

/* ---- Historial · filas más juntas, sin ocultar nada ---- */
.obb-panel-historial .obb-linea-dato { padding: var(--e-1) 0; font-size: var(--t-sm); }

/* ==========================================================================
   [LOCAL-46] Selector de asignación · dos defectos reales
   ========================================================================== */

/*
 * A · El nombre y el porcentaje se tocaban: "CerrajeriaEmpresaEmpresa 50%".
 * B · El radio sobresalía 11px del borde de su opción.
 *
 * Los dos salen del mismo sitio: la opción era `display: block` y sus
 * hijos quedaban en línea, sin separación y sin poder alinearse. Con
 * flex, el radio entra en la caja y el gap separa los textos.
 */
.obb-modal-v3 .obb-modalidad-op {
  display: flex;
  align-items: center;
  gap: .55rem;
  flex-wrap: wrap;
}

.obb-modal-v3 .obb-modalidad-op > input[type="radio"] {
  flex: 0 0 auto;
  width: 1.1rem;
  height: 1.1rem;
  margin: 0;
}

.obb-modal-v3 .obb-modalidad-nombre { flex: 1 1 auto; min-width: 0; }
.obb-modal-v3 .obb-modalidad-pct { flex: 0 0 auto; margin-left: auto; }


/* ==========================================================================
   [LOCAL-48] Ficha EDITABLE compacta · todo bajo .obb-ficha-datos-edit
   --------------------------------------------------------------------------
   No se tocan `.obb-campo` global, los tokens ni `.obb-panel`.
   El tamano de letra se queda en 16px: por debajo, iOS hace zoom al
   enfocar. Los objetivos tactiles se respetan.
   ========================================================================== */

/*
 * El `flex-direction: row` de arriba pierde contra
 * `body.obb-pagina > :not(script)…`, que acumula muchísima
 * especificidad con sus `:not()`. Se repite aquí con el padre delante,
 * que es lo mínimo para ganar sin recurrir a !important.
 */
body.obb-pagina > .obb-modal-fondo { flex-direction: row; }

.obb-ficha-datos-edit .obb-campo { margin-bottom: 0; }

/* Etiqueta pegada a su campo: sobraba el aire, no la etiqueta. */
.obb-ficha-datos-edit .obb-campo > span {
  display: block;
  margin-bottom: 3px;
  line-height: 1.25;
}

/* Input de ~43px: se recorta el relleno, nunca la letra. */
.obb-ficha-datos-edit .obb-campo input,
.obb-ficha-datos-edit .obb-campo select {
  padding: 9px 12px;
  /* La altura la fijaba un min-height de 50px, no el relleno. */
  min-height: 43px;
}

/* Telefono y LLAMAR en la misma fila. */
.obb-ficha-datos-edit .obb-campo > .obb-campo-accion {
  display: flex;
  align-items: center;
  gap: var(--e-2);
}

.obb-ficha-datos-edit .obb-campo-accion .obb-btn {
  min-height: 43px;
  padding: 0 var(--e-3);
  white-space: nowrap;
}

/* Guardar: ancho completo, compacto y tactil. */
.obb-ficha-datos-edit > .obb-btn {
  margin-top: var(--e-2);
  min-height: 44px;
  padding: 0 var(--e-4);
}

@media (pointer: fine) {
  .obb-ficha-datos-edit > .obb-btn,
  .obb-ficha-datos-edit .obb-campo-accion .obb-btn { min-height: 40px; }
}

/* Separacion vertical entre filas: 9px, dentro de lo pedido. */
.obb-ficha-datos-edit { gap: 9px var(--e-4); }

/*
 * Tres columnas en escritorio. El `max(...)` sigue decidiendo por ancho
 * real: cada columna pide al menos el 24% del contenedor y 15rem, asi que
 * la tercera solo aparece cuando cabe, y nunca hay una cuarta.
 */
@media (min-width: 1024px) {
  .obb-ficha-datos-edit {
    grid-template-columns: repeat(auto-fit, minmax(max(15rem, 24%), 1fr));
  }
}

/* ==========================================================================
   [LOCAL-62 · P04] El componente `obb-rg-*` de LOCAL-49 se RETIRA.
   --------------------------------------------------------------------------
   Lo sustituye `obb-tj-*`, al final de este fichero. Se retira en lugar de
   dejarlo muerto porque sus reglas competian con las nuevas: `.obb-lista`
   estaba declarado CINCO veces entre este bloque y el del componente
   anterior, y de ahi venia la desalineacion de P03.
   ========================================================================== */


/* ==========================================================================
   [LOCAL-50] CABECERA DEL PANEL SERVICIOS
   --------------------------------------------------------------------------
   Total a la izquierda y formulario a la derecha. Familia propia, sin
   reutilizar clases del listado ni de los KPIs.
   ========================================================================== */

.obb-sv-cab {
  display: grid;
  grid-template-columns: minmax(9rem, 12rem) 1fr;
  gap: var(--e-3);
  align-items: stretch;
  margin-bottom: var(--e-3);
}

/*
 * [LOCAL-62 · P06] El bloque del total SOLO lleva el KPI.
 *
 * En P05 este bloque alojaba tambien DESCARGAR PDF. Era una asociacion
 * equivocada: el KPI describe el resultado y el boton es una ACCION sobre los
 * mismos filtros que BUSCAR. El boton se ha mudado al formulario, a la fila 3.
 */
.obb-sv-total { display: flex; }

.obb-sv-total .obb-kpi { width: 100%; height: 100%; }

.obb-sv-filtros {
  display: grid;
  gap: var(--e-2);
  padding: var(--e-3);
  border: 1px solid #e7edf4;
  border-radius: 12px;
  background: #fff;
  align-content: start;
  min-width: 0;
}

/* Fila 1 · selector + buscar. Sin selector, buscar ocupa todo. */
.obb-sv-f1 { display: grid; gap: var(--e-2); grid-template-columns: 1fr 1.6fr; }
.obb-sv-f1:has(> :only-child) { grid-template-columns: 1fr; }

/* Fila 2 · fechas y selectores. Con menos campos se reparte sola. */
.obb-sv-f2 { display: grid; gap: var(--e-2); grid-template-columns: repeat(4, minmax(0, 1fr)); }
.obb-sv-f2:has(> :nth-child(3):last-child) { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.obb-sv-filtros .obb-campo { margin-bottom: 0; min-width: 0; }
.obb-sv-filtros .obb-campo > span { margin-bottom: 3px; }
.obb-sv-filtros .obb-campo input,
.obb-sv-filtros .obb-campo select { min-height: 42px; padding: 8px 11px; }

/* Botón compacto: ancho de su celda, altura contenida. */
.obb-sv-btn { width: 100%; min-height: 42px; padding: 0 var(--e-4); }

/*
 * [LOCAL-62 · P06] Fila 3 · BUSCAR y DESCARGAR PDF, hermanos.
 *
 * BUSCAR se queda con el espacio sobrante y DESCARGAR PDF con el ancho de su
 * texto, que es la jerarquia pedida: la accion principal manda y la secundaria
 * va compacta a su lado.
 */
.obb-sv-f3 {
  display: grid;
  gap: var(--e-2);
  grid-template-columns: 1fr auto;
  align-items: stretch;
}

.obb-sv-pdf {
  width: 100%;
  min-height: 42px;
  justify-content: center;
  white-space: nowrap;
}

@media (pointer: fine) {
  .obb-sv-filtros .obb-campo input,
  .obb-sv-filtros .obb-campo select,
  .obb-sv-btn,
  .obb-sv-pdf { min-height: 40px; }
}

/* ---- TABLET ---- */
@media (max-width: 1080px) {
  .obb-sv-cab { grid-template-columns: minmax(8rem, 10rem) 1fr; }
  .obb-sv-f1 { grid-template-columns: 1fr; }
  .obb-sv-f2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .obb-sv-f2:has(> :nth-child(3):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Si el total y el formulario se aprietan, el total sube. */
@media (max-width: 860px) {
  .obb-sv-cab { grid-template-columns: 1fr; }
  .obb-sv-total .obb-kpi { height: auto; }
}

/*
 * [LOCAL-62 · P06] El ensanche de la columna del total a partir de 1200px se
 * retira: existia SOLO para que el KPI y DESCARGAR PDF cupiesen en la misma
 * linea. Con el boton ya en el formulario, la columna vuelve a su medida, que
 * es la que necesita el KPI.
 */

/* ---- MOVIL ---- */
@media (max-width: 700px) {
  .obb-sv-filtros { padding: var(--e-2); gap: 7px; }
  .obb-sv-f2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .obb-sv-filtros .obb-campo input,
  .obb-sv-filtros .obb-campo select,
  .obb-sv-btn,
  .obb-sv-pdf { min-height: 44px; }
}

/*
 * [LOCAL-62 · P06] Por debajo de 560px los dos botones se apilan.
 *
 * Medido en navegador: con «Descargar PDF» al lado, a 320px BUSCAR bajaba a
 * unos 70px utiles y el texto se partia. Apilados siguen siendo las dos
 * acciones del formulario, que es la condicion que importa, y no aparece
 * scroll horizontal.
 */
@media (max-width: 560px) {
  .obb-sv-f3 { grid-template-columns: 1fr; }
}

/*
 * [LOCAL-50] Una sola columna solo por debajo de 330px.
 *
 * Medido: el campo de fecha necesita unos 112px utiles para mostrar
 * DD/MM/AAAA y el icono del calendario. A 330px quedan justo 112; a
 * 320px, 107, y ahi si se comprime. El corte va inmediatamente antes.
 */
@media (max-width: 329px) {
  .obb-sv-f2 { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Panel Usuarios · Cambio 3
   Rejilla real, no escalado: el alta aprovecha el ancho en filas de tres
   campos y las fichas pasan de una por fila a una rejilla que se adapta.
   Todo cuelga de «.obb-us» para no tocar el resto del portal.
   ========================================================================== */

.obb-us { min-width: 0; }

/* -------------------------------------------------- Pestañas */

/* Más bajas que las genéricas, sin bajar del mínimo táctil. */
.obb-us .obb-us-tabs { margin-bottom: var(--e-3); }

.obb-us .obb-us-tabs button {
	padding: var(--e-2) var(--e-2);
	min-height: 40px;
}

/* -------------------------------------------------- Paneles */

.obb-us .obb-us-panel { padding: var(--e-4); margin-bottom: var(--e-3); }

.obb-us .obb-us-h {
	display: flex;
	align-items: center;
	gap: var(--e-2);
	margin: 0 0 var(--e-3);
}

.obb-us .obb-us-h .obb-ico { color: var(--azul); flex: 0 0 auto; }

/* -------------------------------------------------- Alta */

/* Tres columnas en escritorio: Nombre · Usuario · Contraseña /
   Teléfono · Porcentaje · Crear. Sin porcentaje, el botón sube a la
   celda libre y el formulario ocupa dos filas igualmente. */
.obb-us-alta {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--e-3);
	align-items: end;
}

.obb-us .obb-us-campo { margin-bottom: 0; min-width: 0; }

.obb-us .obb-us-campo > span { margin-bottom: var(--e-1); }

/* Icono dentro del campo: decorativo, la etiqueta sigue siendo el label. */
.obb-us-inp { position: relative; display: block; width: 100%; }

.obb-us-inp > .obb-ico {
	position: absolute;
	left: var(--e-3);
	top: 50%;
	transform: translateY(-50%);
	color: var(--apagado);
	pointer-events: none;
}

.obb-us .obb-us-inp input {
	padding-left: var(--e-8);
	min-height: var(--c-sm);
	margin: 0;
}

/* El sufijo de porcentaje va en el hueco de la derecha del propio campo. */
.obb-us-inp-pct::after {
	content: "%";
	position: absolute;
	right: var(--e-3);
	top: 50%;
	transform: translateY(-50%);
	color: var(--tinta-3);
	font-size: var(--t-sm);
	font-weight: 650;
	pointer-events: none;
}

.obb-us .obb-us-inp-pct input { padding-right: var(--e-6); }

/* El botón Crear es una celda más de la rejilla, no una franja. */
.obb-us-crear { display: flex; align-items: flex-end; }

.obb-us .obb-us-crear .obb-btn {
	width: 100%;
	min-height: var(--c-sm);
	padding: var(--e-2) var(--e-4);
}

.obb-us .obb-us-panel .obb-ayuda { margin: var(--e-3) 0 0; }

/* -------------------------------------------------- Fichas */

.obb-us-lista {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
	gap: var(--e-3);
	align-items: start;
}

.obb-us-tj {
	border: 1px solid var(--linea);
	border-radius: var(--r-card);
	background: var(--realce);
	padding: var(--e-3);
	display: flex;
	flex-direction: column;
	gap: var(--e-2);
	min-width: 0;
}

.obb-us-tj.inact { opacity: .6; }

/* Arriba y no centrado: con nombre largo o distintivo «Principal» el
   avatar quedaba flotando a media altura. */
.obb-us-tj-cab { display: flex; align-items: flex-start; gap: var(--e-2); min-width: 0; }

.obb-us-av {
	flex: 0 0 auto;
	width: 36px;
	height: 36px;
	border-radius: var(--r-pill);
	background: var(--azul-suave);
	color: var(--azul);
	font-weight: 700;
	display: flex;
	align-items: center;
	justify-content: center;
}

.obb-us-tj-id { min-width: 0; flex: 1 1 auto; }

.obb-us-tj-id strong {
	display: block;
	font-size: var(--t-base);
	line-height: 1.25;
	overflow-wrap: anywhere;
}

.obb-us-tj-id .obb-mono { color: var(--tinta-3); font-size: var(--t-xs); margin-top: 2px; }

.obb-us-tel {
	display: inline-flex;
	align-items: center;
	gap: var(--e-1);
	font-size: var(--t-sm);
	color: var(--azul);
	font-weight: 650;
	min-height: 24px;
}

.obb-us-tel.obb-dim { color: var(--tinta-3); font-weight: 500; }

/* El eco del reparto va debajo del campo, no a su lado: al lado obligaba
   a partir la línea en cuanto la tarjeta se estrechaba. */
.obb-us-pct { display: block; }

.obb-us-pct-campo { display: block; min-width: 0; }

.obb-us-pct-campo > span {
	display: block;
	font-size: var(--t-2xs);
	font-weight: 700;
	letter-spacing: .02em;
	text-transform: uppercase;
	color: var(--tinta-2);
	margin-bottom: var(--e-1);
}

.obb-us .obb-us-pct .obb-pct {
	width: 100%;
	margin: 0;
	min-height: var(--c-sm);
	padding-left: var(--e-8);
	padding-right: var(--e-6);
}

.obb-us .obb-us-pct .obb-pct-resto {
	display: block;
	margin: var(--e-1) 0 0;
	font-size: var(--t-2xs);
}

/* -------------------------------------------------- Acciones */

/* Reparten la fila entre ellas en lugar de ocupar una cada una. */
.obb-us-acc { display: flex; flex-wrap: wrap; gap: var(--e-2); margin-top: auto; }

.obb-us .obb-us-b {
	flex: 1 1 auto;
	min-width: 112px;
	padding: var(--e-2) var(--e-3);
	min-height: var(--c-sm);
	font-size: var(--t-xs);
	gap: var(--e-1);
}

/* Destructiva reconocible, sin convertirse en una franja roja. */
/* Media fila y a la derecha: se distingue sin ocupar una franja entera. */
.obb-us .obb-us-del { flex: 0 1 calc(50% - var(--e-2)); margin-left: auto; }

.obb-us .obb-us-del,
.obb-us .obb-us-del:hover,
.obb-us .obb-us-del:focus,
.obb-us .obb-us-del:active {
	color: var(--rojo);
	border-color: var(--rojo-suave);
	background-color: var(--blanco);
}

.obb-us .obb-us-del .obb-ico { color: var(--rojo); }

/* -------------------------------------------------- Responsive */

/* Tablet: dos columnas de campos; el botón cierra la rejilla a lo ancho. */
@media (max-width: 1023px) {

	.obb-us-alta { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Móvil: los campos cortos siguen emparejados mientras quepan, porque
   apilarlos todos alargaba el alta más que el diseño anterior. */
@media (max-width: 639px) {

	.obb-us-alta { gap: var(--e-2); }

	/* El nombre es el campo largo: ocupa la fila entera. */
	.obb-us-alta > .obb-us-campo:first-child { grid-column: 1 / -1; }

	/* En móvil el botón sí ocupa el ancho: es el destino del formulario. */
	.obb-us-crear { grid-column: 1 / -1; }

	/* Sin porcentaje, el teléfono se queda solo: que ocupe el ancho. */
	.obb-us-alta:not(.obb-us-alta-pct) > .obb-us-campo:nth-child(4) { grid-column: 1 / -1; }

	.obb-us-lista { grid-template-columns: minmax(0, 1fr); }

	.obb-us .obb-us-panel { padding: var(--e-3); }
}

/* Por debajo de 400 px el icono cede su sitio al texto, igual que en las
   pestañas: así los campos siguen emparejados hasta 320 px sin apretarse. */
@media (max-width: 399px) {

	.obb-us-inp > .obb-ico { display: none; }

	.obb-us .obb-us-inp input { padding-left: var(--e-3); }

	.obb-us .obb-us-pct .obb-pct { padding-left: var(--e-3); }
}

/* Ficha algo más ceñida en móvil: el avatar cede unos píxeles. */
@media (max-width: 639px) {

	.obb-us-av { width: 32px; height: 32px; font-size: var(--t-sm); }

	.obb-us-tj { gap: var(--e-2); padding: var(--e-3); }

	.obb-us-tel { min-height: 20px; }
}

/* Pantallas muy estrechas: las acciones dejan de pelearse por el ancho. */
@media (max-width: 359px) {

	.obb-us .obb-us-b { min-width: 0; flex: 1 1 calc(50% - var(--e-2)); }
}

/* ==========================================================================
   Detalle del Servicio · Cambio 4
   Reparto real del ancho: la ficha en rejilla, el guardar junto al operario,
   las acciones repartidas y las notas en dos zonas. Todo bajo clases
   propias «obb-dt-*» salvo los ajustes de los paneles del detalle, que ya
   eran exclusivos de esta pantalla.
   ========================================================================== */

/* ---------------------------------------------- Cabecera de la ficha */

.obb-dt-cab { align-items: flex-start; }

.obb-dt-id { display: flex; align-items: center; gap: var(--e-2); min-width: 0; }

.obb-dt-id-ico {
	flex: 0 0 auto;
	width: 32px;
	height: 32px;
	border-radius: var(--r-input);
	background: var(--azul-suave);
	color: var(--azul);
	display: flex;
	align-items: center;
	justify-content: center;
}

.obb-dt-id-txt { min-width: 0; display: block; }

/*
 * El identificador no se parte. Sin esto, a 320 px el hueco entre el icono
 * y el badge se quedaba en unos pocos pixeles y el `overflow-wrap` del
 * panel rompia «SV-260922-011» letra a letra, una por linea.
 */
.obb-dt-id-txt strong {
	display: block;
	font-size: var(--t-md);
	line-height: 1.2;
	white-space: nowrap;
	overflow-wrap: normal;
	word-break: normal;
}

.obb-dt-id-sub {
	display: block;
	font-size: var(--t-2xs);
	color: var(--tinta-3);
	text-transform: none;
	letter-spacing: 0;
}

/* Separación ligera bajo la cabecera, como en la referencia. */
.obb-panel-ficha .obb-dt-cab {
	padding-bottom: var(--e-2);
	margin-bottom: var(--e-2);
	border-bottom: 1px solid var(--linea);
}

/* Título de bloque con su icono. */
.obb-dt-h { display: flex; align-items: center; gap: var(--e-2); }
.obb-dt-h .obb-ico { color: var(--azul); flex: 0 0 auto; }

/* ---------------------------------------------- Ficha */

/* Hasta tres columnas cuando el ancho da: el 30% impide una cuarta. */
.obb-ficha-datos {
	grid-template-columns: repeat(auto-fit, minmax(max(14rem, 30%), 1fr));
}

/* Operario y Guardar comparten fila: el botón deja de ser una franja. */
.obb-dt-asignar {
	grid-column: 1 / -1;
	display: flex;
	align-items: flex-end;
	gap: var(--e-3);
	flex-wrap: wrap;
}

.obb-dt-asignar > .obb-campo { flex: 1 1 16rem; min-width: 0; margin: 0; }

.obb-ficha-datos-edit > .obb-dt-asignar > .obb-btn {
	flex: 0 0 auto;
	min-width: 12rem;
	min-height: var(--c-sm);
	padding: var(--e-2) var(--e-4);
}

/* ---------------------------------------------- Acciones */

/* Reparten el ancho sin estirarse hasta lo absurdo. La segunda fila es la
   de la oferta pendiente -Aceptar y Rechazar-, que sin esto se estiraba a
   media pantalla cada una. */
.obb-panel-acciones .obb-dt-acc .obb-btn,
.obb-panel-acciones .obb-sep-sm .obb-btn {
	flex: 1 1 12rem;
	max-width: 18rem;
	justify-content: center;
	gap: var(--e-2);
}

.obb-dt-chev { display: none; }

/* ---------------------------------------------- Notas */

.obb-dt-notas { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--e-3); }

.obb-dt-notas-lista { min-width: 0; }

.obb-dt-nota {
	border-left: 3px solid var(--linea);
	padding: 2px 0 var(--e-2) var(--e-3);
	margin-bottom: var(--e-2);
}

.obb-dt-nota:last-child { margin-bottom: 0; }

.obb-dt-notas-alta { min-width: 0; display: flex; flex-direction: column; gap: var(--e-2); }

.obb-dt-nota-campo { margin: 0; }

.obb-dt-nota-campo textarea { min-height: 80px; }

/* Botón a la derecha bajo el textarea, no una franja. */
.obb-dt-notas-pie { display: flex; justify-content: flex-end; }

.obb-panel-notas .obb-dt-notas-pie .obb-btn { flex: 0 0 auto; min-width: 11rem; }

/* ---------------------------------------------- Historial */

.obb-dt-hist {
	position: relative;
	padding-left: var(--e-4);
	border-left: 2px solid var(--linea);
	display: flex;
	flex-direction: column;
	gap: var(--e-2);
}

.obb-dt-hito {
	position: relative;
	display: flex;
	gap: var(--e-2);
	flex-wrap: wrap;
	font-size: var(--t-sm);
	line-height: 1.35;
}

/* El punto temporal se dibuja sobre la línea. */
.obb-dt-hito::before {
	content: "";
	position: absolute;
	left: calc( var(--e-4) * -1 - 5px );
	top: 6px;
	width: 8px;
	height: 8px;
	border-radius: var(--r-pill);
	background: var(--azul);
	box-shadow: 0 0 0 3px var(--blanco);
}

.obb-dt-hito-fecha { color: var(--tinta-3); flex: 0 0 auto; }
.obb-dt-hito-txt { color: var(--tinta-2); min-width: 0; }

/* ---------------------------------------------- Escritorio */

/* Notas en dos zonas cuando hay ancho de sobra. */
@media (min-width: 1024px) {

	.obb-dt-notas {
		grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
		gap: var(--e-5);
		align-items: start;
	}

	.obb-dt-notas-lista {
		border-right: 1px solid var(--linea);
		padding-right: var(--e-5);
	}
}

/* ---------------------------------------------- Móvil */

/* Entre móvil y escritorio las notas van apiladas: sin partir en dos
   columnas estrechas, pero tampoco con el aire de dos bloques. */
@media (max-width: 1023px) {

	.obb-dt-notas { gap: var(--e-2); }

	.obb-dt-nota-campo textarea { min-height: 72px; }
}

@media (max-width: 639px) {

	/* El rótulo auxiliar del ID cede su línea en pantallas estrechas. */
	.obb-dt-id-sub { display: none; }

	/* Una acción por fila, compacta y con su punta de flecha. */
	.obb-panel-acciones .obb-dt-acc { flex-direction: column; }

	.obb-panel-acciones .obb-sep-sm .obb-btn { max-width: none; }

	.obb-panel-acciones .obb-dt-acc .obb-btn {
		flex: 1 1 auto;
		max-width: none;
		width: 100%;
		justify-content: flex-start;
		min-height: var(--c-sm);
		padding: var(--e-2) var(--e-3);
	}

	.obb-dt-chev { display: inline-flex; margin-left: auto; opacity: .8; }

	/* Guardar a lo ancho, pero con altura contenida. */
	.obb-dt-asignar > .obb-campo { flex: 1 1 100%; }

	.obb-ficha-datos-edit > .obb-dt-asignar > .obb-btn { width: 100%; min-width: 0; }

	.obb-panel-notas .obb-dt-notas-pie .obb-btn { width: 100%; min-width: 0; }

	.obb-dt-nota-campo textarea { min-height: 76px; }
}

/*
 * La cabecera se reorganiza sola: mientras el identificador y el badge
 * caben juntos van en una linea -la composicion de escritorio y tablet-,
 * y cuando no caben el badge baja a la suya en vez de estrangular al ID.
 * Sin punto de corte fijo: depende del texto real del estado.
 */
.obb-panel-ficha .obb-dt-cab { flex-wrap: wrap; row-gap: var(--e-2); }

/* No crece: si creciera se comeria el hueco libre y empujaria al badge a
   la segunda linea incluso con estados cortos que caben de sobra. */
.obb-dt-id { flex: 0 1 auto; }

.obb-panel-ficha .obb-dt-cab > .obb-badge { flex: 0 0 auto; margin-left: auto; }

/* ==========================================================================
   Actualizar Servicio · Cambio 5
   Los cuatro estados comparten esqueleto: cabecera, selector segmentado,
   formulario en rejilla y cierre con Notas + Actualizar en la misma zona.
   Clases propias «obb-ac-*»; el resto del portal no se toca.
   ========================================================================== */

/* ---------------------------------------------- Cabecera del servicio */

.obb-ac-cab {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--e-3);
	flex-wrap: wrap;
	row-gap: var(--e-2);
	padding: var(--e-3) var(--e-4);
	margin-bottom: var(--e-3);
}

.obb-ac-cab-txt { min-width: 0; flex: 0 1 auto; }

.obb-ac-cab-txt strong { display: block; font-size: var(--t-md); line-height: 1.25; }

/* [LOCAL-61] La pareja de píldoras se coloca igual que la píldora sola: a la
   derecha de la cabecera. Sin esta línea el `margin-left:auto` no alcanzaba a
   la envoltura y la pareja se quedaba pegada al texto. */
.obb-ac-cab > .obb-badge,
.obb-ac-cab > .obb-badge-par { flex: 0 0 auto; margin-left: auto; }

.obb-ac-dir {
	display: flex;
	align-items: center;
	gap: var(--e-1);
	color: var(--tinta-2);
	font-size: var(--t-sm);
	margin-top: 2px;
	overflow-wrap: anywhere;
}

.obb-ac-dir .obb-ico { color: var(--tinta-3); flex: 0 0 auto; }

/* ---------------------------------------------- Selector de estado */

/* Cuatro opciones de igual peso, sin franjas ni scroll horizontal. */
.obb-ac-estados {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: var(--e-2);
	margin-bottom: var(--e-3);
}

.obb-ac-estados .obb-estado-chip {
	min-height: 46px;
	padding: var(--e-2) var(--e-3);
	font-size: var(--t-sm);
	gap: var(--e-2);
}

/* ---------------------------------------------- Formulario */

.obb-ac-form { padding: var(--e-4); }

.obb-ac-h {
	display: flex;
	align-items: center;
	gap: var(--e-2);
	font-size: var(--t-md);
	margin: 0 0 var(--e-3);
	padding-bottom: var(--e-2);
	border-bottom: 1px solid var(--linea);
}

.obb-ac-h .obb-ico { color: var(--azul); flex: 0 0 auto; }

.obb-ac-fila {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--e-3);
	align-items: end;
	margin-bottom: var(--e-3);
}

.obb-ac-fila > .obb-campo { margin: 0; min-width: 0; }

/* Sufijo de moneda dentro del propio campo. */
.obb-ac-euro { position: relative; }

.obb-ac-euro > span:first-child { display: block; }

.obb-ac-euro::after {
	content: "€";
	position: absolute;
	right: var(--e-3);
	bottom: 0;
	height: var(--c-md);
	display: flex;
	align-items: center;
	color: var(--tinta-3);
	font-weight: 650;
	pointer-events: none;
}

.obb-ac-euro input { padding-right: var(--e-6); }

/* ---------------------------------------------- Switch de IVA

   Es el MISMO checkbox de siempre: cambia su aspecto, no su valor ni su
   identificador. Sigue recibiendo foco y responde a teclado porque no se
   oculta: se dibuja con appearance: none. */

/* Gana a «.obb-campo > span», que si no lo trataria como el rotulo del
   campo: en mayusculas, en bloque y con el texto debajo del control. */
.obb .obb-ac-iva > .obb-switch {
	display: flex;
	align-items: center;
	gap: var(--e-2);
	min-height: var(--c-md);
	margin: 0;
	text-transform: none;
	letter-spacing: normal;
	font-size: var(--t-base);
	color: var(--tinta);
}

.obb .obb-switch input[type="checkbox"] {
	appearance: none;
	-webkit-appearance: none;
	flex: 0 0 auto;
	width: 46px;
	min-width: 46px;
	height: 26px;
	/* `.obb-campo input` impone min-height 50: sin esto el switch salia
	   como un ovalo alto. */
	min-height: 26px;
	max-height: 26px;
	margin: 0;
	border-radius: var(--r-pill);
	background: var(--linea-2);
	border: 0;
	position: relative;
	cursor: pointer;
	transition: background-color .15s ease;
}

.obb .obb-switch input[type="checkbox"]::after {
	content: "";
	position: absolute;
	top: 3px;
	left: 3px;
	width: 20px;
	height: 20px;
	border-radius: var(--r-pill);
	background: var(--blanco);
	box-shadow: 0 1px 2px rgba(2, 23, 75, .3);
	transition: transform .15s ease;
}

.obb .obb-switch input[type="checkbox"]:checked { background: var(--azul); }

.obb .obb-switch input[type="checkbox"]:checked::after { transform: translateX(20px); }

.obb-switch-txt { font-weight: 650; font-size: var(--t-sm); }

@media (prefers-reduced-motion: reduce) {

	.obb .obb-switch input[type="checkbox"],
	.obb .obb-switch input[type="checkbox"]::after { transition: none; }
}

/* ---------------------------------------------- Ayuda y resumen */

.obb-ac-info {
	display: flex;
	align-items: flex-start;
	gap: var(--e-2);
	margin: 0 0 var(--e-3);
}

.obb-ac-info .obb-ico { color: var(--tinta-3); flex: 0 0 auto; margin-top: 2px; }

.obb-ac-resumen {
	border: 1px solid var(--linea);
	border-radius: var(--r-input);
	background: var(--realce);
	padding: var(--e-3);
	margin-bottom: var(--e-3);
}

.obb-ac-resumen-h {
	display: flex;
	align-items: center;
	gap: var(--e-2);
	font-size: var(--t-2xs);
	font-weight: 700;
	letter-spacing: .02em;
	text-transform: uppercase;
	color: var(--tinta-2);
	margin-bottom: var(--e-2);
}

.obb-ac-resumen-h .obb-ico { color: var(--azul); }

.obb-ac-resumen .obb-totales { margin: 0; }

.obb-ac-factura { margin-bottom: var(--e-3); }

/* Panel de datos fiscales · oculto hasta que se marca la factura.
   Clase propia para no depender de la utilidad global `.obb-oculto`,
   que otros modulos usan como texto para lectores de pantalla. */
.obb-ac-fiscal { display: none; }

.obb-ac-fiscal > .obb-campo { margin-bottom: var(--e-3); }

.obb-ac-fiscal textarea { min-height: 116px; }

/* ---------------------------------------------- Cierre · Notas + Actualizar */

.obb-ac-cierre {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: var(--e-3);
	align-items: end;
}

.obb-ac-notas { margin: 0; min-width: 0; }

.obb-ac-notas textarea { min-height: 92px; }

.obb-ac-cierre-btn { display: flex; align-items: flex-end; }

/* Ancho contenido: el necesario para icono, texto y aire. */
.obb .obb-ac-guardar {
	min-height: var(--c-md);
	min-width: 13rem;
	padding: var(--e-3) var(--e-5);
	gap: var(--e-2);
}

/* ---------------------------------------------- Tablet */

@media (max-width: 1023px) {

	.obb-ac-notas textarea { min-height: 80px; }
}

/* Por debajo de 768 px las tres columnas del cobro aprietan: el importe y
   el impuesto se emparejan y el selector ocupa la fila. */
@media (max-width: 767px) {

	.obb-ac-fila-cobro { grid-template-columns: repeat(2, minmax(0, 1fr)); }

	.obb-ac-fila-cobro > .obb-campo:first-child { grid-column: 1 / -1; }
}

/* Por debajo de 900 px el textarea y el botón dejan de convivir cómodos:
   el botón baja y se alinea a la derecha, sin estirarse. */
@media (max-width: 899px) {

	.obb-ac-cierre { grid-template-columns: minmax(0, 1fr); }

	.obb-ac-cierre-btn { justify-content: flex-end; }
}

/* ---------------------------------------------- Móvil */

@media (max-width: 639px) {

	/* 2 × 2: cuatro columnas dejarían los textos ilegibles. */
	.obb-ac-estados { grid-template-columns: repeat(2, minmax(0, 1fr)); }

	.obb-ac-fila { grid-template-columns: minmax(0, 1fr); gap: var(--e-2); }

	/* Dos por fila: en una sola columna el formulario se alargaba más que
	   el diseño anterior, y con cuatro no se leen las cifras. */
	.obb-ac-fila-cobro,
	.obb-ac-fila-mat { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--e-2); }

	.obb-ac-fila-mat > .obb-campo:last-child { grid-column: 1 / -1; }

	.obb-ac-form { padding: var(--e-3); }

	.obb-ac-notas textarea { min-height: 80px; }

	.obb-ac-cierre-btn { justify-content: stretch; }

	.obb .obb-ac-guardar { width: 100%; min-width: 0; min-height: var(--c-sm); }
}

/* Pantallas muy estrechas: los rótulos de estado pierden su icono, igual
   que ya hacían las pestañas del portal. */
@media (max-width: 359px) {

	.obb-ac-estados .obb-estado-chip .obb-ico { display: none; }
}

/* ==========================================================================
   Portales Empresa y Operario · LOCAL-54
   Una sola arquitectura para Nuevo Servicio, Inicio de la empresa y Mi
   Cuenta: misma cabecera de tarjeta, misma rejilla de formulario, mismos
   botones y los mismos tres tramos responsive. Reutiliza los tokens y las
   clases existentes; no duplica reglas ni pisa otras vistas.
   ========================================================================== */

/* ------------------------------------------------ Cabecera de tarjeta */

.obb-bloque-cab {
	display: flex;
	align-items: flex-start;
	gap: var(--e-3);
	margin-bottom: var(--e-3);
	padding-bottom: var(--e-2);
	border-bottom: 1px solid var(--linea);
}

.obb-bloque-ico {
	flex: 0 0 auto;
	width: 36px;
	height: 36px;
	border-radius: var(--r-input);
	background: var(--azul-suave);
	color: var(--azul);
	display: flex;
	align-items: center;
	justify-content: center;
}

.obb-bloque-txt { min-width: 0; }

.obb-bloque .obb-bloque-cab h3 { margin: 0; }

.obb-bloque-sub {
	display: block;
	margin-top: 2px;
	font-size: var(--t-sm);
	font-weight: 500;
	color: var(--tinta-2);
	text-transform: none;
	letter-spacing: normal;
}

/* ------------------------------------------------ Rejilla de formulario */

/* Dos columnas en escritorio. Los campos largos y los cierres ocupan la
   fila entera con «obb-form-full». */
.obb-form {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--e-3) var(--e-4);
	align-items: start;
}

.obb-form > .obb-campo,
.obb-form .obb-form-tel .obb-campo { margin-bottom: 0; }

.obb-form-full { grid-column: 1 / -1; }

.obb-form-tel { min-width: 0; }

/* El «no facilitaron telefono» cuelga de su campo, no flota suelto. */
.obb-form .obb-form-check {
	margin: var(--e-2) 0 0;
	font-size: var(--t-sm);
}

/* Notas ancha y accion a la derecha, alineadas por abajo. */
.obb-form-cierre {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: var(--e-3) var(--e-4);
	align-items: end;
}

.obb-form-cierre > .obb-campo { margin-bottom: 0; }

.obb-form-cierre textarea { min-height: 96px; }

.obb-form-cierre-btn { display: flex; justify-content: flex-end; align-items: flex-end; }

/* Guardar Cambios cierra la rejilla de Acceso, a la derecha. */
.obb-form-guardar { grid-column: 2 / -1; align-self: end; }

/* Boton medio: ni bloque ni minusculo. El mismo en las tres pantallas. */
.obb .obb-btn-medio {
	min-height: var(--c-md);
	min-width: 12rem;
	padding: var(--e-3) var(--e-5);
	gap: var(--e-2);
}

/* ------------------------------------------------ Inicio de la empresa */

/* Resumen y accion juntos en la zona superior. */
.obb-inicio-cab {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
	gap: var(--e-3);
	margin-bottom: var(--e-3);
	align-items: stretch;
}

.obb-inicio-cab > .obb-kpi { margin: 0; height: 100%; }

/* ------------------------------------------------ Tarjeta de accion */

.obb-ta {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--e-3);
	flex-wrap: wrap;
	width: 100%;
	min-width: 0;
}

.obb-ta-txt {
	display: flex;
	align-items: flex-start;
	gap: var(--e-3);
	min-width: 0;
	flex: 1 1 18rem;
	text-align: left;
}

.obb-ta-txt strong { display: block; font-size: var(--t-base); line-height: 1.3; }

.obb-ta-ico {
	flex: 0 0 auto;
	width: 36px;
	height: 36px;
	border-radius: var(--r-input);
	background: var(--azul-suave);
	color: var(--azul);
	display: flex;
	align-items: center;
	justify-content: center;
}

.obb-ta-sub {
	display: block;
	margin-top: 2px;
	font-size: var(--t-sm);
	color: var(--tinta-2);
	font-weight: 500;
}

.obb-ta-cta { flex: 0 0 auto; }

.obb-ta-cta .obb-btn { margin: 0; }

.obb-ta-panel .obb-ta-cta .obb-linea-acciones { margin: 0; }

/* La tarjeta entera del Inicio es pulsable: se comporta como boton pero
   conserva el aspecto de tarjeta. */
.obb .obb-ta-boton {
	display: flex;
	background: var(--blanco);
	border: 1px solid var(--linea);
	border-radius: var(--r-card);
	padding: var(--e-3) var(--e-4);
	cursor: pointer;
	text-align: left;
	width: 100%;
}

.obb .obb-ta-boton:hover { border-color: var(--azul); }

.obb .obb-ta-boton .obb-ta-cta {
	pointer-events: none;
	display: inline-flex;
	align-items: center;
}

/* ------------------------------------------------ Tablet */

@media (max-width: 1023px) {

	/* Cliente y Telefono pasan a ancho completo; Codigo y Tipo siguen
	   compartiendo fila mientras se lean comodos. */
	.obb-form > .obb-campo:first-child,
	.obb-form > .obb-form-tel { grid-column: 1 / -1; }

	/* En Mi Cuenta el formulario se lee mejor en vertical. */
	.obb-bloque-vertical .obb-form { grid-template-columns: minmax(0, 1fr); }

	.obb-bloque-vertical .obb-form-guardar { grid-column: 1 / -1; }

	.obb-bloque-vertical .obb-form-guardar .obb-btn,
	.obb-bloque-vertical .obb-form-cierre-btn .obb-btn { width: 100%; }

	.obb-inicio-cab { grid-template-columns: repeat(2, minmax(0, 1fr)); }

	.obb-ta { flex-wrap: wrap; }

	.obb-ta-panel .obb-ta-cta { flex: 1 1 100%; }

	.obb-ta-panel .obb-ta-cta .obb-btn { width: 100%; }
}

/* ------------------------------------------------ Movil */

@media (max-width: 639px) {

	.obb-form { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--e-2) var(--e-3); }

	/* Todo a una columna salvo Codigo y Tipo, que caben en pareja. */
	.obb-form > .obb-campo { grid-column: 1 / -1; }

	.obb-form > .obb-campo.obb-form-par { grid-column: auto; }

	.obb-form-cierre { grid-template-columns: minmax(0, 1fr); }

	.obb-form-cierre-btn,
	.obb-form-guardar { grid-column: 1 / -1; justify-content: stretch; }

	.obb-form-cierre-btn .obb-btn,
	.obb-form-guardar .obb-btn { width: 100%; min-width: 0; }

	.obb-inicio-cab { grid-template-columns: minmax(0, 1fr); }

	.obb-ta-cta { flex: 1 1 100%; }

	.obb-ta-cta .obb-btn { width: 100%; min-width: 0; }

	.obb .obb-ta-boton .obb-ta-cta { justify-content: center; }
}

/* Por debajo de 360 px la pareja Codigo + Tipo tambien se apila. */
@media (max-width: 359px) {

	.obb-form > .obb-campo.obb-form-par { grid-column: 1 / -1; }
}

/* ==========================================================================
   [LOCAL-56 · CAMBIO 1] ALTA DEL ADMINISTRADOR · rejilla de TRES columnas
   --------------------------------------------------------------------------
   Variante de `.obb-form`, no un sistema nuevo: hereda cabecera, campos,
   cierre y botones de LOCAL-54 y solo cambia el numero de columnas y los
   cortes responsive. PC 3 · tablet 2 · movil 1.
   ========================================================================== */

.obb-form.obb-form-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* Asterisco de obligatorio: rojo, pegado a la etiqueta. */
.obb .obb-oblig { color: var(--rojo); font-weight: 800; }

/*
 * Bloque intermedio de la fila 2. Se alinea por abajo con el campo de
 * texto que tiene al lado, para que LLAMAR quede a la altura del input y
 * no flotando junto a la etiqueta.
 */
.obb-form-3 .obb-form-medio {
	min-width: 0;
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
	padding-top: calc(var(--t-sm) + 9px);
}

.obb .obb-form-llamar {
	min-height: var(--c-md);
	width: 100%;
	gap: var(--e-2);
	margin: 0;
}

/* Sin numero escrito el boton esta, pero no invita a pulsarlo. */
.obb .obb-form-llamar[aria-disabled="true"] {
	opacity: .5;
	pointer-events: none;
}

.obb-form-3 .obb-form-medio .obb-form-check {
	margin: var(--e-2) 0 0;
	font-size: var(--t-sm);
}

/* El aviso de reparto no deja hueco cuando no hay nada que decir. */
.obb-form-3 #r-acuerdo-aviso:empty { display: none; }
.obb-form-3 #r-reparto[hidden] { display: none; }

/* ---- TABLET · dos columnas ---- */
@media (max-width: 1023px) {

	.obb-form.obb-form-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

	/*
	 * La regla general de `.obb-form` manda a ancho completo el primer
	 * campo y el bloque del telefono. En tres columnas eso rompia la
	 * jerarquia pedida, asi que aqui se neutraliza.
	 */
	.obb-form.obb-form-3 > .obb-campo:first-child,
	.obb-form.obb-form-3 > .obb-form-tel { grid-column: auto; }

	/*
	 * Con dos columnas el bloque intermedio ya no esta al lado del campo
	 * de telefono, asi que reservar la altura de su etiqueta dejaba un
	 * hueco vacio encima. Aqui LLAMAR y la casilla van en linea.
	 */
	.obb-form-3 .obb-form-medio {
		padding-top: 0;
		flex-direction: row;
		align-items: center;
		flex-wrap: wrap;
		gap: var(--e-2) var(--e-3);
	}

	.obb-form-3 .obb-form-medio .obb-form-llamar { width: auto; min-width: 9rem; }

	.obb-form-3 .obb-form-medio .obb-form-check { margin: 0; }
}

/* ---- MOVIL · una columna, mismo orden logico ---- */
@media (max-width: 639px) {

	.obb-form.obb-form-3 { grid-template-columns: minmax(0, 1fr); }

	.obb-form.obb-form-3 > .obb-campo,
	.obb-form.obb-form-3 > .obb-form-medio { grid-column: 1 / -1; }

	/* En una sola columna el boton ya no necesita reservar la altura
	   de una etiqueta que no tiene encima. */
	.obb-form-3 .obb-form-medio { padding-top: 0; }
}

/* ==========================================================================
   [LOCAL-56 · CAMBIO 3] MODALIDAD FIJADA POR LA EMPRESA
   --------------------------------------------------------------------------
   Se enseña como dato, no como control: el administrador no la elige.
   ========================================================================== */

.obb .obb-modalidad-fija {
	display: flex;
	flex-direction: column;
	gap: 2px;
	padding: var(--e-3);
	border: 1px solid var(--linea);
	border-radius: var(--r-input);
	background: var(--azul-suave);
	margin-bottom: var(--e-3);
}

.obb .obb-modalidad-fija-et {
	font-size: var(--t-xs);
	font-weight: 800;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--tinta-2);
}

.obb .obb-modalidad-fija strong { font-size: var(--t-base); color: var(--azul-osc); }

/* ==========================================================================
   [LOCAL-56 · CAMBIO 2] HISTORIAL DE CUENTAS
   --------------------------------------------------------------------------
   Dos acciones por cuenta -ver y descargar- y las dos pestañas del
   administrador. Reutiliza `.obb-tabs`, que ya existe en Servicios y en
   Usuarios: no se estrena otro componente de pestañas.
   ========================================================================== */

.obb .obb-cuenta-acciones {
	display: flex;
	flex-wrap: wrap;
	gap: var(--e-2);
	justify-content: flex-end;
}

.obb .obb-cuenta-acciones .obb-btn { margin: 0; white-space: nowrap; }

/* Contador junto al nombre de la pestaña. */
.obb .obb-tab-n {
	margin-left: var(--e-2);
	padding: 1px 7px;
	border-radius: 999px;
	background: rgba(0, 0, 0, .08);
	font-size: var(--t-xs);
	font-weight: 800;
}

.obb .obb-tabs button.act .obb-tab-n { background: rgba(255, 255, 255, .28); }

@media (max-width: 639px) {

	/* En movil las dos acciones ocupan el ancho y no se parten. */
	.obb .obb-cuenta-acciones { width: 100%; }

	.obb .obb-cuenta-acciones .obb-btn { flex: 1 1 8rem; justify-content: center; }
}

/* =====================================================================
   [LOCAL-62] P01 · CABECERA DE MODAL, CERRAR Y ACCIONES COMPACTAS

   Se anade al final a proposito. El bloque de `.obb-ac-num` esta en la
   linea 1969 y es GLOBAL -lo comparten las tablas de modalidades, de
   porcentajes y de cuentas-, asi que no se toca: se corrige POR
   EXCEPCION para las dos celdas de acciones que lo necesitan. Cambiar la
   regla global habria afectado a mas pantallas de las que pide P01.
   ===================================================================== */

/* --- Cabecera del modal: titulo a la izquierda, cerrar arriba a la derecha */
.obb .obb-modal-cab {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--e-3);
	margin-bottom: var(--e-2);
}

/* El <h3> conserva su estilo; solo deja de ocupar todo el ancho. */
.obb .obb-modal-cab > h3 {
	margin: 0;
	flex: 1 1 auto;
	min-width: 0;
}

/*
 * El boton de cerrar. 44px es el minimo tactil que ya usa el resto del
 * portal (--c-sm), asi que en movil es igual de alcanzable que cualquier
 * otro boton y no consume ancho de contenido: va en la cabecera, no en
 * una fila propia.
 */
.obb .obb-modal-x {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--c-sm);
	height: var(--c-sm);
	padding: 0;
	border: 1px solid var(--linea-2);
	border-radius: var(--r-input);
	background: var(--blanco);
	color: var(--tinta-2);
	cursor: pointer;
	transition: background .15s ease, color .15s ease, border-color .15s ease;
}

.obb .obb-modal-x:hover,
.obb .obb-modal-x:focus-visible {
	background: var(--gris);
	color: var(--tinta);
	border-color: var(--gris-claro);
}

/* --- §5.2 · [ CREAR MODALIDAD ] [ CERRAR ] a la par ------------------- */
.obb .obb-modal-par {
	display: flex;
	flex-wrap: wrap;
	gap: var(--e-2);
	margin-top: var(--e-3);
}

/*
 * Crear es la accion principal y se queda con el espacio sobrante; Cerrar
 * toma solo el suyo. Al no caber, `flex-wrap` los pone uno debajo del otro
 * a ancho completo, que es lo que §5.2 pide para movil: no comprimidos.
 */
.obb .obb-modal-par > .obb-btn:first-child { flex: 1 1 12rem; justify-content: center; }
.obb .obb-modal-par > .obb-btn + .obb-btn   { flex: 0 1 8rem;  justify-content: center; }

/* --- §5.3 · acciones compactas sin scroll horizontal ----------------- */
/*
 * La causa del scroll era `.obb-ac-num { white-space: nowrap }` (linea
 * 1969), global y fuera de toda media query: los tres botones no podian
 * partirse NUNCA por encima de 640px, y el modal solo tiene 540px. El
 * arreglo responsive existia, pero solo por debajo de 640px.
 *
 * Aqui se cubre el hueco: de 641px hacia arriba, y tambien dentro del
 * modal en escritorio, que es donde se veia el problema.
 */
.obb .obb-acc-compactas {
	white-space: normal;
	display: flex;
	flex-wrap: wrap;
	gap: var(--e-2);
	justify-content: flex-end;
	align-items: center;
}

/* Misma altura, padding reducido, y texto que no se parte dentro del boton. */
.obb .obb-acc-compactas .obb-btn {
	flex: 0 1 auto;
	min-height: 36px;
	padding: var(--e-1) var(--e-2);
	font-size: var(--t-sm);
	white-space: nowrap;
	gap: var(--e-1);
	line-height: 1.15;
}

/* Los iconos de las acciones, al tamano del texto. */
.obb .obb-acc-compactas .obb-btn svg {
	width: 14px;
	height: 14px;
	flex: 0 0 auto;
}

/*
 * En movil manda el bloque de 640px que ya existe (rejilla de 2 columnas y
 * 44px de alto): ahi las acciones son el contenido principal de la tarjeta
 * y deben ser grandes. Se le devuelve la prioridad.
 */
@media (max-width: 640px) {

	.obb .obb-acc-compactas { display: grid; justify-content: stretch; }

	/*
	 * `white-space: normal` AQUI es obligatorio, no cosmetico.
	 *
	 * La regla base pone `nowrap` para que el texto no se parta dentro del
	 * boton en escritorio. En movil las acciones van en una rejilla de dos
	 * columnas, y a 320px cada columna mide unos 120px: con `nowrap`,
	 * «Predeterminada» no cabe y desbordaba la tarjeta -medido: 297px de
	 * contenido en 272px de caja-. Aqui el boton ocupa el ancho completo de su
	 * columna, asi que partir el texto en dos lineas es lo correcto.
	 */
	.obb .obb-acc-compactas .obb-btn {
		min-height: var(--c-sm);
		height: auto;
		padding: var(--e-2) var(--e-2);
		justify-content: center;
		white-space: normal;
		text-align: center;
		word-break: break-word;
	}
}

/*
 * Por debajo de 420px dos columnas no caben sin partir el texto, y partirlo
 * dejaba un boton de 48px junto a otros de 44: alturas distintas, que §5.3
 * prohibe. Una sola columna a ancho completo: misma altura, una linea cada
 * uno, y ningun boton comprimido. Cubre 390px y 320px.
 */
@media (max-width: 420px) {

	.obb .obb-tabla-mod .obb-acc-compactas,
	.obb .obb-tabla-ac .obb-acc-compactas {
		grid-template-columns: minmax(0, 1fr);
	}

	.obb .obb-acc-compactas .obb-btn { white-space: nowrap; }
}

/* ---------------------------------------------------------------------
   [LOCAL-62] El OTRO desborde del modal de Modalidades en movil estrecho.

   Medido a 320px: la celda «Modalidad» pedia 284px en 246px de caja. No son
   las acciones: es el nombre de la modalidad y su chip «Predeterminada» en
   una sola linea, porque el bloque movil de la tabla pone `display:flex` con
   `justify-content: space-between` y sin `flex-wrap`. Defecto anterior a esta
   fase, pero el criterio de §5.4 es «no scroll horizontal», asi que se
   corrige aqui.
   --------------------------------------------------------------------- */
@media (max-width: 640px) {

	.obb .obb-tabla-mod td[data-col="Modalidad"] {
		flex-wrap: wrap;
		row-gap: var(--e-1);
	}

	/* El nombre puede encogerse y partirse; el chip baja de linea si hace falta. */
	.obb .obb-tabla-mod td[data-col="Modalidad"] > strong {
		min-width: 0;
		word-break: break-word;
	}

	.obb .obb-tabla-mod td[data-col="Modalidad"] .obb-chip { flex: 0 0 auto; }
}

/* =====================================================================
   [LOCAL-62 · P04] TARJETA DE SERVICIO · `obb-reg-*`

   Sustituye a `obb-rg-*` (LOCAL-49). Prefijo nuevo y comprobado libre:
   `obb-tj-*` ya estaba ocupado por el componente muerto
   `.obb-tarjeta-v2`, y reutilizarlo habria sido una trampa.

   UN SOLO DOM para PC, tablet y movil. Lo que cambia por anchura es QUE
   celdas se ven, nunca el contenido, asi que no hay dos componentes que
   se desincronicen ni ningun dato pintado dos veces.
   ===================================================================== */

/* --- La lista. UNA sola declaracion, y aqui se arregla P03 ------------ */
/*
 * `align-items: stretch` es explicito a proposito: es lo que garantiza que
 * todas las tarjetas tengan el MISMO ancho, el mismo inicio y el mismo
 * final. No se deja al valor por defecto para que no vuelva a filtrarse un
 * `start` de otro bloque, que es lo que causo la desalineacion.
 */
.obb .obb-lista {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: var(--e-2);
	width: 100%;
	margin: 0;
	padding: 0;
}

/* --- La tarjeta ------------------------------------------------------- */
/*
 * §8.2 · trazo negro en TODAS, sea cual sea el fondo. Fino y consistente:
 * 1px, no mas. El radio se hereda en los hijos con `overflow: hidden`.
 */
.obb .obb-reg {
	display: block;
	width: 100%;
	box-sizing: border-box;
	border: 1px solid #000;
	border-radius: 10px;
	overflow: hidden;
	background: #f0f4f8;
	color: var(--tinta);
}

/* --- §8.3 y §8.11 · los dos tonos de los servicios asignados ---------- */
.obb .obb-reg.obb-reg-t0 { background: #e8ecf0; }
.obb .obb-reg.obb-reg-t1 { background: #f0f4f8; }

/* --- §8.8 a §8.10 · los estados con color propio ---------------------- */
.obb .obb-reg.obb-reg-e-cobrado      { background: #e2f4e6; }
.obb .obb-reg.obb-reg-e-ppto_enviado { background: #d2c5fc; }
.obb .obb-reg.obb-reg-e-con_cita     { background: #fff1c7; }
.obb .obb-reg.obb-reg-e-nulo         { background: #fadfdb; }

/* --- Cabecera: la tarjeta cerrada ------------------------------------- */
/*
 * Rejilla con columnas NOMBRADAS, no por conteo de hijos.
 *
 * El componente anterior usaba `:has(> :nth-child(5):last-child)` para
 * repartir las columnas segun cuantas celdas pintaba el rol. Eso daba un
 * numero de columnas distinto para admin, empresa y operario, y es
 * justamente lo que §9 pide evitar. Con areas nombradas, la celda que un
 * rol no ve simplemente no ocupa su area y las demas no se mueven.
 */
.obb .obb-reg-cab {
	display: grid;
	/*
	 * [LOCAL-62 · D] Reparto ajustado a las capturas: el identificador
	 * necesita sitio para «CÓDIGO CONTROL» entero, y el estado para que
	 * «SIN ASIGNAR» no se parta en dos lineas. La fecha, ahora con rotulo
	 * corto, cede lo que les hacia falta.
	 */
	grid-template-columns:
		minmax(0, 2fr)     /* cliente            */
		minmax(0, 1.05fr)  /* ids                */
		minmax(0, .9fr)    /* empresa            */
		minmax(0, .9fr)    /* cobrado / IVA      */
		minmax(0, 1.15fr)  /* estado             */
		minmax(0, 1.05fr)  /* detalle            */
		minmax(0, .7fr)    /* fecha              */
		44px;              /* chevron            */
	align-items: center;
	gap: var(--e-3);
	/* [LOCAL-62 · D] Mas compacta: las capturas de referencia tienen las
	   tarjetas bastante mas bajas que la primera version. */
	padding: 8px var(--e-3);
}

.obb .obb-reg-celda { min-width: 0; }

/*
 * [LOCAL-62 · D] Separadores finos entre columnas, como en las capturas.
 * Van en el borde IZQUIERDO de cada celda menos la primera, de modo que no
 * sobra ninguna raya al final de la fila ni se descuadra la rejilla.
 * El chevron no lleva raya: es un control, no un dato.
 */
@media (min-width: 701px) {
	.obb .obb-reg-cab > .obb-reg-celda + .obb-reg-celda:not(.obb-reg-c-chev) {
		border-left: 1px solid rgba(16, 28, 48, .09);
		padding-left: var(--e-3);
	}
}

/*
 * La etiqueta de cada dato. En PC se ve pequena encima del valor.
 *
 * [LOCAL-62 · D] Mas pequena y con menos espaciado entre letras que antes:
 * medido en navegador, «FECHA DEL SERVICIO» y «CODIGO CONTROL» se partian en
 * dos lineas y estiraban la tarjeta muy por encima de la altura de las
 * capturas de referencia. Ahora caben en una sola linea.
 */
.obb .obb-reg-et {
	display: block;
	font-size: 9.5px;
	font-weight: 700;
	letter-spacing: .02em;
	text-transform: uppercase;
	color: #5d6b80;
	margin-bottom: 1px;
	line-height: 1.15;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.obb .obb-reg-val {
	min-width: 0;
	font-size: var(--t-sm);
	line-height: 1.3;
	overflow-wrap: anywhere;
}

.obb .obb-reg-vacio { color: #7d8799; }

/* --- Cliente: inicial, nombre y direccion ---------------------------- */
.obb .obb-reg-c-cli {
	display: flex;
	align-items: center;
	gap: var(--e-2);
	min-width: 0;
}

.obb .obb-reg-avatar {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	border: 1px solid #000;
	background: rgba(255, 255, 255, .72);
	font-weight: 700;
	font-size: 13px;
}

.obb .obb-reg-cli-meta { min-width: 0; display: block; }

.obb .obb-reg-nom {
	display: block;
	font-weight: 700;
	font-size: var(--t-sm);
	line-height: 1.25;
	overflow-wrap: anywhere;
}

.obb .obb-reg-dir {
	display: block;
	font-size: 12px;
	color: #5d6b80;
	line-height: 1.25;
	overflow-wrap: anywhere;
}

/* --- ID y codigo de control ------------------------------------------ */
.obb .obb-reg-c-ids .obb-reg-et-cc { margin-top: var(--e-1); }
.obb .obb-mono { font-variant-numeric: tabular-nums; }

/* --- Cobrado / IVA --------------------------------------------------- */
.obb .obb-reg-eur { font-weight: 700; white-space: nowrap; }
.obb .obb-reg-iva { color: #4a5668; white-space: nowrap; }

/* --- §8.7 · estado y, si hay cita, su fecha y hora ------------------- */
.obb .obb-reg-c-est .obb-reg-val {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 3px;
}

/*
 * La pildora de estado es la compartida `.obb-badge`, que esta en
 * `white-space: nowrap` A PROPOSITO para tablas y modales, donde una etiqueta
 * partida en dos lineas descoloca la fila. Dentro de la tarjeta eso no vale:
 * medido en navegador, en la banda 768-1024px la columna de estado baja a
 * 83-105px y «Presupuesto enviado» ocupa 196px, de modo que la pildora salia
 * 44px por fuera del borde de la tarjeta. Aqui -y SOLO aqui- se le permite
 * repartir el texto en varias lineas. La regla global no se toca: fuera de la
 * tarjeta la pildora sigue en una sola linea.
 *
 * `overflow-wrap: anywhere` es la red de seguridad para que ninguna palabra
 * larga por si sola pueda volver a desbordar en una anchura futura.
 */
.obb .obb-reg .obb-badge {
	white-space: normal;
	/*
	 * `break-word`, no `anywhere`: con `anywhere` el navegador parte tambien
	 * a mitad de palabra en cuanto va justo, y en movil salia «ASIGNAD / O».
	 * Con `break-word` reparte por los espacios -«Presupuesto enviado» en dos
	 * lineas, que es lo que resolvia el desbordamiento- y solo trocea una
	 * palabra si ella sola no cabe de ninguna manera.
	 */
	overflow-wrap: break-word;
	text-align: left;
}

/*
 * La fecha y hora de la cita. Va DEBAJO de la pildora y con su propio
 * aspecto para que no se confunda con la fecha del servicio, que tiene
 * celda aparte: son dos datos distintos y §8.7 exige que se distingan.
 */
.obb .obb-reg-cita {
	display: inline-block;
	font-size: 11.5px;
	font-weight: 700;
	white-space: nowrap;
	padding: 1px 6px;
	border: 1px solid #000;
	border-radius: var(--r-pill);
	background: rgba(255, 255, 255, .66);
}

/* --- Botones de la tarjeta ------------------------------------------- */
.obb .obb-reg-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--e-1);
	min-height: 34px;
	padding: 5px 10px;
	border: 1px solid #000;
	border-radius: 8px;
	background: rgba(255, 255, 255, .8);
	color: var(--tinta);
	font-size: 12.5px;
	font-weight: 600;
	line-height: 1.15;
	text-decoration: none;
	cursor: pointer;
	white-space: nowrap;
}

.obb .obb-reg-btn:hover,
.obb .obb-reg-btn:focus-visible { background: #fff; }

.obb .obb-reg-btn svg { width: 14px; height: 14px; flex: 0 0 auto; }

/*
 * [LOCAL-62 · D] «Detalle del Servicio» en azul suave relleno, como en las
 * capturas. Es la accion principal de la tarjeta cerrada y antes se veia
 * igual que el resto de botones de contorno negro, sin destacar.
 */
.obb .obb-reg-btn-detalle {
	width: 100%;
	border-color: #bcd3f2;
	background: #e8f1fd;
	color: #12418c;
	font-weight: 700;
}

.obb .obb-reg-btn-detalle:hover,
.obb .obb-reg-btn-detalle:focus-visible {
	background: #d8e7fb;
	border-color: #9dbff0;
}

.obb .obb-reg-ver {
	border: 0;
	background: none;
	padding: 0 2px;
	color: #1558b0;
	font-size: 12px;
	font-weight: 700;
	cursor: pointer;
	text-decoration: underline;
}

/* --- §8.12 · el chevron ---------------------------------------------- */
.obb .obb-reg-c-chev {
	display: flex;
	align-items: center;
	justify-content: flex-end;
}

/*
 * [LOCAL-62 · D] El chevron, ajustado a las capturas de referencia: un BOTON
 * REDONDO, blanco, con sombra suave, y la punta MIRANDO ABAJO cuando la
 * tarjeta esta cerrada.
 *
 * Antes era un cuadrado redondeado y el icono apuntaba a la DERECHA; al
 * abrir giraba 180 grados, asi que pasaba a apuntar a la IZQUIERDA. Ninguna
 * de las dos posiciones decia «esto se despliega hacia abajo». El giro vive
 * ahora en el ICONO, no en el boton, para que el aro de foco no se mueva.
 */
.obb .obb-reg-chev {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--c-sm);
	height: var(--c-sm);
	padding: 0;
	border: 1px solid #d7deea;
	border-radius: 50%;
	background: #fff;
	box-shadow: 0 1px 3px rgba(16, 28, 48, .14);
	color: var(--tinta);
	cursor: pointer;
	transition: background .15s ease, box-shadow .15s ease;
}

.obb .obb-reg-chev .obb-ico {
	transition: transform .18s ease;
	transform: rotate(90deg);
}

.obb .obb-reg-chev:hover,
.obb .obb-reg-chev:focus-visible {
	background: #fff;
	box-shadow: 0 2px 6px rgba(16, 28, 48, .2);
}

/* Punta abajo = cerrada; punta arriba = expandida. */
.obb .obb-reg.obb-reg-abierta .obb-reg-chev .obb-ico { transform: rotate(-90deg); }

/* --- La segunda fila: solo al expandir ------------------------------- */
.obb .obb-reg-exp { display: none; }

.obb .obb-reg.obb-reg-abierta .obb-reg-exp {
	display: grid;
	align-items: start;
	gap: var(--e-3);
	padding: 10px var(--e-3) 12px;
	border-top: 1px solid #000;
	background: rgba(255, 255, 255, .42);
}

/*
 * [LOCAL-62 · P07] Una plantilla por numero de celdas.
 *
 * La fila lleva SEIS celdas para administrador y empresa -notas, servicio,
 * operario, telefono, material, acciones- y CINCO para el operario, que no ve
 * la columna «Operario». El renderer cuenta y lo dice en la clase, asi que aqui
 * cada caso tiene su reparto y no queda ninguna columna vacia ni ninguna celda
 * cayendose a una segunda fila.
 *
 * Acciones baja de 1.5fr a 1.25fr porque ya solo tiene dos botones: Ubicacion
 * se ha eliminado.
 */
.obb .obb-reg.obb-reg-abierta .obb-reg-exp-c6 {
	grid-template-columns:
		minmax(0, 1.7fr)   /* notas             */
		minmax(0, 1fr)     /* servicio          */
		minmax(0, 1fr)     /* operario          */
		minmax(0, 1fr)     /* telefono          */
		minmax(0, .85fr)   /* material operario */
		minmax(0, 1.25fr); /* acciones          */
}

.obb .obb-reg.obb-reg-abierta .obb-reg-exp-c5 {
	grid-template-columns:
		minmax(0, 1.7fr)   /* notas             */
		minmax(0, 1fr)     /* servicio          */
		minmax(0, 1fr)     /* telefono          */
		minmax(0, .85fr)   /* material operario */
		minmax(0, 1.25fr); /* acciones          */
}

/*
 * [P08-HF1] SIETE CELDAS · con «Cobrado por».
 *
 * Al anadir ese campo el renderer cuenta una celda mas: SIETE para
 * administrador y empresa, SEIS para el operario, que sigue sin ver la columna
 * «Operario».
 *
 * POR QUE HACE FALTA ESTA REGLA. La plantilla es de columnas EXPLICITAS. Sin
 * un `-c7`, la fila de siete celdas se quedaria sin plantilla y la septima
 * caeria a una segunda fila, desalineando rotulos y contenido. La bateria 10
 * de LOCAL-62 lo mide -compara «columnas declaradas» con «celdas»-, asi que
 * esto no es una precaucion teorica: sin la regla, la prueba se pone roja.
 *
 * EL CASO DEL OPERARIO NO NECESITA REGLA NUEVA: sus seis celdas son
 * notas · servicio · telefono · cobrado por · material · acciones, y las
 * anchuras de `-c6` les encajan una a una (1.7 · 1 · 1 · 1 · .85 · 1.25).
 *
 * VA AQUI, ANTES DE LAS MEDIA QUERIES de tablet y movil. Esas redefinen
 * `.obb-reg-exp` con la misma especificidad y ganan por orden de aparicion;
 * puesta despues, esta regla les robaria su rejilla.
 *
 * «Cobrado por» toma 1fr, el mismo ancho que Telefono y Operario: es un
 * nombre corto, de la misma clase que los que ya hay.
 */
.obb .obb-reg.obb-reg-abierta .obb-reg-exp-c7 {
	grid-template-columns:
		minmax(0, 1.3fr)   /* notas             */
		minmax(0, .95fr)   /* servicio          */
		minmax(0, .95fr)   /* operario          */
		minmax(0, 1fr)     /* telefono          */
		minmax(0, 1fr)     /* cobrado por       */
		minmax(0, 1.15fr)  /* material operario */
		minmax(0, 1.15fr); /* acciones          */
}

/*
 * POR QUE «MATERIAL OPERARIO» SUBE DE .85fr A 1.05fr.
 *
 * Medido, no estimado. Con el reparto heredado de `-c6`, al meter una septima
 * columna su rotulo pasaba de caber justo -122 px de 122 en P08 a 1366- a
 * quedarse en 107 px necesitando 108: se cortaba en «MATERIAL OPERAR…». Es el
 * rotulo mas largo de la fila, asi que es el primero que se parte.
 *
 * Se le da la holgura quitandosela a «Notas» y «Servicio», que son los que
 * mejor la soportan: Notas es texto que fluye y envuelve sin perder nada, y
 * Servicio lleva un nombre corto con icono. El total de fracciones queda en
 * 7.5fr y la estructura visual no cambia: siguen siendo las mismas columnas,
 * en el mismo orden, en una sola fila.
 *
 * El reparto se fijo midiendo el PEOR caso de PC, que es 1181 px -el pixel
 * justo antes de que entre la rejilla de tablet-, no el comodo de 1920.
 */

/*
 * [P08-HF1] NEGRITA EN EMPRESA, TELEFONO Y COBRADO POR.
 *
 * SOLO EL VALOR. Los ROTULOS de todas las celdas ya van en negrita desde
 * `.obb-reg-et { font-weight: 700 }`, asi que aqui no se toca nada de eso: lo
 * que faltaba era el dato.
 *
 * ES ADITIVO Y POR CLASE. Tres selectores concretos, uno por campo. No se
 * sustituye ninguna regla, no se baja el peso de nada y no se usa una regla
 * generica sobre `.obb-reg-val` que habria afectado tambien a cliente, estado,
 * importes, servicio, operario, notas y acciones.
 *
 * Vale para las tres anchuras: el DOM es el mismo en PC, tablet y movil.
 */
.obb .obb-reg-c-emp .obb-reg-val,
.obb .obb-reg-x-tel .obb-reg-val,
.obb .obb-reg-x-cob .obb-reg-val {
	font-weight: 700;
}

/*
 * El guion de «no hay dato» NO es un valor, asi que no se pone en negrita:
 * destacarlo lo haria parecer un dato. No se quita ninguna negrita existente
 * -`.obb-reg-vacio` nunca ha tenido-, solo se evita heredar la de arriba.
 */
.obb .obb-reg-c-emp .obb-reg-val .obb-reg-vacio,
.obb .obb-reg-x-tel .obb-reg-val .obb-reg-vacio,
.obb .obb-reg-x-cob .obb-reg-val .obb-reg-vacio {
	font-weight: 400;
}

/* El telefono no se parte a mitad de numero. */
.obb .obb-reg-tel { white-space: nowrap; }

.obb .obb-reg-serv { display: inline-flex; align-items: center; gap: var(--e-1); min-width: 0; }
.obb .obb-reg-serv-ico { display: inline-flex; flex: 0 0 auto; }
.obb .obb-reg-nota { overflow-wrap: anywhere; }

.obb .obb-reg-acciones {
	display: flex;
	flex-wrap: wrap;
	gap: var(--e-2);
}

/* =====================================================================
   TABLET · mismo modelo visual que PC, adaptado al ancho (§8.5)
   ===================================================================== */
@media (max-width: 1180px) {

	.obb .obb-reg-cab {
		/*
		 * La columna de estado lleva suelo propio -116px- porque ademas de la
		 * pildora aloja la pildora de la cita, «30/09/2026 13:00», que SI debe
		 * seguir en una sola linea: una fecha partida en dos se lee mal. Con
		 * `minmax(0, 1fr)` esta columna bajaba a 83px en 768px. Las demas
		 * siguen pudiendo encogerse, asi que el total sigue cabiendo.
		 */
		grid-template-columns:
			minmax(0, 2fr) minmax(0, .9fr) minmax(0, 1fr)
			minmax(0, 1.05fr) minmax(116px, 1fr) 44px;
		row-gap: var(--e-2);
	}

	/* Detalle y fecha bajan a una segunda linea de la cabecera. */
	.obb .obb-reg-c-det  { grid-column: 1 / 4; }
	.obb .obb-reg-c-fec  { grid-column: 4 / 6; }
	.obb .obb-reg-c-chev { grid-row: 1; grid-column: 6; }

	.obb .obb-reg.obb-reg-abierta .obb-reg-exp {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.obb .obb-reg-x-notas { grid-column: 1 / -1; }
	.obb .obb-reg-x-acc   { grid-column: 1 / -1; }
}

/* =====================================================================
   MOVIL · §8.6 · NO es la vista de PC comprimida
   ---------------------------------------------------------------------
   Cerrada:  nombre y direccion · estado (+cita) · chevron
             y debajo empresa · cobrado · fecha
   Abierta:  + codigo control · servicio · operario · material · notas
             y las acciones, incluido Detalle del Servicio
   ===================================================================== */
@media (max-width: 700px) {

	.obb .obb-reg-cab {
		grid-template-columns: minmax(0, 1fr) auto 44px;
		row-gap: var(--e-2);
		padding: var(--e-3);
	}

	.obb .obb-reg-c-cli  { grid-column: 1; grid-row: 1; }
	.obb .obb-reg-c-est  { grid-column: 2; grid-row: 1; align-items: flex-end; }
	.obb .obb-reg-c-chev { grid-column: 3; grid-row: 1; }

	.obb .obb-reg-c-est .obb-reg-val { align-items: flex-end; }

	/*
	 * [LOCAL-62 · D] Segunda zona de la tarjeta cerrada: empresa, cobrado y
	 * fecha EN TRES COLUMNAS, con el rotulo encima del valor, separadas por
	 * una raya fina y bajo una linea divisoria. Es la disposicion de las
	 * capturas de referencia en movil.
	 *
	 * Antes era una lista de filas «etiqueta a la izquierda, valor a la
	 * derecha»: ocupaba tres veces mas alto y no se parecia a la referencia.
	 */
	/*
	 * SEIS columnas, no tres: las dos filas reparten distinto. Con tres
	 * iguales el nombre se quedaba en un tercio del ancho y se partia a mitad
	 * de palabra -«F RECHAZ / O»-. Arriba el cliente se lleva la mitad, el
	 * estado un tercio y el chevron el resto; abajo los tres datos van a dos
	 * columnas cada uno, que es el tercio que pide la referencia.
	 */
	.obb .obb-reg-cab {
		grid-template-columns: repeat(6, minmax(0, 1fr));
	}

	.obb .obb-reg-c-cli  { grid-column: 1 / 4; grid-row: 1; }
	.obb .obb-reg-c-est  { grid-column: 4 / 6; grid-row: 1; }
	.obb .obb-reg-c-chev { grid-column: 6 / 7; grid-row: 1; justify-self: end; }

	.obb .obb-reg-c-emp { grid-column: 1 / 3; grid-row: 2; }
	.obb .obb-reg-c-din { grid-column: 3 / 5; grid-row: 2; }
	.obb .obb-reg-c-fec { grid-column: 5 / 7; grid-row: 2; }

	/* Raya divisoria entre la cabecera y la fila de tres datos. */
	.obb .obb-reg-c-emp {
		border-top: 1px solid rgba(16, 28, 48, .1);
		padding-top: var(--e-2);
	}

	.obb .obb-reg-c-din,
	.obb .obb-reg-c-fec {
		border-top: 1px solid rgba(16, 28, 48, .1);
		border-left: 1px solid rgba(16, 28, 48, .1);
		padding-top: var(--e-2);
		padding-left: var(--e-2);
	}

	/*
	 * En movil, estas dos celdas de la cabecera SOLO se ven al expandir:
	 * §8.6 pide el codigo de control y el boton Detalle en la tarjeta
	 * abierta. Estan una sola vez en el DOM; aqui se revelan.
	 */
	.obb .obb-reg-c-ids,
	.obb .obb-reg-c-det { display: none; }

	.obb .obb-reg.obb-reg-abierta .obb-reg-c-ids,
	.obb .obb-reg.obb-reg-abierta .obb-reg-c-det {
		display: block;
		grid-column: 1 / -1;
	}

	/*
	 * Los tres datos de la fila inferior van con el rotulo ENCIMA del valor,
	 * alineados a la izquierda dentro de su columna. Los datos de la tarjeta
	 * ABIERTA si conservan la disposicion «etiqueta izquierda, valor
	 * derecha», que ahi lee mejor porque van a lo ancho.
	 */
	.obb .obb-reg-c-emp .obb-reg-val,
	.obb .obb-reg-c-din .obb-reg-val,
	.obb .obb-reg-c-fec .obb-reg-val {
		text-align: left;
		font-size: 12.5px;
	}

	.obb .obb-reg.obb-reg-abierta .obb-reg-x {
		display: flex;
		align-items: baseline;
		justify-content: space-between;
		gap: var(--e-3);
		flex-wrap: wrap;
	}

	.obb .obb-reg.obb-reg-abierta .obb-reg-x .obb-reg-et { margin-bottom: 0; }

	.obb .obb-reg.obb-reg-abierta .obb-reg-x .obb-reg-val { text-align: right; }

	.obb .obb-reg.obb-reg-abierta .obb-reg-exp {
		grid-template-columns: minmax(0, 1fr);
		row-gap: var(--e-2);
	}

	/* Las acciones, a lo ancho y con objetivo tactil de 44px. */
	.obb .obb-reg-x-acc { display: block; }
	.obb .obb-reg-x-acc .obb-reg-val { text-align: left; }
	.obb .obb-reg-acciones { margin-top: var(--e-1); }
	.obb .obb-reg-btn { min-height: var(--c-sm); flex: 1 1 8rem; }
	.obb .obb-reg-chev { width: var(--c-sm); height: var(--c-sm); }

	/* El avatar, algo mayor: en movil es la unica pista visual del cliente. */
	.obb .obb-reg-avatar { width: 36px; height: 36px; }
}

/* =====================================================================
   MOVIL ESTRECHO · 320px
   ===================================================================== */
@media (max-width: 360px) {

	.obb .obb-reg-cab { padding: var(--e-2); gap: var(--e-2); }

	/* El estado baja a su propia linea: con 320px no cabe al lado del nombre. */
	.obb .obb-reg-cab { grid-template-columns: minmax(0, 1fr) 44px; }
	.obb .obb-reg-c-cli  { grid-column: 1; grid-row: 1; }
	.obb .obb-reg-c-chev { grid-column: 2; grid-row: 1; }
	.obb .obb-reg-c-est  { grid-column: 1 / -1; grid-row: 2; align-items: flex-start; }
	.obb .obb-reg-c-est .obb-reg-val { align-items: flex-start; }

	.obb .obb-reg-btn { flex: 1 1 100%; }
	.obb .obb-reg-dir { font-size: 11.5px; }
}

/* ==========================================================================
   [P08] PORCENTAJES · base, excepciones y guardado en lote
   ==========================================================================

   Reutiliza lo que ya existe y no lo duplica: la tabla es `.obb-tabla-ac`,
   que ya trae su versión de tarjeta en móvil con las etiquetas en
   `data-col`, y el contenedor es `.obb-tabla-caja`, que ya scrollea en
   horizontal solo por dentro. Aquí se añade únicamente lo propio de P08:
   pestañas, estados de casilla y la barra de guardado.
   ========================================================================== */

/* El modal estándar mide 540 px y una matriz de ocho columnas no cabe.
   La clase la pone el panel; en móvil no cambia nada porque el ancho ya
   es el del dispositivo. */
.obb .obb-modal-ancho { max-width: 980px; }

/* -------------------------------------------------- pestañas */

.obb-p8-tabs {
	display: flex;
	gap: var(--e-1);
	margin: 0 0 var(--e-3);
	border-bottom: 1px solid var(--linea);
	/* Con muchas pestañas se desplazan, nunca desbordan el modal. */
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

.obb .obb-p8-tab {
	appearance: none;
	background: none;
	border: 0;
	border-bottom: 2px solid transparent;
	padding: var(--e-2) var(--e-3);
	font: inherit;
	font-weight: 600;
	color: var(--tinta-2);
	cursor: pointer;
	white-space: nowrap;
	min-height: 40px;
}

.obb .obb-p8-tab.activa {
	color: var(--tinta);
	border-bottom-color: var(--rojo);
}

/* -------------------------------------------------- barra de filtros */

.obb-p8-barra {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--e-2);
	margin: 0 0 var(--e-3);
}

.obb .obb-p8-busca {
	flex: 1 1 12rem;
	min-width: 0;
	/*
	 * El buscador NO va dentro de `.obb-campo`, asi que no heredaba el
	 * borde ni el fondo de los campos del portal: en la captura se veia
	 * como un texto suelto, sin caja. Se le dan los mismos valores que
	 * `.obb-campo input`, no otros parecidos.
	 */
	padding: var(--e-2) var(--e-3);
	border: 1px solid var(--linea-2);
	border-radius: var(--r-input);
	font-size: var(--t-campo);
	font-family: inherit;
	color: var(--tinta);
	background: var(--campo);
	min-height: 40px;
	-webkit-appearance: none;
	appearance: none;
}

.obb-p8-check {
	display: inline-flex;
	align-items: center;
	gap: var(--e-1);
	font-size: var(--t-sm);
	color: var(--tinta-2);
	white-space: nowrap;
}

/* Acceso al panel de modalidades · acción secundaria, aspecto secundario.
   Desde un operario son siete empresas y los botones largos ocupaban dos
   filas enteras por encima de la tabla. */
.obb-p8-ir-caja {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--e-1);
	margin: 0 0 var(--e-3);
}

.obb-p8-ir-rotulo {
	font-size: var(--t-sm);
	color: var(--tinta-2);
	margin-right: var(--e-1);
}

.obb .obb-p8-ir {
	padding: 4px var(--e-2);
	min-height: 32px;
	font-size: var(--t-sm);
}

/* -------------------------------------------------- selección múltiple */

.obb-p8-masivo {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--e-2);
	padding: var(--e-2) var(--e-3);
	margin: 0 0 var(--e-3);
	border: 1px solid var(--linea-2);
	border-radius: var(--r-card);
	background: var(--fondo-2);
	font-size: var(--t-sm);
}

.obb .obb-p8-masivo .obb-pct { width: 5rem; min-height: 40px; }

/* -------------------------------------------------- casillas */

.obb .obb-p8-in {
	width: 5rem;
	min-height: 40px;
	text-align: right;
}

/* Una excepción se ve: es un número puesto a mano, no una herencia. */
.obb .obb-p8-in.obb-p8-exc { font-weight: 700; }

/* Cambio sin guardar. */
.obb .obb-p8-in.obb-p8-sucia {
	border-color: var(--rojo-claro);
	box-shadow: inset 2px 0 0 var(--rojo-claro);
}

/* Inválida: fuera de rango o margen negativo. */
.obb .obb-p8-in.obb-p8-mala {
	border-color: var(--rojo);
	background: var(--rojo-suave);
}

/* La fila cambió por debajo mientras la pantalla estaba abierta. */
.obb .obb-p8-in.obb-p8-conflicto {
	border-color: var(--ambar);
	background: #fff6e0;
}

.obb-p8-celda {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: var(--e-2);
	flex-wrap: wrap;
}

.obb .obb-p8-chip-exc { background: var(--verde-suave); color: var(--verde); }
.obb .obb-p8-chip-sin { background: var(--rojo-suave); color: var(--rojo); }

.obb-p8-adm { font-variant-numeric: tabular-nums; }
.obb .obb-p8-adm.neg { color: var(--rojo); font-weight: 700; }

.obb-p8-nobase { color: var(--tinta-3); }

/* -------------------------------------------------- grupos plegables */

.obb .obb-p8-grupo td {
	background: var(--fondo-2);
	font-weight: 700;
}

.obb .obb-p8-plegar {
	appearance: none;
	background: none;
	border: 0;
	padding: 0;
	font: inherit;
	font-weight: 700;
	color: inherit;
	cursor: pointer;
	min-height: 32px;
}

.obb-p8-car { display: inline-block; width: 1em; }

/* [ESCALA] La cabecera de la empresa: nombre, cuenta y, a la derecha, el
   acceso a sus Modalidades. En una tira aparte, con treinta empresas, ese
   acceso ocupaba tres filas enteras y empujaba la tabla fuera de pantalla. */
.obb-p8-cab {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--e-2);
}

.obb .obb-p8-cab .obb-p8-ir { margin-left: auto; }

.obb-p8-cuenta {
	margin-left: var(--e-2);
	font-weight: 400;
	font-size: var(--t-sm);
	color: var(--tinta-2);
}

.obb .obb-p8-c { width: 2.2rem; text-align: center; }

.obb .obb-p8-vacio {
	text-align: center;
	padding: var(--e-4);
	color: var(--tinta-2);
}

/* -------------------------------------------------- [ESCALA] filtros */

/* Los contadores de estos botones salen del resumen del servidor, no de
   constantes: un filtro que dice «3» y enseña 7 es peor que no tenerlo. */
.obb-p8-filtros {
	display: flex;
	flex-wrap: wrap;
	gap: var(--e-2);
	margin: var(--e-3) 0 0;
}

.obb .obb-p8-filtro {
	appearance: none;
	display: inline-flex;
	align-items: center;
	gap: var(--e-1);
	min-height: 36px;
	padding: 0 .75rem;
	border: 1px solid var(--linea);
	border-radius: var(--r-pill);
	background: var(--blanco);
	font: inherit;
	font-size: var(--t-sm);
	color: var(--tinta-2);
	cursor: pointer;
}

.obb .obb-p8-filtro.activo {
	border-color: var(--azul);
	background: var(--azul);
	color: var(--blanco);
	font-weight: 700;
}

.obb-p8-fn {
	font-variant-numeric: tabular-nums;
	font-weight: 700;
	opacity: .8;
}

/* -------------------------------------------------- [ESCALA] carga progresiva */

.obb-p8-mas {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--e-2);
	margin-top: var(--e-2);
	font-size: var(--t-sm);
	color: var(--tinta-2);
}

.obb .obb-p8-cargando {
	text-align: center;
	padding: var(--e-3);
	color: var(--tinta-2);
	font-size: var(--t-sm);
}

/* -------------------------------------------------- [ESCALA] paginacion */

.obb-p8-paginas {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--e-2);
	margin-top: var(--e-2);
	font-size: var(--t-sm);
	color: var(--tinta-2);
}

.obb-p8-cuenta-pg { font-variant-numeric: tabular-nums; }

.obb-p8-pgs {
	display: inline-flex;
	flex-wrap: wrap;
	gap: var(--e-1);
}

.obb .obb-p8-pg {
	appearance: none;
	min-width: 36px;
	min-height: 36px;
	padding: 0 .4rem;
	border: 1px solid var(--linea);
	border-radius: var(--r-input);
	background: var(--blanco);
	font: inherit;
	font-size: var(--t-sm);
	font-variant-numeric: tabular-nums;
	color: var(--tinta-2);
	cursor: pointer;
}

.obb .obb-p8-pg.activo {
	border-color: var(--azul);
	background: var(--azul);
	color: var(--blanco);
	font-weight: 700;
}

.obb .obb-p8-pg[disabled] {
	opacity: .4;
	cursor: default;
}

.obb-p8-tam {
	display: inline-flex;
	align-items: center;
	gap: var(--e-1);
	font-size: var(--t-sm);
	color: var(--tinta-2);
}

.obb .obb-p8-tam select {
	min-height: 36px;
	border: 1px solid var(--linea);
	border-radius: var(--r-input);
	background: var(--blanco);
	font: inherit;
	font-size: var(--t-sm);
	padding: 0 .4rem;
}

/* -------------------------------------------------- matriz */

.obb .obb-p8-matriz { min-width: max-content; }

/* [ESCALA] LA CABECERA DE MODALIDADES SE QUEDA FIJA.
   Con diez operarios en pantalla, al bajar se perdía de vista a qué
   modalidad pertenecía cada columna, y una casilla de dinero sin saber de
   qué columna es no se puede comprobar. Hace falta que la caja scrollee en
   vertical para que `sticky` tenga contra qué pegarse: de ahí el alto
   máximo. En móvil no se limita, porque allí el scroll es el de la página. */
.obb .obb-p8-mcaja {
	max-height: 70vh;
	overflow: auto;
}

.obb .obb-p8-matriz thead th {
	position: sticky;
	top: 0;
	z-index: 2;
	background: var(--fondo-2);
}

/* La esquina pertenece a las dos barras fijas, así que va por encima. */
.obb .obb-p8-matriz thead th.obb-p8-opn-h {
	left: 0;
	z-index: 3;
}

.obb .obb-p8-matriz th,
.obb .obb-p8-matriz td { vertical-align: top; }

.obb .obb-p8-mh {
	font-size: .72rem;
	font-weight: 500;
	color: var(--tinta-2);
	line-height: 1.3;
	white-space: nowrap;
}

.obb-p8-mn {
	display: block;
	font-size: var(--t-sm);
	font-weight: 700;
	color: var(--tinta);
}

.obb-p8-mcelda {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 2px;
}

.obb-p8-mini {
	font-size: .7rem;
	color: var(--tinta-2);
	white-space: nowrap;
}

.obb .obb-p8-mini.neg { color: var(--rojo); font-weight: 700; }

.obb-p8-na { font-size: var(--t-sm); color: var(--tinta-3); }

/* La primera columna se queda fija: con ocho modalidades, al desplazarse
   en horizontal se perdía de vista de quién era cada fila. */
.obb .obb-p8-opn {
	position: sticky;
	left: 0;
	background: var(--blanco);
	white-space: nowrap;
	z-index: 1;
}

.obb-p8-leyenda {
	display: flex;
	flex-wrap: wrap;
	gap: var(--e-3);
	margin: var(--e-2) 0 0;
	font-size: .72rem;
	color: var(--tinta-2);
}

.obb-p8-lg-sucia::before {
	content: '';
	display: inline-block;
	width: 3px;
	height: .8em;
	margin-right: 4px;
	vertical-align: -1px;
	background: var(--rojo-claro);
}

/* -------------------------------------------------- barra de guardado */

.obb-p8-savebar {
	position: sticky;
	bottom: 0;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--e-2);
	margin: var(--e-3) 0 0;
	padding: var(--e-3);
	border: 1px solid var(--linea-2);
	border-radius: var(--r-card);
	background: var(--blanco);
	box-shadow: 0 -6px 14px rgba(2, 23, 75, .08);
}

.obb-p8-savebar-mala { border-color: var(--rojo); background: var(--rojo-suave); }

.obb-p8-sb-txt {
	flex: 1 1 10rem;
	min-width: 0;
	font-size: var(--t-sm);
	font-weight: 600;
}

/* -------------------------------------------------- móvil */

@media (max-width: 560px) {

	/* La barra de guardado pasa a dos líneas antes que a scroll lateral. */
	.obb-p8-savebar { gap: var(--e-2); }
	.obb-p8-sb-txt { flex: 1 1 100%; }
	.obb .obb-p8-savebar .obb-btn { flex: 1 1 calc(50% - var(--e-2)); }

	/* La matriz no se convierte en tarjetas: una matriz sin ejes no es una
	   matriz. Se deja desplazar en horizontal DENTRO de su caja, que es lo
	   que `.obb-tabla-caja` ya hace, y así el modal no desborda. */
	.obb .obb-p8-matriz { font-size: var(--t-sm); }
	.obb .obb-p8-matriz .obb-p8-in { width: 4.2rem; min-height: 44px; }

	.obb .obb-p8-in { min-height: 44px; }

	/* El buscador y la casilla ocupan la fila entera; Desplegar y Plegar
	   la comparten: cada uno en su propia linea era espacio perdido antes
	   de llegar a la tabla, que es lo que se viene a ver. */
	.obb-p8-barra > .obb-p8-busca,
	.obb-p8-barra > .obb-p8-check { flex: 1 1 100%; }
	.obb-p8-barra > .obb-btn { flex: 1 1 calc(50% - var(--e-2)); }

	/* [ESCALA] Los cuatro filtros caben en dos líneas de dos, con el
	   objetivo táctil completo: en una sola línea de cuatro el texto se
	   partía y el contador quedaba debajo del nombre. */
	.obb .obb-p8-filtro {
		flex: 1 1 calc(50% - var(--e-2));
		justify-content: space-between;
		min-height: 44px;
	}

	/* El rótulo y el botón de cargar más, cada uno en su línea: así el
	   botón es de ancho completo y no una diana de 100 px. */
	.obb-p8-mas > span,
	.obb-p8-paginas > .obb-p8-cuenta-pg { flex: 1 1 100%; }
	.obb .obb-p8-mas .obb-btn { flex: 1 1 100%; min-height: 44px; }

	.obb-p8-pgs { flex: 1 1 100%; }
	.obb .obb-p8-pg { min-width: 44px; min-height: 44px; }

	/* En móvil manda el scroll de la página: un alto máximo aquí dejaría
	   dos barras de desplazamiento, una dentro de la otra. */
	.obb .obb-p8-mcaja { max-height: none; }
	.obb .obb-p8-matriz thead th { position: static; }
}
