/* Componentes base ÚNICOS (se carga después de styles.css). Una fuente por componente: pill, mensaje, estado vacío, botón de peligro, objetivos táctiles de 44 px,
   diálogo (OLI.modal), aviso breve (toast) y tabla. Solo usa los tokens de styles.css (--sp-*, --z-*, --ok/--aviso/--error/--info, --danger-*, --r-*, --t-*).
   Los nombres viejos por pantalla (.asi-pill, .asi-tabla, .pill-warn, .chip, .pen-msg, .ob-err, .cx-mal…) ya se migraron y se borraron: no quedan alias. */

/* Solo para lectores de pantalla (cabecera de una columna sin texto, título de una tabla). */
.solo-lectores { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ── Pill: estado en una palabra. Tonos: ok, aviso, error, info, neutral (por defecto). ───────────────────── */
.pill { display: inline-flex; align-items: center; gap: var(--sp-1); padding: 3px 10px; border-radius: var(--r-pill); font-size: var(--t-12); font-weight: 700; line-height: 1.3; white-space: nowrap; background: var(--card2); color: var(--text-primary); }
.pill-ok, .pill[data-tono="ok"] { background: var(--ok-bg); color: var(--ok-fg); }
.pill-aviso, .pill[data-tono="aviso"] { background: var(--aviso-bg); color: var(--aviso-fg); }
.pill-error, .pill[data-tono="error"] { background: var(--error-bg); color: var(--error-fg); }
.pill-info, .pill[data-tono="info"] { background: var(--info-bg); color: var(--info-fg); }
/* Baja (rojo oscuro, lleno): la membresia se dio de baja. Mismos tokens en los dos temas que el boton de peligro (blanco sobre rojo profundo, 6,5:1); no se confunde con Deudor (rojo en tinta) ni con Inactivo (aviso). Siempre con texto e icono. */
.pill-baja, .pill[data-tono="baja"] { background: var(--danger-bg); color: var(--danger-fg); }
/* Etiqueta de contorno (la del tipo de dato o el estado de una tarjeta): .pill-borde, y .on cuando está activa. */
.pill-borde { background: transparent; border: 1px solid var(--linea); color: var(--gris); align-self: flex-start; padding: 3px 9px; font-size: var(--t-11); font-weight: 400; text-transform: uppercase; letter-spacing: .5px; }
.pill-borde.on { color: var(--blanco); }
.pill-neutral, .pill[data-tono="neutral"] { background: var(--card2); color: var(--text-secondary); }

/* ── Mensaje: una línea de estado bajo un formulario o una acción. .err = error (con role=alert en el HTML); .msg-ok / .msg-aviso / .msg-info = notas. OLI.msg() pone el rol. ── */
.err, .msg { min-height: 18px; margin: var(--sp-1) 0; font-size: var(--t-13); line-height: 1.4; color: var(--text-secondary); }
.err, .msg-error { color: var(--error-fg); }
.msg-ok { color: var(--ok-fg); }
.msg-aviso { color: var(--aviso-fg); }
.msg-info { color: var(--info-fg); }
.txt-ok { color: var(--ok-fg); }
.txt-error { color: var(--error-fg); }

/* ── Cargando (texto con pulso, para las tablas y tarjetas del panel mientras llega la respuesta). ── */
@keyframes pulse { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }
.loading { color: var(--text-tertiary); padding: 18px var(--sp-1); font-size: var(--t-15); animation: pulse 1.3s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .loading { animation: none; } }

/* ── Estado vacío ("todavía no hay nada" / "no se pudo cargar"): compacto a la izquierda, o centrado con ícono y título (.vacio-centro). ── */
.vacio { padding: var(--sp-5) var(--sp-1); font-size: var(--t-15); color: var(--text-secondary); }
.vacio-centro { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); text-align: center; padding: 28px 20px; }
.vacio-centro h3 { margin: 0; font-size: var(--t-17); text-wrap: balance; color: var(--text-primary); }
.vacio-centro p { margin: 0; max-width: 46ch; font-size: var(--t-15); }
.vacio-centro .btn { margin-top: var(--sp-2); }
.vacio-ic { font-size: var(--t-40); margin-bottom: var(--sp-2); opacity: .8; }

/* ── Botones: peligro (relleno, texto blanco sobre rojo profundo en los dos temas; con .btn-ghost queda de contorno) y objetivos táctiles de 44 px. ── */
.btn-danger, .adm .btn-danger { background: var(--danger-bg); color: var(--danger-fg); border: 1.5px solid var(--danger-bg); }
.btn-danger.btn-ghost, .adm .btn-danger.btn-ghost { background: transparent; border-color: var(--error-fg); color: var(--error-fg); }
.btn-danger.btn-ghost:hover { background: var(--error-bg); }
/* El mostrador es de uso intensivo, a veces apurado: 48 px siempre. En pantallas táctiles, todo lo pequeño llega a 48 px (Samsung One UI y Material). */
.asi-card .btn-sm { min-height: var(--touch); }
@media (pointer: coarse) {
  .btn-sm, .adm .btn-sm, .asi-card .btn-sm, .cont-tab, .nav-sw, .atc-x, .atc-send, .mhead-av, .faltantes button, .tabla th[data-sort] { min-height: var(--touch); }
  .nav-sw, .atc-x, .atc-send, .mhead-av { min-width: var(--touch); }
}
/* El interruptor se ve de 51×31 pero se toca en 44: el área sale de un pseudo-elemento. */
.interruptor { position: relative; }
.interruptor::before { content: ""; position: absolute; inset: -9px -4px; }

/* ── Diálogo (OLI.modal): centrado en escritorio, hoja desde abajo en el móvil. Reemplaza las redefiniciones sueltas que había en styles.css. ── */
@keyframes hojaFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes hojaSube { from { transform: translateY(100%); } to { transform: none; } }
@keyframes dcPop { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }
.oli-modal-bg[hidden] { display: none; }
.oli-modal-bg { position: fixed; inset: 0; background: rgba(0,0,0,.65); display: flex; align-items: center; justify-content: center; z-index: var(--z-modal); padding: 18px; }
.oli-modal { background: var(--negro-2); border: 1px solid var(--linea); border-radius: var(--r-14); padding: 26px 24px; max-width: 400px; width: 100%;
  max-height: calc(100dvh - 32px); overflow-y: auto; overscroll-behavior: contain; }
.oli-modal.aj { background: var(--surface-grouped); }
.oli-modal h3 { margin: 0 0 6px; font-size: var(--t-20); }
.oli-modal .muted { color: var(--gris); font-size: var(--t-15); line-height: 1.5; }
.oli-modal input:not([type="checkbox"]):not([type="radio"]) { width: 100%; padding: 13px 14px; border-radius: var(--r-12); border: 1px solid var(--linea); background: var(--surface-input); color: var(--blanco); font-size: 16px; margin: 14px 0 4px; }
/* Formularios dentro del diálogo (el de ingreso y registro de la landing): los campos ya traen su propio margen. */
.oli-modal .field input { margin: 0; padding: 12px 14px; }
.oli-modal .pw-wrap input { padding-right: 44px; }
.oli-modal .btn-block + .btn-block { margin-top: var(--sp-2); }
.oli-modal .campo-lbl { display: block; margin: var(--sp-3) 0 0; font-size: var(--t-13); font-weight: 600; color: var(--text-secondary); }
.oli-modal .campo-lbl + input { margin-top: 6px; }
@media (min-width: 600px) { .oli-modal { border: 0; border-radius: var(--r-28); max-width: 460px; animation: dcPop var(--t-cambio) var(--ease) both; } }
@media (max-width: 599px) {
  .oli-modal-bg { align-items: flex-end; padding: 0; background: rgba(0,0,0,.45); animation: hojaFade var(--t-cambio) ease both; }
  .oli-modal { max-width: none; border: 0; border-radius: var(--r-28) var(--r-28) 0 0; padding: 30px 20px max(24px, env(safe-area-inset-bottom)); position: relative;
    animation: hojaSube var(--t-hoja) cubic-bezier(.2,.8,.2,1) both; }
  .oli-modal::before { content: ""; position: absolute; top: 9px; left: 50%; width: 38px; height: 5px; margin-left: -19px; border-radius: var(--r-8); background: var(--border-default); }
}
@media (prefers-reduced-motion: reduce) { .oli-modal-bg, .oli-modal { animation: none; } }

/* ── Aviso breve (OLI.toast): los tonos se suman al .toast de styles.css. ── */
.toast.toast-error { background: var(--danger-bg); color: var(--danger-fg); border-color: transparent; }
.toast.toast-error::before { background: var(--danger-fg); }
.toast.toast-ok::before { background: var(--ok-fg); }
.toast.toast-aviso::before { background: var(--aviso-fg); }

/* ── Tabla única. Modificadores: .tabla-densa (menos aire), .tabla-plana (sin tarjeta: va dentro de una), .tabla-fija (cabecera pegada al hacer scroll),
   .tabla-apila (en el móvil cada fila pasa a tarjeta; las celdas llevan data-l="Etiqueta"). Números: .num (derecha, cifras tabulares).
   Orden: th[data-sort] con aria-sort. Selección: tr[aria-selected="true"]. Alrededor, .tabla-wrap da el scroll horizontal. ── */
.tabla-wrap { overflow-x: auto; border-radius: var(--r-22); }
.tabla { width: 100%; border-collapse: separate; border-spacing: 0; margin-top: 6px; font-size: var(--t-15); background: var(--surface-card); border-radius: var(--r-22); overflow: hidden; }
.tabla th, .tabla td { text-align: left; padding: var(--sp-2) 14px; height: 48px; border-bottom: 1px solid var(--sep); vertical-align: middle; }
.tabla th { height: 40px; color: var(--text-tertiary); font-size: var(--t-11); font-weight: 700; text-transform: uppercase; letter-spacing: .08em; }
.tabla tbody tr { transition: background .12s; }
.tabla tbody tr:last-child td { border-bottom: none; }
@media (hover: hover) and (pointer: fine) { .tabla tbody tr:hover { background: var(--overlay-soft); } }
.tabla .num, .tabla th.num, .tabla td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tabla small { display: block; color: var(--text-secondary); }
.tabla input[type="checkbox"] { width: 22px; height: 22px; }
.tabla-densa th, .tabla-densa td { padding: 6px var(--sp-2); height: auto; font-size: var(--t-13); }
.tabla-densa th { font-size: var(--t-12); }
.tabla-plana { background: transparent; border-radius: 0; }
.tabla-plana th, .tabla-plana td { vertical-align: top; }
.tabla-plana th { height: auto; padding-top: 6px; padding-bottom: 6px; text-transform: none; letter-spacing: 0; font-size: var(--t-13); font-weight: 600; color: var(--text-secondary); border-bottom: 0; }
.tabla-plana td { height: auto; border-top: 1px solid var(--sep); border-bottom: 0; }
.tabla tbody th { text-align: left; height: auto; color: var(--text-primary); font-size: inherit; font-weight: 600; text-transform: none; letter-spacing: 0; border-bottom: 1px solid var(--sep); }
.tabla-plana tbody th { border-bottom: 0; border-top: 1px solid var(--sep); }
.tabla-fija thead th { position: sticky; top: 0; z-index: 2; background: var(--surface-card); }
.tabla th[data-sort], .tabla th[aria-sort] { user-select: none; cursor: pointer; }
.tabla th[data-sort]:hover { color: var(--text-primary); }
.tabla th[aria-sort="ascending"]::after { content: " \25B2"; font-size: .8em; }
.tabla th[aria-sort="descending"]::after { content: " \25BC"; font-size: .8em; }
.tabla tr[aria-selected="true"] td { background: var(--overlay-medium); }
.tabla tr:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
@media (max-width: 599px) {
  .tabla-apila, .tabla-apila tbody, .tabla-apila tr, .tabla-apila th, .tabla-apila td { display: block; }
  .tabla-apila { background: transparent; border-radius: 0; }
  .tabla-apila thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }   /* sigue leyéndose con lector de pantalla */
  .tabla-apila tr { background: var(--surface-card); border-radius: var(--r-22); margin-bottom: 10px; padding: var(--sp-2); }
  .tabla-apila td { border: 0; height: auto; padding: var(--sp-1) var(--sp-2); }
  .tabla-apila td::before { content: attr(data-l) ": "; font-weight: 700; color: var(--text-secondary); font-size: var(--t-12); }
  .tabla-apila td[data-l=""]::before, .tabla-apila td:not([data-l])::before { content: ""; }
  .tabla-apila .num, .tabla-apila th.num, .tabla-apila td.num { text-align: left; }
  .tabla-apila.tabla-plana tr { background: transparent; border-radius: 0; margin: 0; padding: var(--sp-2) 0; border-top: 1px solid var(--sep); }
  .tabla-apila.tabla-plana tr:first-child { border-top: 0; }
  .tabla-apila.tabla-plana td { border-top: 0; padding: var(--sp-1) 0; }
}

/* ── Aviso: ícono (✓ ! ✕ i, de data-ic: nunca solo color), errores que quedan hasta cerrarlos y un solo ritmo para los éxitos (lo fija componentes.js). ── */
.toast::before { content: attr(data-ic); display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--oli-00); color: var(--oli-900); font-size: var(--t-12); font-weight: 800; line-height: 1; }
.toast.toast-error::before { background: var(--danger-fg); color: var(--danger-bg); }
.toast.toast-ok::before { background: var(--ok-fg); color: var(--oli-900); }
.toast.toast-aviso::before { background: var(--aviso-fg); color: var(--oli-900); }
.toast.persiste { pointer-events: auto; }
.toast-x { flex: none; min-width: var(--touch); min-height: var(--touch); margin: -12px -16px -12px 0; padding: 0; border: 0; border-radius: var(--r-12); background: transparent; color: inherit; font: inherit; font-size: var(--t-20); line-height: 1; cursor: pointer; }
.toast-x:hover { background: var(--overlay-medium); }
.toast-x:focus-visible, .toast-accion:focus-visible { outline: 2px solid currentColor; outline-offset: -2px; }
.toast .toast-accion { color: inherit; }
.oli-consecuencia { display: flex; gap: var(--sp-2); align-items: flex-start; margin: var(--sp-3) 0 0; padding: var(--sp-2) var(--sp-3); border-radius: var(--r-12); background: var(--error-bg); color: var(--error-fg); font-size: var(--t-13); font-weight: 600; line-height: 1.4; }
.oli-consecuencia > span { flex: none; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; background: var(--error-fg); color: var(--surface-card); font-size: var(--t-12); font-weight: 800; }

/* ── Estado: el ícono de OLI.estado va dentro del pill (nunca solo color). ── */
.pill-ic { display: inline-grid; place-items: center; min-width: 1em; font-weight: 800; }

/* ── Campo: etiqueta, control, ayuda y error en línea (OLI.campo). ── */
.campo { display: block; margin: 0 0 var(--sp-3); }
.campo > label { display: block; margin: 0 0 var(--sp-1); font-size: var(--t-13); font-weight: 600; color: var(--text-secondary); }
.campo > input, .campo > select, .campo > textarea { width: 100%; min-height: var(--touch); padding: var(--sp-2) var(--sp-3); border-radius: var(--r-12); border: 1px solid var(--border-default); background: var(--surface-input); color: var(--text-primary); font: inherit; font-size: 16px; }
.campo > input[aria-invalid="true"] { border-color: var(--error-fg); }
.campo-ayuda { margin: var(--sp-1) 0 0; font-size: var(--t-13); color: var(--text-secondary); }
.campo-error { min-height: 0; margin: var(--sp-1) 0 0; font-size: var(--t-13); font-weight: 600; color: var(--error-fg); }
.campo-error:empty { display: none; }

/* ── Esqueleto de carga (OLI.esqueleto): líneas con pulso; quieto con movimiento reducido (ya lo apaga .esq en styles.css). ── */
.esq-linea { display: block; height: var(--sp-6); margin: var(--sp-2) 0; }

/* ── Franja de marca: UN solo tablero blanco y negro, en tres tamaños. ── */
.franja { --fr-alto: 6px; --fr-cuadro: 18px; height: var(--fr-alto); background: repeating-linear-gradient(90deg, var(--oli-00) 0 var(--fr-cuadro), var(--oli-900) var(--fr-cuadro) calc(var(--fr-cuadro) * 2)); }
.franja-s { --fr-alto: 4px; --fr-cuadro: 14px; }
.franja-m { --fr-alto: 5px; --fr-cuadro: 18px; }
.franja-l { --fr-alto: 6px; --fr-cuadro: 18px; }

/* ── Lista de atajos de teclado (la comparten la app del hincha y el Back Office) y búsqueda tipo paleta (Ctrl+K). ── */
.oli-atajos { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-2) var(--sp-4); margin: var(--sp-3) 0; }
.oli-atajos dt { font-weight: 700; white-space: nowrap; }
.oli-atajos dd { margin: 0; color: var(--text-secondary); }
.oli-atajos kbd { font: 600 var(--t-11) / 1 var(--mono, ui-monospace, monospace); padding: 3px 6px; border-radius: var(--r-8); border: 1px solid var(--border-default); background: var(--overlay-soft); color: var(--text-secondary); }

/* ═══ Sistema de diseño · componentes base (Ola 2 UX). Catálogo vivo: public/_componentes.html. Reglas: solo tokens, 48 px de objetivo táctil con el dedo, foco visible,
   texto + ícono (nunca solo color) y movimiento detrás de --t-* (que prefers-reduced-motion apaga). Helpers: OLI.tarea, kpi, nota, errorEstado, pildoras, fila, hoja, esqueleto. ═══ */

/* Escala tipográfica de 4 niveles. Los títulos de pantalla usan .tx-titulo (34/40); se contraen a 20/26 con la barra de título (.mhead) al hacer scroll. */
.tx-titulo { font: 600 var(--fs-titulo) / var(--lh-titulo) var(--display); letter-spacing: -.03em; }
.tx-titulo-chico { font: 600 var(--fs-titulo-chico) / var(--lh-titulo-chico) var(--display); letter-spacing: -.02em; }
.tx-seccion { font-size: var(--fs-seccion); line-height: var(--lh-seccion); font-weight: 700; }
.tx-cuerpo { font-size: var(--fs-cuerpo); line-height: var(--lh-cuerpo); }
.tx-apoyo { font-size: var(--fs-apoyo); line-height: var(--lh-apoyo); color: var(--text-secondary); }
@media (max-width: 599px) { .tx-titulo { font-size: var(--fs-titulo-chico); line-height: var(--lh-titulo-chico); } }   /* en pantallas angostas el título nace contraído */

/* Foco visible único para los componentes interactivos. */
.tarea:focus-visible, .pildora:focus-visible, .hoja-x:focus-visible, .kpi-boton:focus-visible { outline: var(--focus-outline); outline-offset: 2px; }

/* Tarjeta de tarea: un título, una línea de apoyo y una acción. Toda la tarjeta es el objetivo táctil (≥ 48 px). */
.tarea { display: flex; align-items: center; gap: var(--sp-3); width: 100%; min-height: var(--touch); padding: var(--sp-3) var(--sp-4); border: 0; border-radius: var(--radio-md); background: var(--surface-card); color: var(--text-primary); box-shadow: var(--elev-1); font: inherit; text-align: left; text-decoration: none; cursor: pointer; transition: background var(--t-toque) var(--ease), transform var(--t-toque) var(--ease); }
@media (hover: hover) and (pointer: fine) { .tarea:hover { background: var(--overlay-soft); } }
.tarea:active { transform: scale(.985); }
.tarea-ic { flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--radio-sm); background: var(--overlay-medium); }
.tarea-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.tarea-tx b { font-size: var(--fs-cuerpo); line-height: var(--lh-cuerpo); font-weight: 600; }
.tarea-tx small { font-size: var(--fs-apoyo); line-height: var(--lh-apoyo); color: var(--text-secondary); }
.tarea-ac { flex: none; font-size: var(--fs-apoyo); font-weight: 700; padding: var(--sp-2) var(--sp-3); border-radius: var(--radio-full); background: var(--action-primary-bg); color: var(--action-primary-text); }
.tarea-aviso { box-shadow: inset 4px 0 0 var(--aviso-fg), var(--elev-1); }
.tarea-error { box-shadow: inset 4px 0 0 var(--error-fg), var(--elev-1); }
.tarea-ok { box-shadow: inset 4px 0 0 var(--ok-fg), var(--elev-1); }
.tarea-info { box-shadow: inset 4px 0 0 var(--info-fg), var(--elev-1); }
.tarea-primaria { background: var(--action-primary-bg); color: var(--action-primary-text); }
.tarea-primaria .tarea-tx small { color: inherit; opacity: .85; }
.tarea-primaria .tarea-ic { background: var(--overlay-strong); }
.tarea-primaria .tarea-ac { background: var(--action-primary-text); color: var(--action-primary-bg); }

/* Píldoras de filtro (aria-pressed). */
.pildoras { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.pildora { display: inline-flex; align-items: center; gap: var(--sp-2); min-height: 40px; padding: var(--sp-2) var(--sp-4); border: 1px solid var(--border-default); border-radius: var(--radio-full); background: transparent; color: var(--text-secondary); font: inherit; font-size: var(--fs-apoyo); font-weight: 600; line-height: var(--lh-apoyo); cursor: pointer; transition: background var(--t-toque) var(--ease), color var(--t-toque) var(--ease); }
.pildora[aria-pressed="true"] { background: var(--action-primary-bg); border-color: var(--action-primary-bg); color: var(--action-primary-text); }
.pildora-n { min-width: 20px; padding: 0 6px; border-radius: var(--radio-full); background: var(--overlay-medium); font-size: var(--t-12); line-height: 20px; text-align: center; font-variant-numeric: tabular-nums; }
@media (pointer: coarse) { .pildora { min-height: var(--touch); } }

/* KPI: número grande + etiqueta (+ cambio con flecha). .stat es el nombre histórico del panel y comparte la misma regla. */
.kpi, .stat { flex: 1 1 150px; min-width: 150px; background: var(--surface-card); border-radius: var(--radio-md); padding: var(--sp-4) var(--sp-4); box-shadow: var(--elev-1); }
.kpi-n, .stat .n { font: 700 var(--t-28) / 1.1 var(--display); font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.kpi-l, .stat .l { margin-top: var(--sp-1); color: var(--text-secondary); font-size: var(--t-12); line-height: var(--lh-apoyo); font-weight: 600; }
.kpi-ap, .stat .l .sub { display: block; font-weight: 500; color: var(--text-tertiary); }
.kpi-delta { display: inline-block; margin-top: var(--sp-1); padding: 1px var(--sp-2); border-radius: var(--radio-full); font-size: var(--t-12); font-weight: 700; }
.kpi-sube { background: var(--ok-bg); color: var(--ok-fg); }
.kpi-baja { background: var(--aviso-bg); color: var(--aviso-fg); }
@media (max-width: 599px) { .kpi, .stat { flex: 1 1 calc(50% - var(--sp-2)); min-width: 0; padding: var(--sp-3) var(--sp-4); } .kpi-n, .stat .n { font-size: var(--t-22); } }

/* Aviso en la página: ícono + texto (info / ok / aviso / error). El tono cambia el borde y el ícono, el texto sigue en el color principal (contraste 4,5:1 en los dos temas). */
.nota { display: flex; align-items: flex-start; gap: var(--sp-3); margin: 0 0 var(--sp-3); padding: var(--sp-3) var(--sp-4); border-radius: var(--radio-sm); border: 1px solid var(--border-default); background: var(--overlay-soft); color: var(--text-primary); font-size: var(--fs-apoyo); line-height: var(--lh-apoyo); }
.nota .ic { flex: none; margin-top: 1px; }
.nota-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.nota-tx b { font-size: var(--fs-cuerpo); line-height: var(--lh-cuerpo); }
.nota-ok { border-color: var(--ok-fg); background: var(--ok-bg); }
.nota-ok .ic { color: var(--ok-fg); }
.nota-aviso { border-color: var(--aviso-fg); background: var(--aviso-bg); }
.nota-aviso .ic { color: var(--aviso-fg); }
.nota-error { border-color: var(--error-fg); background: var(--error-bg); }
.nota-error .ic { color: var(--error-fg); }
.nota-info { border-color: var(--info-fg); background: var(--info-bg); }
.nota-info .ic { color: var(--info-fg); }

/* Estado vacío con acción / error con salida (.vacio-centro es la base; ver arriba). */
.vacio-acciones { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-2); margin-top: var(--sp-2); }
.vacio-error .vacio-ic { display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; background: var(--error-bg); color: var(--error-fg); font-size: var(--t-28); font-weight: 800; opacity: 1; }

/* Esqueleto: misma forma que lo que va a llegar (línea, tarjeta, fila, KPI). El pulso lo apaga prefers-reduced-motion (regla de .esq en styles.css). */
.esq-grupo { display: grid; gap: var(--sp-2); }
.cards > .esq-grupo { flex: 1 1 100%; }
.esq-grupo-kpi { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.esq-tarjeta { height: 96px; border-radius: var(--radio-md); }
.esq-fila { height: var(--touch); border-radius: var(--radio-sm); }
.esq-kpi { height: 84px; border-radius: var(--radio-md); }

/* Botones: primario (.btn), secundario (.btn-ghost) y peligro (.btn-danger). Con el dedo, 48 px. */
@media (pointer: coarse) { .btn { min-height: var(--touch); } }

/* Fila de lista con acción: .grupo > .grupo-fila (ícono, título, apoyo, valor) + botón a la derecha. */
.fila-ac-wrap { cursor: default; flex-wrap: wrap; }
.fila-ic { background: var(--card2); color: var(--text-primary); }
.fila-ac { margin-left: auto; flex: none; margin-top: 0; }
@media (pointer: coarse) { .grupo-fila { min-height: var(--touch); } }

/* Hoja inferior accesible (OLI.hoja): cabecera con título y cierre de 48 px. La hoja en sí (asa, radio 28, subida desde abajo) es .oli-modal. */
.hoja-cab { display: flex; align-items: center; gap: var(--sp-3); margin: 0 0 var(--sp-3); }
.hoja-cab h3 { flex: 1; margin: 0; font-size: var(--fs-seccion); line-height: var(--lh-seccion); }
.hoja-x { flex: none; display: grid; place-items: center; width: var(--touch); height: var(--touch); margin: calc(var(--sp-2) * -1); border: 0; border-radius: 50%; background: transparent; color: var(--text-secondary); font: inherit; font-size: var(--t-28); line-height: 1; cursor: pointer; }
.hoja-x:hover { background: var(--overlay-medium); color: var(--text-primary); }
.hoja-cuerpo { display: grid; gap: var(--sp-3); }

/* ═══ ONE UI · Fundación (app del Olimpista). Spec: docs/oneui-app.md. Todo lo que cambia una pieza ya existente va con body.app (Admin, Back Office, Asistido, Mostrador y Comercio no cambian);
   lo nuevo (.tarjeta, .pila, .btn-texto, .accion-fija, .hoja-acciones, .contenido-angosto) es global. Radios por token: tarjeta 24, campo 16, hoja 28, botón y chip píldora. Catálogo: /_componentes.html. ═══ */

/* Botones: principal (.btn-valor, 52 px, dorado, UNO por pantalla), secundario (.btn-ghost, 48 px), terciario (.btn-texto, 44 px) y peligro (.btn-danger). .btn suelto es el molde tinta de siempre (52 px, píldora).
   Estados: reposo, presionado (escala .98 + velo, 100 ms), deshabilitado (45 %), cargando (.cargando: círculo adentro, el ancho no cambia) y foco con anillo. */
body.app .btn, .btn-texto { display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2); position: relative; min-height: var(--alto-boton); padding: 0 var(--sp-5); border-radius: var(--radio-full);
  font-size: var(--fs-cuerpo); font-weight: 600; line-height: 1.2; text-align: center; text-decoration: none; cursor: pointer;
  transition: transform var(--t-presion) var(--ease), filter var(--t-presion) var(--ease), background-color var(--t-presion) var(--ease), opacity var(--t-toque) var(--ease); }
body.app .btn-ghost { min-height: var(--alto-boton-sec); }
body.app .btn-sm, .btn-texto { min-height: var(--alto-boton-ter); padding: 0 var(--sp-4); font-size: var(--t-14); }
.btn-texto { border: 0; background: transparent; color: var(--text-primary); font-family: inherit; }
.btn-texto .ic { width: 20px; height: 20px; }
body.app .btn:active:not(:disabled):not([aria-disabled="true"]):not(.cargando), .btn-texto:active:not(:disabled) { transform: scale(.98); filter: brightness(.92); }
body.app .btn-ghost:active:not(:disabled), .btn-texto:active:not(:disabled) { background: var(--overlay-medium); filter: none; }
@media (hover: hover) and (pointer: fine) { body.app .btn:hover:not(:disabled) { filter: brightness(.94); } body.app .btn-ghost:hover:not(:disabled), .btn-texto:hover:not(:disabled) { filter: none; background: var(--overlay-medium); } }
body.app .btn:disabled, body.app .btn[aria-disabled="true"], .btn-texto:disabled { opacity: .45; cursor: not-allowed; }
body.app .btn:focus-visible, .btn-texto:focus-visible { outline: var(--focus-outline); outline-offset: 3px; }
body.app .btn .ic { width: 20px; height: 20px; }
body.app .btn.cargando, .btn-texto.cargando { color: transparent; pointer-events: none; }
body.app .btn.cargando > *, .btn-texto.cargando > * { visibility: hidden; }
body.app .btn.cargando::after, .btn-texto.cargando::after { content: ""; position: absolute; top: 50%; left: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 50%; border: 2.5px solid var(--btn-giro, currentColor); border-right-color: transparent; animation: oliGiro var(--t-giro) linear infinite; }
body.app .btn { --btn-giro: var(--action-primary-text); }
body.app .btn-valor { --btn-giro: var(--oli-900); }
body.app .btn-ghost, .btn-texto { --btn-giro: var(--text-primary); }
body.app .btn-danger { --btn-giro: var(--danger-fg); }
body.app .btn-danger.btn-ghost { --btn-giro: var(--error-fg); }
@keyframes oliGiro { to { transform: rotate(360deg); } }
/* Acción fija abajo en los pasos largos: queda sobre la barra inferior con su margen de seguridad. */
.accion-fija { position: sticky; bottom: calc(var(--alto-barra-app) + env(safe-area-inset-bottom) + var(--sp-2)); z-index: var(--z-pop); display: grid; gap: var(--sp-2); padding: var(--sp-3) 0; background: linear-gradient(to top, var(--surface-grouped) 70%, transparent); }
@media (min-width: 900px) { .accion-fija { bottom: 0; } }

/* Campos rellenos: 56 px, radio 16, sin borde en reposo, anillo dorado al enfocar, error en rojo con texto e ícono (OLI.campo). La etiqueta va fija arriba. */
body.app :is(.field, .campo, .perfil .field, .ob-field) :is(input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]), select, textarea),
body.app .oli-modal input:not([type="checkbox"]):not([type="radio"]) {
  min-height: var(--alto-campo); padding: 0 var(--sp-4); border: 0; border-radius: var(--radio-campo); background: var(--surface-campo); color: var(--text-primary); font-size: 16px;
  box-shadow: inset 0 0 0 2px transparent; transition: box-shadow var(--t-toque) var(--ease); }
body.app :is(.field, .campo, .perfil .field, .ob-field) textarea { min-height: 112px; padding: var(--sp-3) var(--sp-4); }
body.app :is(.field, .campo, .perfil .field, .ob-field) :is(input, select, textarea):focus-visible, body.app .oli-modal input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--text-value); }
body.app :is(.field, .campo, .perfil .field, .ob-field) :is(input, select, textarea)[aria-invalid="true"], body.app .oli-modal input[aria-invalid="true"] { box-shadow: inset 0 0 0 2px var(--error-fg); }
body.app .campo > label, body.app .field label { margin: 0 0 var(--sp-2) var(--sp-1); }
body.app :is(.campo-ayuda, .campo-error) { display: flex; align-items: flex-start; gap: var(--sp-2); }
body.app .campo-ayuda::before, body.app .campo-error:not(:empty)::before { flex: none; display: grid; place-items: center; width: 16px; height: 16px; margin-top: 1px; border-radius: 50%; font-size: var(--t-11); font-weight: 800; line-height: 1; }
body.app .campo-ayuda::before { content: "i"; background: var(--info-bg); color: var(--info-fg); }
body.app .campo-error:not(:empty)::before { content: "!"; background: var(--error-fg); color: var(--surface-card); }

/* Lista agrupada (.grupo): contenedor de radio 24, filas de 56 px con ícono en círculo, flecha y divisores con sangría. */
body.app .grupo { border-radius: var(--radio-tarjeta); }
body.app .grupo-fila { min-height: var(--alto-fila); padding: var(--sp-2) var(--sp-4); gap: var(--sp-3); }
body.app .grupo-fila + .grupo-fila::before { left: 64px; }
body.app .grupo.sin-ic .grupo-fila + .grupo-fila::before { left: var(--sp-4); }
body.app .grupo-ic { width: 36px; height: 36px; border-radius: 50%; }
body.app .grupo-fila > svg.ic:last-child:not(.grupo-chev), body.app .grupo-fila > .grupo-chev { width: 16px; height: 16px; color: var(--text-tertiary); }
body.app .grupo-tx b { font-size: var(--fs-cuerpo); line-height: var(--lh-cuerpo); }
body.app .grupo-tx small { font-size: var(--fs-apoyo); line-height: var(--lh-apoyo); }
body.app .grupo-fila:focus-visible { outline: var(--focus-outline); outline-offset: -2px; }

/* Tarjeta (.tarjeta) y pila de tarjetas (.pila): radio 24, relleno 20, 12 px entre una y otra. .cu-card sigue siendo la tarjeta de Mi cuenta con la misma medida. */
.tarjeta { background: var(--surface-card); border-radius: var(--radio-tarjeta); padding: 20px; box-shadow: var(--elev-1); min-width: 0; }
.pila { display: grid; gap: var(--sp-3); }
body.app .cu-card { padding: 20px; margin-bottom: var(--sp-3); }
.contenido-angosto { max-width: var(--ancho-contenido); margin-left: auto; margin-right: auto; }   /* pantallas de una columna (formularios, listas) en tablet y escritorio */
body.app :is(.tarea, .kpi, .stat) { box-shadow: var(--elev-1); }
body.app .nota { border-radius: var(--radio-campo); }

/* Chips, segmentados e interruptores: las mismas formas en toda la app (píldora). */
body.app :is(.ctl-seg, .cu-subtabs) { border-radius: var(--radio-full); border: 0; background: var(--overlay-medium); }
body.app :is(.ctl-seg-b, .cu-subtab) { border-radius: var(--radio-full); }
body.app .ctl-seg-b[aria-checked="true"], body.app .cu-subtab[aria-selected="true"] { box-shadow: var(--elev-1); }
body.app .cu-filtro, body.app .pildora { border-radius: var(--radio-full); }
body.app .interruptor { width: 52px; height: 32px; }
body.app .interruptor::after { width: 28px; height: 28px; }
body.app .interruptor::before { inset: -8px -4px; }   /* se ve de 52×32 y se toca en 48 */

/* Estados: vacío y error con la MISMA plantilla (OLI.vacio / OLI.errorEstado): ícono en círculo, título, un motivo y una acción. */
body.app .vacio-centro { padding: var(--sp-6) var(--sp-5); }
body.app .vacio-centro h3 { font-size: var(--fs-seccion); line-height: var(--lh-seccion); }
body.app .vacio-centro p { font-size: var(--fs-cuerpo); line-height: var(--lh-cuerpo); color: var(--text-secondary); }
body.app .vacio-ic { display: grid; place-items: center; width: 72px; height: 72px; margin-bottom: var(--sp-2); border-radius: 50%; background: var(--overlay-medium); color: var(--text-secondary); font-size: var(--t-28); opacity: 1; }
body.app .vacio-ic .ic { width: 32px; height: 32px; }
body.app .vacio-error .vacio-ic { background: var(--error-bg); color: var(--error-fg); }
.esq-campo { height: var(--alto-campo); border-radius: var(--radio-campo); }
.esq-boton { height: var(--alto-boton); border-radius: var(--radio-full); }
.esq-lista { background: var(--surface-card); border-radius: var(--radio-tarjeta); overflow: hidden; }
.esq-fila-lista { position: relative; display: block; height: var(--alto-fila); background: none; border-radius: 0; animation: none; }
.esq-fila-lista::before, .esq-fila-lista::after { content: ""; position: absolute; background: var(--card2); animation: esqPulso var(--t-pulso) ease-in-out infinite; }
.esq-fila-lista::before { left: var(--sp-4); top: 10px; width: 36px; height: 36px; border-radius: 50%; }
.esq-fila-lista::after { left: 64px; top: 22px; width: 55%; height: 12px; border-radius: 6px; }
@media (prefers-reduced-motion: reduce) { .esq-fila-lista::before, .esq-fila-lista::after { animation: none; } }

/* Aviso breve (toast): píldora sobre la barra inferior. */
body.app .toast { min-height: var(--touch); padding: var(--sp-3) var(--sp-5) var(--sp-3) var(--sp-4); border-radius: var(--radio-full); border-color: transparent; font-size: var(--fs-apoyo); line-height: var(--lh-apoyo); box-shadow: var(--sombra); }

/* Hojas (OLI.hoja / OLI.modal): radio 28, manija, 250 ms; los botones van al final con .hoja-acciones. */
body.app .oli-modal { border-radius: var(--radio-hoja); }
@media (max-width: 599px) { body.app .oli-modal { border-radius: var(--radio-hoja) var(--radio-hoja) 0 0; padding-top: var(--sp-6); }
  body.app .oli-modal::before { top: var(--sp-2); width: 36px; height: 4px; margin-left: -18px; } }
.hoja-acciones { display: grid; gap: var(--sp-2); margin-top: var(--sp-2); }
@media (min-width: 600px) { .hoja-acciones { grid-auto-flow: column; grid-auto-columns: 1fr; } }

/* Barra inferior (celular): 64 px más la zona segura, ícono y etiqueta siempre, y una píldora detrás de la pantalla activa. Barra lateral (escritorio): los mismos íconos y el mismo orden. */
@media (max-width: 899px) {
  body.app { --barra-h: calc(var(--alto-barra-app) + env(safe-area-inset-bottom)); }
  body.app .tabs { box-sizing: border-box; height: var(--barra-h); padding: 0 var(--sp-2) env(safe-area-inset-bottom); align-items: stretch; }
  body.app .tab { justify-content: center; gap: 4px; padding: 0; }
  body.app .tab .tab-ic { margin: 0; }
  body.app .tab span, body.app.cu-on .tab span { font-size: var(--t-12); line-height: 14px; }
  /* La pantalla activa se marca con una línea corta arriba del ícono (sin píldora gris detrás): ícono y etiqueta en color pleno. */
  .tab-ind { top: 0; width: 32px; height: 3px; border-radius: 0 0 3px 3px; background: var(--text-primary); }
}
@media (min-width: 900px) {
  body.app .tabs { border-radius: var(--radio-tarjeta); }
  body.app .tab { border-radius: var(--radio-full); padding: 9px var(--sp-4); }
}

/* Encabezado: título grande que se contrae. Subpágina (body[data-nivel] = sub | paso, lo pone el router o Mis datos): UN solo «volver» (#mBack) con flecha y el nombre de la página padre.
   Celular: píldora de 32 px en la MISMA fila que el título, con área táctil de 44 px invisible (::before). Escritorio: enlace «← Mis datos» sobre el título, con el estilo del encabezado. */
body.app .mhead-back { position: relative; z-index: 2; display: inline-flex; align-items: center; gap: var(--sp-1); align-self: flex-start; flex: 0 1 auto; min-width: 0; max-width: 100%; min-height: 32px; margin: 0; padding: 0 var(--sp-3) 0 var(--sp-2); border-radius: var(--radio-full);
  background: color-mix(in srgb, var(--oli-00) 16%, transparent); color: var(--oli-00); font: 600 var(--t-13) / 1 var(--display); text-decoration: none; white-space: nowrap; transition: background-color var(--t-presion) var(--ease), transform var(--t-presion) var(--ease); }
body.app .mhead-back::before { content: ""; position: absolute; inset: -6px -4px; min-width: calc(var(--touch) - 4px); min-height: calc(var(--touch) - 4px); }
body.app .mhead-back[hidden] { display: none; }
body.app .mhead-back:active { transform: scale(.96); background: color-mix(in srgb, var(--oli-00) 28%, transparent); }
body.app .mhead-back:focus-visible { outline: 2px solid var(--oli-00); outline-offset: 2px; }
body.app .mhead-back .ic { flex: none; width: 18px; height: 18px; }
body.app .mhead-back-tx { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
@media (hover: hover) { body.app .mhead-back:hover { background: color-mix(in srgb, var(--oli-00) 26%, transparent); } }
@media (max-width: 899px) {
  body.app:is([data-nivel="sub"], [data-nivel="paso"]) .mhead-body { height: calc(92px - 36px * var(--c)); }
  body.app:is([data-nivel="sub"], [data-nivel="paso"]) { --mhead-sp: 98px; }   /* el espaciador .mhead-sp lo lee (styles.css): una sola altura */
  body.app:is([data-nivel="sub"], [data-nivel="paso"]) .mhead-tx { display: grid; grid-template-columns: auto minmax(0, 1fr); align-content: center; align-items: center; column-gap: var(--sp-3); align-self: stretch; }
  body.app:is([data-nivel="sub"], [data-nivel="paso"]) .mhead-back { grid-column: 1; grid-row: 1; max-width: 42vw; }
  body.app:is([data-nivel="sub"], [data-nivel="paso"]) .mhead-tx h1 { grid-column: 2; grid-row: 1; font-size: calc(24px - 4px * var(--c)); line-height: 1.12; white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }   /* títulos largos («Avisos y preferencias») pasan a dos líneas en vez de cortarse */
  body.app:is([data-nivel="sub"], [data-nivel="paso"]) .mhead-tx p { grid-column: 1 / -1; grid-row: 2; }
  body.app:is([data-nivel="sub"], [data-nivel="paso"]) .mhead-escudo { display: none; }
}
@media (min-width: 900px) {
  body.app .mhead-back { min-height: 0; margin: 0 0 var(--sp-1) -2px; padding: 2px var(--sp-1) 2px 0; border-radius: var(--radio-campo); background: none; color: var(--oli-300); font-size: var(--t-14); }
  body.app .mhead-back:hover { background: none; color: var(--oli-00); text-decoration: underline; text-underline-offset: 3px; }
  body.app .mhead-back:active { background: none; }
  body.app[data-nivel="paso"] .mhead-escudo { display: none; }
}

/* Movimiento entre pantallas (View Transitions con respaldo por clases). html[data-nav] = adelante | atras | tab lo pone el router: avanzar entra por la derecha, volver por la izquierda,
   cambiar de pestaña es un fundido corto. La cabecera y la barra tienen nombre propio: no se deslizan con la pantalla. Con «reducir movimiento» todo es instantáneo (las duraciones valen 0,01 ms). */
@keyframes oliEntraDer { from { opacity: 0; transform: translateX(40px); } to { opacity: 1; transform: none; } }
@keyframes oliEntraIzq { from { opacity: 0; transform: translateX(-40px); } to { opacity: 1; transform: none; } }
@keyframes oliSaleIzq { to { opacity: 0; transform: translateX(-40px); } }
@keyframes oliSaleDer { to { opacity: 0; transform: translateX(40px); } }
@keyframes oliFundido { from { opacity: 0; } to { opacity: 1; } }
@keyframes oliSale { to { opacity: 0; } }
body.app #view > .section { animation: none; }
@supports (view-transition-name: none) {
  body.app .mhead { view-transition-name: oli-cabecera; }
  body.app .tabs { view-transition-name: oli-navegacion; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--t-cambio); animation-timing-function: var(--ease); }
  html[data-nav="adelante"]::view-transition-old(root) { animation-name: oliSaleIzq; }
  html[data-nav="adelante"]::view-transition-new(root) { animation-name: oliEntraDer; }
  html[data-nav="atras"]::view-transition-old(root) { animation-name: oliSaleDer; }
  html[data-nav="atras"]::view-transition-new(root) { animation-name: oliEntraIzq; }
  html[data-nav="tab"]::view-transition-old(root) { animation-name: oliSale; animation-duration: var(--t-toque); }
  html[data-nav="tab"]::view-transition-new(root) { animation-name: oliFundido; animation-duration: var(--t-toque); }
}
@supports not (view-transition-name: none) {
  body.app #view.nav-anim { animation: oliFundido var(--t-toque) var(--ease) both; }
  html[data-nav="adelante"] body.app #view.nav-anim { animation-name: oliEntraDer; animation-duration: var(--t-cambio); }
  html[data-nav="atras"] body.app #view.nav-anim { animation-name: oliEntraIzq; animation-duration: var(--t-cambio); }
}

/* Márgenes de pantalla: 16 px, 20 desde 600 px. */
@media (min-width: 600px) and (max-width: 899px) { body.app .wrap { padding-left: 20px; padding-right: 20px; } }

/* utilidades:inicio (generado por la migración de style=""; una clase por declaración, con !important para igualar al estilo en línea) */
.ai-center { align-items: center !important }
.ai-start { align-items: flex-start !important }
.as-center { align-self: center !important }
.bg-danger-bg { background: var(--danger-bg) !important }
.c-inherit { color: inherit !important }
.c-text-error { color: var(--text-error) !important }
.c-text-secondary { color: var(--text-secondary) !important }
.c-text-success { color: var(--text-success) !important }
.c-text-tertiary { color: var(--text-tertiary) !important }
.cur-p { cursor: pointer !important }
.fd-col { flex-direction: column !important }
.flex-1 { flex: 1 !important }
.flex-none { flex: 0 0 auto !important }
.fw-400 { font-weight: 400 !important }
.fw-600 { font-weight: 600 !important }
.fw-700 { font-weight: 700 !important }
.fw-800 { font-weight: 800 !important }
.gap-8 { gap: 8px !important }
.gap-12 { gap: 12px !important }
.grid-1 { grid-template-columns: 1fr !important }
.h-14 { height: 14px !important }
.jc-between { justify-content: space-between !important }
.jc-end { justify-content: flex-end !important }
.lh-1 { line-height: 1 !important }
.m-0 { margin: 0 !important }
.mb-0 { margin-bottom: 0 !important }
.mb-2 { margin-bottom: 2px !important }
.mb-6 { margin-bottom: 6px !important }
.mb-8 { margin-bottom: 8px !important }
.mb-10 { margin-bottom: 10px !important }
.mb-12 { margin-bottom: 12px !important }
.mb-14 { margin-bottom: 14px !important }
.minw-200 { min-width: 200px !important }
.ml-0 { margin-left: 0 !important }
.ml-18 { margin-left: 18px !important }
.mr-0 { margin-right: 0 !important }
.mr-8 { margin-right: 8px !important }
.mt-0 { margin-top: 0 !important }
.mt-2 { margin-top: 2px !important }
.mt-6 { margin-top: 6px !important }
.mt-8 { margin-top: 8px !important }
.mt-10 { margin-top: 10px !important }
.mt-12 { margin-top: 12px !important }
.mt-14 { margin-top: 14px !important }
.mt-16 { margin-top: 16px !important }
.mt-30 { margin-top: 30px !important }
.mt-34 { margin-top: 34px !important }
.mx-0 { margin-left: 0 !important; margin-right: 0 !important }
.my-4 { margin-top: 4px !important; margin-bottom: 4px !important }
.my-6 { margin-top: 6px !important; margin-bottom: 6px !important }
.my-7 { margin-top: 7px !important; margin-bottom: 7px !important }
.my-8 { margin-top: 8px !important; margin-bottom: 8px !important }
.my-10 { margin-top: 10px !important; margin-bottom: 10px !important }
.my-12 { margin-top: 12px !important; margin-bottom: 12px !important }
.nowrap { white-space: nowrap !important }
.op-70 { opacity: .7 !important }
.ox-auto { overflow-x: auto !important }
.pb-14 { padding-bottom: 14px !important }
.pl-14 { padding-left: 14px !important }
.pr-14 { padding-right: 14px !important }
.pt-14 { padding-top: 14px !important }
.px-0 { padding-left: 0 !important; padding-right: 0 !important }
.px-16 { padding-left: 16px !important; padding-right: 16px !important }
.py-6 { padding-top: 6px !important; padding-bottom: 6px !important }
.py-10 { padding-top: 10px !important; padding-bottom: 10px !important }
.ta-center { text-align: center !important }
.ta-left { text-align: left !important }
.td-none { text-decoration: none !important }
.txt-11 { font-size: 11px !important }
.txt-12 { font-size: 12px !important }
.txt-13 { font-size: 13px !important }
.txt-14 { font-size: 14px !important }
.txt-15 { font-size: 15px !important }
.txt-19 { font-size: 19px !important }
.txt-24 { font-size: 24px !important }
.txt-34 { font-size: 34px !important }
.txt-t13 { font-size: var(--t-13) !important }
.txt-t15 { font-size: var(--t-15) !important }
.txt-t20 { font-size: var(--t-20) !important }
.w-14 { width: 14px !important }
.w-100 { width: 100% !important }
.w-150 { width: 150px !important }
.w-220 { width: 220px !important }
.w-auto { width: auto !important }
.wb-all { word-break: break-all !important }
.fl-wrap { flex-wrap: wrap !important }
/* utilidades:fin */

/* orden de cobro: casillas de cuotas del personal (Asistido, Back Office, Gestión). Objetivo táctil de 48 px; el motivo del bloqueo va en texto. Solo tokens. */
.orden-casilla { width: 24px; height: 24px; margin: 12px; flex: none; cursor: pointer; }
.orden-casilla:disabled { cursor: not-allowed; opacity: .55; }
.orden-casilla:focus-visible { outline: 2px solid var(--text-primary); outline-offset: 2px; }
.orden-bloqueada { color: var(--text-secondary); }
.orden-motivo { display: block; min-height: 20px; font-size: var(--t-13); font-weight: 600; color: var(--text-secondary); }
.tes-op:has(.orden-casilla) { min-height: 48px; display: flex; flex-wrap: wrap; align-items: center; }
.asi-cuota-celda { min-width: 48px; min-height: 48px; }

/* ── Sello «Olimpista verificado» (OLI.sello): estrella de 12 puntas con tilde. Relleno = tinta (--text-primary) y tilde = fondo (--surface-page): contraste máximo en oscuro, claro y automático.
   Sobre superficies que no cambian de tema (el carnet, siempre negro) se fijan con --oli-00 / --oli-900 en esa pantalla. Un solo tamaño por clase. ── */
.sello { --sello-c: var(--text-primary); --sello-t: var(--surface-page); flex: none; width: var(--sello-tam, 22px); height: var(--sello-tam, 22px); vertical-align: -0.28em; overflow: visible; }
.sello-16 { --sello-tam: 16px; } .sello-22 { --sello-tam: 22px; } .sello-26 { --sello-tam: 26px; } .sello-30 { --sello-tam: 30px; } .sello-44 { --sello-tam: 44px; }
.sello-f { fill: var(--sello-c); stroke: var(--sello-c); stroke-width: .05; stroke-linejoin: round; }
.sello-t { fill: none; stroke: var(--sello-t); stroke-width: .085; stroke-linecap: round; stroke-linejoin: round; }
@keyframes sello-entra { from { transform: scale(.9); opacity: .6; } to { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: no-preference) { .sello { animation: sello-entra 200ms ease-out both; } }
/* Color del sello por condición, NO por plan (los planes cambian en 2027): Socio = azul de verificado (el de X y LinkedIn); Vitalicio = plateado; el resto conserva la tinta. `svg.sello.sello-*` gana a `.cn2-frente .sello` y a `.sello`. */
svg.sello.sello-azul { --sello-c: var(--verificado-azul); --sello-t: var(--oli-00); }
svg.sello.sello-plata { --sello-c: var(--verificado-plata); --sello-t: var(--oli-900); }
.sello-btn { display: inline-flex; align-items: center; justify-content: center; flex: none; padding: 0; margin: 0; border: 0; background: transparent; color: inherit; cursor: pointer; border-radius: var(--r-pill); min-width: 24px; min-height: 24px; }
.sello-btn:focus-visible { outline: 2px solid var(--focus-ring, currentColor); outline-offset: 2px; }
.sello-nombre { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; }
.sello-nombre > .sello-nombre-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.sello-hoja { display: flex; flex-direction: column; align-items: center; gap: var(--sp-3); text-align: center; padding: var(--sp-2) 0 var(--sp-3); }
.sello-hoja p { margin: 0; color: var(--text-secondary); font-size: var(--t-15); line-height: 1.5; }
.sello-hoja .btn { align-self: stretch; }
.sello-linea { margin: 0 0 var(--sp-3); font: 600 var(--t-17) / 1.2 var(--display); }

/* ── Tienda oficial (tienda.js): carrusel de productos de la tienda del Club y fila de solo enlace. Todo son enlaces externos (no hay botón principal). ── */
.tn { min-width: 0; }
.ih-main > .ih-tienda { order: 5; }   /* Inicio: justo después de «Beneficios para vos» (el carrusel de Beneficios tiene el mismo orden y va antes en el documento) */
.tn-cab { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); margin: 0 0 var(--sp-2); }
.tn-cab h3 { margin: 0; font: 700 var(--t-20) / 1.2 var(--display); letter-spacing: -.02em; }
.tn-toda { display: inline-flex; align-items: center; min-height: var(--alto-boton-ter); padding: 0 var(--sp-1); color: var(--text-primary); font-size: var(--t-13); font-weight: 700; text-decoration: none; white-space: nowrap; }
.tn-sub, .tn-socios, .tn-aviso { margin: 0 0 var(--sp-3); color: var(--text-secondary); font-size: var(--t-13); line-height: 1.4; }
.tn-aviso { margin: var(--sp-1) 0 var(--sp-2); font-size: var(--t-12); }
.tn-rail { list-style: none; margin: 0; padding: 0 0 6px; display: flex; gap: var(--sp-3); overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.tn-rail::-webkit-scrollbar { display: none; }
.tn-item { flex: 0 0 152px; scroll-snap-align: start; min-width: 0; }
.tn-card { display: flex; flex-direction: column; gap: var(--sp-2); height: 100%; min-height: var(--alto-boton-ter); padding: var(--sp-2); border-radius: var(--radio-sm); background: var(--surface-card); box-shadow: var(--elev-1); color: var(--text-primary); text-decoration: none; }
.tn-img { display: flex; align-items: center; justify-content: center; aspect-ratio: 1 / 1; overflow: hidden; border-radius: var(--r-8); background: var(--overlay-soft); color: var(--text-secondary); font: 700 var(--t-20) / 1 var(--display); }
.tn-img img { width: 100%; height: 100%; object-fit: contain; }
.tn-nom { font-size: var(--t-14); font-weight: 600; line-height: 1.25; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
.tn-pre { font-size: var(--t-14); font-weight: 700; }
.tn-ir { margin-top: auto; font-size: var(--t-12); font-weight: 700; color: var(--text-secondary); }
.tn-esq { min-height: 216px; }
.tn-fila { display: flex; align-items: center; gap: var(--sp-3); min-height: var(--alto-fila); padding: var(--sp-2) var(--sp-4); border-radius: var(--radio-sm); background: var(--surface-card); box-shadow: var(--elev-1); color: var(--text-primary); text-decoration: none; }
.tn-fila-ic { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 36px; width: 36px; height: 36px; border-radius: var(--r-pill); background: var(--overlay-soft); }
.tn-fila-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.tn-fila-tx small { color: var(--text-secondary); font-size: var(--t-13); }
.tn-fila > .ic:last-child { color: var(--text-tertiary); }
.tn-card:focus-visible, .tn-toda:focus-visible, .tn-fila:focus-visible, .tn-rail:focus-visible { outline: var(--focus-outline); outline-offset: 2px; }
.atc-b.atc-p a[data-tn] { color: inherit; text-decoration: underline; text-underline-offset: 2px; font-weight: 700; }

/* Revisión estética del Inicio (escritorio): carrusel con borde que se desvanece, saludo legible, billetera vacía compacta, escalón con lo que falta. */
.tn-rail.tn-mas { -webkit-mask-image: linear-gradient(to right, black calc(100% - 48px), transparent); mask-image: linear-gradient(to right, black calc(100% - 48px), transparent); }
.tn-nom { text-transform: none; }
.mhead-tx p { color: var(--oli-300, var(--oli-400)); }
.wg-2.wg-vacia { gap: var(--sp-2); }
.wg-2.wg-vacia .wg-nota { font-size: var(--t-14); color: var(--text-primary); }
.wg-falta { font-size: var(--t-12); font-weight: 600; color: var(--text-primary); text-align: center; }

/* ── Contraseñas (clave.js): recuperar la cuenta, requisitos en vivo y cambiar la contraseña. Solo tokens; prefijo .cl- ── */
.cl-vista { display: block; }
.cl-ic { width: var(--sp-8, 64px); height: var(--sp-8, 64px); margin: 0 0 var(--sp-3); border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--surface-input); color: var(--text-primary); }
.cl-ic-ok { background: var(--ok-bg); color: var(--ok-fg); }
.cl-h { margin: 0 0 var(--sp-2); font-size: var(--t-20); line-height: 1.25; }
.cl-h:focus { outline: none; }
.cl-p { margin: 0 0 var(--sp-4); color: var(--text-secondary); font-size: var(--t-15); line-height: 1.5; overflow-wrap: anywhere; }
.cl-p strong { color: var(--text-primary); }
.cl-lista { margin: 0 0 var(--sp-4); padding-left: var(--sp-4); color: var(--text-secondary); font-size: var(--t-15); line-height: 1.5; }
.cl-lista li { margin: 0 0 var(--sp-1); }
.cl-acc { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-3); }
.cl-acc .btn-texto { align-self: stretch; }
.oli-modal .cl-vista .campo input:not([type="checkbox"]):not([type="radio"]), .cl-vista .campo input { margin: 0; }
.cl-olv { margin: calc(var(--sp-1) * -1) 0 var(--sp-3); text-align: right; }
.cl-olvide-in { margin: var(--sp-2) 0 var(--sp-3); text-align: center; }
.cl-req { list-style: none; margin: var(--sp-2) 0 0; padding: 0; }
.cl-req-i { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--t-13); font-weight: 600; color: var(--text-secondary); }
.cl-mk { position: relative; flex: none; box-sizing: border-box; width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid var(--border-default); }
.cl-req-i[data-ok="1"] { color: var(--ok-fg); }
.cl-req-i[data-ok="1"] .cl-mk { background: var(--ok-fg); border-color: var(--ok-fg); }
.cl-req-i[data-ok="1"] .cl-mk::after { content: ""; position: absolute; left: 5px; top: 2px; width: 4px; height: 8px; border: solid var(--surface-page); border-width: 0 2px 2px 0; transform: rotate(45deg); }

/* «Volver» de las páginas públicas (sin sesión: subasta, carnet, legal, ayuda, restablecer): MISMO componente que el de la app (.mhead-back, misma píldora de 32 px con área táctil de 44 px; en escritorio, enlace claro), con destino fijo y nunca history.back(). En .pub (fondo del tema) el color es el del texto. */
body:is(.puerta, .pub) .mhead-back { position: relative; display: inline-flex; align-items: center; gap: var(--sp-1); align-self: flex-start; flex: 0 1 auto; min-width: 0; max-width: 100%; min-height: 32px; margin: 0; padding: 0 var(--sp-3) 0 var(--sp-2); border-radius: var(--radio-full);
  background: color-mix(in srgb, var(--oli-00) 16%, transparent); color: var(--oli-00); font: 600 var(--t-13) / 1 var(--display); text-decoration: none; white-space: nowrap; transition: background-color var(--t-presion) var(--ease), transform var(--t-presion) var(--ease); }
body:is(.puerta, .pub) .mhead-back::before { content: ""; position: absolute; inset: -6px -4px; min-width: calc(var(--touch) - 4px); min-height: calc(var(--touch) - 4px); }
body:is(.puerta, .pub) .mhead-back:active { transform: scale(.96); background: color-mix(in srgb, var(--oli-00) 28%, transparent); }
body:is(.puerta, .pub) .mhead-back:focus-visible { outline: 2px solid var(--oli-00); outline-offset: 2px; }
body:is(.puerta, .pub) .mhead-back .ic { flex: none; width: 18px; height: 18px; }
body:is(.puerta, .pub) .mhead-back-tx { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
@media (hover: hover) { body:is(.puerta, .pub) .mhead-back:hover { background: color-mix(in srgb, var(--oli-00) 26%, transparent); } }
body.pub .mhead-back { color: var(--text-primary); background: color-mix(in srgb, var(--text-primary) 10%, transparent); margin-bottom: var(--sp-3); }
body.pub .mhead-back:focus-visible { outline: var(--focus-outline); }
@media (min-width: 900px) {
  body:is(.puerta, .pub) .mhead-back { min-height: 0; margin: 0 0 var(--sp-1) -2px; padding: 2px var(--sp-1) 2px 0; border-radius: var(--radio-campo); background: none; color: var(--oli-300); font-size: var(--t-14); }
  body:is(.puerta, .pub) .mhead-back:hover { background: none; color: var(--oli-00); text-decoration: underline; text-underline-offset: 3px; }
  body:is(.puerta, .pub) .mhead-back:active { background: none; }
  body.pub .mhead-back, body.pub .mhead-back:hover { color: var(--text-primary); }
}
