/* ============================================================================
   MI PORTAFOLIO · COMPONENTES EDITORIALES
   Depende de mp-tokens.css. Aquí vive la retícula de prensa: masthead,
   cintilla de mercados, encabezados de sección, celdas con hairline,
   colofón, y el reskin de todo lo que el JS genera (modales, toasts,
   tooltips, tablas, estados vacíos y de error).
   ========================================================================== */

/* ─────────────────────────── BASE TIPOGRÁFICA ───────────────────────────── */
html {
  /* Color PLANO, no degradado. El degradado se estiraba a lo alto del
     DOCUMENTO, así que cualquier elemento pegajoso con fondo opaco —el
     selector de mazos, la barra superior— pintaba un tono que no coincidía
     con el papel de debajo y dejaba un escalón visible al hacer scroll. Un
     papel uniforme es además lo que hace un diseñador: la profundidad la dan
     las sombras de las tarjetas, no un degradado que nadie ve.
     Va en `html` porque el fondo del elemento raíz se propaga al canvas y así
     cubre también el rebote elástico de iOS sin franjas. */
  background-color: var(--sup) !important;
  background-image: none !important;
}
html, body {
  color: var(--tinta-2) !important;
  font-family: var(--ff-sans) !important;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Titulares y cifras protagonistas: serif editorial. */
h1, h2, h3, .mp-titular, .mp-cifra {
  font-family: var(--ff-serif) !important;
  color: var(--tinta-1);
  letter-spacing: -0.012em;
  font-feature-settings: 'ss01';
}
h1, h2 { line-height: 1.08; }
h3     { line-height: 1.18; }

/* h4/h5 quedan en sans: son rótulos de UI, no titulares. */
h4, h5, h6 { font-family: var(--ff-sans) !important; color: var(--tinta-1); }

/* TODO número, ticker, porcentaje y etiqueta técnica: monoespaciada tabular.
   `.tabular` ya estaba repartida por el markup en 313 sitios numéricos, así
   que se convierte en el gancho del sistema en vez de inventar una clase
   nueva y tener que reetiquetar todo. */
/* LA MONOESPACIADA ES PARA CIFRAS Y CLAVES, NUNCA PARA PROSA.
   Tres voces y solo tres: serif para titulares, sans para todo lo que se lee
   como frase, mono para lo que se lee como dato (precios, porcentajes, claves
   de pizarra). Cuando la mono se desborda a fechas, leyendas, pies de página y
   botones —como estaba— la pantalla deja de tener jerarquía: todo suena a
   terminal y nada suena a producto. Si vas a poner --ff-mono en una regla
   nueva, pregúntate si el usuario lee ESO como número. Si no, es sans. */
.tabular, .mp-num, .mp-ticker, .mp-etq, code, kbd, samp {
  font-family: var(--ff-mono) !important;
  font-variant-numeric: tabular-nums lining-nums !important;
  font-feature-settings: 'tnum' 1, 'lnum' 1, 'zero' 1;
  letter-spacing: -0.01em;
}

/* Cualquier celda de tabla alinea cifras aunque no lleve .tabular:
   así los números nunca "bailan" al refrescarse. */
td, th, input[type="number"], .mp-tabla td, .mp-tabla th {
  font-variant-numeric: tabular-nums lining-nums;
}

/* Etiqueta técnica: mono, versalita óptica, tracking abierto. */
.mp-etq {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 10px;
  font-weight: 500;
  color: var(--tinta-3);
}

/* ────────────────────────────── REGLAS ──────────────────────────────────── */
/* Regla doble de cabecera: 2px + hairline, como una primera plana. */
.mp-regla-doble {
  border: 0;
  border-top: 2px solid var(--tinta-1);
  position: relative;
  margin: 0;
  height: 4px;
}
.mp-regla-doble::after {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 3px;
  border-top: 1px solid var(--regla-fuerte);
}
.mp-regla      { border: 0; border-top: 1px solid var(--regla); margin: 0; }
.mp-regla-2px  { border: 0; border-top: 2px solid var(--tinta-1); margin: 0; }

/* ───────────────────────────── MASTHEAD ─────────────────────────────────── */
.mp-masthead {
  font-family: var(--ff-serif) !important;
  font-weight: 700;
  color: var(--tinta-1);
  letter-spacing: -0.028em;
  line-height: .92;
  /* El mínimo (17px) está medido: por debajo de eso el cluster
     logo + marca + Suscribirse + Mi cuenta ya no cabe en 375px y alguno de
     los dos botones que Apple debe encontrar quedaría fuera de pantalla. */
  font-size: clamp(17px, 4.4vw, 30px);
  white-space: nowrap;
}
.mp-masthead-meta {
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-meta);
  letter-spacing: -0.006em;
  color: var(--tinta-4);
  text-transform: none;
  line-height: 1.3;
}
/* La regla doble de primera plana desaparece: era el elemento más
   "periódico impreso" de la pantalla y chocaba de frente con las tarjetas.
   La identidad editorial se queda donde importa —el serif del logotipo y de
   los titulares, la monoespaciada tabular de las cifras—, pero la piel de la
   app pasa a ser la misma en todas partes. */
.mp-regla-doble { display: none; }

/* Un carrusel que se corta a media palabra parece un error de maquetación. El
   borde por el que queda contenido se desvanece; el que ya se acabó, no. Lo
   marca _bordesDeScroll() en app.js con data-borde. */
[data-borde="ini"]   { -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent 100%);
                               mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent 100%); }
[data-borde="fin"]   { -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 32px);
                               mask-image: linear-gradient(90deg, transparent 0, #000 32px); }
[data-borde="medio"] { -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 32px, #000 calc(100% - 32px), transparent 100%);
                               mask-image: linear-gradient(90deg, transparent 0, #000 32px, #000 calc(100% - 32px), transparent 100%); }

/* ─────────────────── PANEL DE PORTAFOLIOS (perfiles) ───────────────────── */
.mp-perfiles { display: flex; flex-direction: column; gap: var(--paso-2); }
.mp-perfil {
  display: flex; align-items: center; gap: var(--paso-2);
  border: var(--hairline) solid var(--regla);
  border-radius: var(--radio);
  background: var(--sup);
  overflow: hidden;
}
.mp-perfil.activo { border-color: var(--tinta-1); box-shadow: inset 0 0 0 1px var(--tinta-1); }
.mp-perfil-elegir {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: var(--paso-3);
  background: transparent; border: 0; cursor: pointer;
  padding: var(--paso-3); min-height: 56px;
  text-align: left;
}
.mp-perfil-elegir:hover { background: var(--sup-hondo); }
/* El avatar es la identidad del portafolio: a 20px no se distinguía un zorro
   de un panda, que es justo lo que hace útil tener avatares. */
.mp-perfil-avatar {
  flex: 0 0 auto; width: 40px; height: 40px;
  border-radius: var(--radio-chico); overflow: hidden;
  display: inline-flex;
}
.mp-perfil-nom {
  flex: 1 1 auto; min-width: 0;
  font-size: var(--txt-cuerpo); font-weight: 600; color: var(--tinta-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mp-perfil-marca {
  flex: 0 0 auto;
  font-size: var(--txt-etq); font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--sello);
}
/* Editar y borrar SIEMPRE visibles. Estaban tras :hover, que en una pantalla
   táctil significa que no existen. */
.mp-perfil-accion {
  flex: 0 0 auto;
  width: 44px; height: 44px; margin-right: 2px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 0; cursor: pointer;
  color: var(--tinta-3); border-radius: var(--radio-chico);
}
.mp-perfil-accion svg { width: 17px; height: 17px; }
.mp-perfil-accion:hover { background: var(--sup-hondo); color: var(--tinta-1); }
.mp-perfil-accion.borrar:hover { color: var(--baja); }

/* Formulario de crear/editar */
.mp-campo-etq {
  display: block;
  font-size: var(--txt-etq); font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--tinta-3);
  margin: var(--paso-4) 0 var(--paso-2);
}
.mp-campo {
  width: 100%; box-sizing: border-box;
  padding: var(--paso-3) var(--paso-4) !important;
  min-height: 44px !important;
  font-size: 16px !important;          /* 16px o iOS hace zoom al enfocar */
  border-radius: var(--radio) !important;
}
.mp-avatares {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(52px, 1fr));
  gap: var(--paso-2);
}
.mp-avatar {
  aspect-ratio: 1; padding: 0;
  background: transparent; cursor: pointer;
  border: 2px solid transparent;
  border-radius: var(--radio-chico);
  overflow: hidden; opacity: .55;
  transition: opacity var(--t-rapida) var(--easing),
              border-color var(--t-rapida) var(--easing);
}
.mp-avatar:hover { opacity: .85; }
.mp-avatar.activo { opacity: 1; border-color: var(--tinta-1); }
.mp-avatar:focus-visible { outline: 2px solid var(--sello); outline-offset: 2px; }

/* ─────────────── SELECTOR DE PERIODO DEL PERIÓDICO ─────────────────────── */
.mp-periodos {
  display: inline-flex;
  gap: 2px;
  /* Va dentro del mazo, sobre sus tarjetas. */
  margin: 0 0 var(--paso-4);
  padding: 3px;
  background: var(--sup-hondo);
  border-radius: 999px;
}
.mp-periodo {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--tinta-3);
  font-family: var(--ff-sans);
  font-size: var(--txt-meta);
  font-weight: 600;
  letter-spacing: -0.006em;
  padding: var(--paso-2) var(--paso-4);
  min-height: 36px;
  border-radius: 999px;
  cursor: pointer;
  transition: background-color var(--t-rapida) var(--easing),
              color var(--t-rapida) var(--easing);
}
.mp-periodo:hover { color: var(--tinta-1); }
.mp-periodo.activa {
  background: var(--sup-panel);
  color: var(--tinta-1);
  box-shadow: var(--elev-1);
}
.mp-periodo:focus-visible { outline: 2px solid var(--sello); outline-offset: 2px; }

/* Mientras se rehace un mazo tras cambiar de ventana. Sin esto el botón parece
   no haber hecho nada durante el segundo que tarda la petición. */
.mp-mazo-pane.cargando { opacity: .45; transition: opacity 120ms var(--easing); }
.mp-mazo-pane.cargando .mp-tarjeta { pointer-events: none; }

/* ────────────────── PANELES DE LISTAS (watchlist / widget) ─────────────── */
.mp-listas { margin-top: var(--paso-7); }
.mp-panel {
  background: var(--sup-panel);
  border: var(--hairline) solid var(--regla);
  border-radius: var(--radio-tarjeta);
  box-shadow: var(--elev-1);
  padding: var(--paso-5);
  margin-bottom: var(--paso-4);
}
.mp-panel-titulo {
  font-family: var(--ff-serif) !important;
  font-size: var(--txt-seccion); font-weight: 700; letter-spacing: -0.02em;
  color: var(--tinta-1); margin: 0;
}
.mp-panel-nota {
  font-size: var(--txt-meta); line-height: 1.55; color: var(--tinta-3);
  margin: var(--paso-2) 0 var(--paso-4);
}
.mp-panel-pie {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--paso-3); flex-wrap: wrap; margin-top: var(--paso-4);
}
.mp-panel-estado { font-size: var(--txt-etq); color: var(--tinta-4); }

/* Buscador con lupa. La lupa va DENTRO del campo y el padding izquierdo le
   deja su sitio: un icono flotando encima del texto es el defecto clásico. */
.mp-buscador { position: relative; }
.mp-buscador-lupa {
  position: absolute; left: var(--paso-3); top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; color: var(--tinta-4); pointer-events: none;
}
.mp-buscador input {
  width: 100%; box-sizing: border-box;
  /* !important porque la hoja móvil de ux_helpers.js fija `padding: 10px 12px`
     a todos los input: sin esto el texto arranca bajo la lupa y se lee
     "(lupa)usca una acción". */
  padding: var(--paso-3) var(--paso-4) var(--paso-3) calc(var(--paso-3) * 2 + 18px) !important;
  min-height: 44px !important;
  font-size: 16px !important;   /* 16px o iOS hace zoom al enfocar */
  border-radius: var(--radio) !important;
}

/* Fichas de la lista. Cada una es su propio par (ir al análisis / quitar). */
.mp-chips {
  display: flex; flex-wrap: wrap; gap: var(--paso-2);
  margin-top: var(--paso-3); min-height: 4px;
}
.mp-chip {
  display: inline-flex; align-items: center; gap: 0;
  background: var(--sup); border: var(--hairline) solid var(--regla);
  border-radius: 999px; overflow: hidden;
}
.mp-chip-nom {
  font-family: var(--ff-mono); font-variant-numeric: tabular-nums;
  font-size: var(--txt-meta); font-weight: 600; color: var(--tinta-1);
  background: transparent; border: 0; cursor: pointer;
  padding: var(--paso-2) var(--paso-2) var(--paso-2) var(--paso-3);
  min-height: 36px;
}
.mp-chip-nom:hover { color: var(--sello-vivo); }
.mp-chip-quitar {
  background: transparent; border: 0; cursor: pointer;
  color: var(--tinta-4); font-size: 17px; line-height: 1;
  padding: 0 var(--paso-3) 0 var(--paso-2); min-height: 36px;
}
.mp-chip-quitar:hover { color: var(--baja); }
.mp-chip.arrastrable { cursor: grab; }
.mp-chips-vacio { font-size: var(--txt-meta); color: var(--tinta-4); margin: var(--paso-2) 0 0; }

/* ─────────────────────────── MODAL ──────────────────────────────────────
   Los diálogos de la app estaban escritos a mano, cada uno con su cssText:
   por eso ninguno se parecía al siguiente. Este es el molde. */
.mp-modal {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  padding: var(--paso-4);
  background: rgba(20,22,27,.42);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  animation: mp-modal-entra 160ms var(--easing);
}
@keyframes mp-modal-entra { from { opacity: 0 } to { opacity: 1 } }
.mp-modal-caja {
  background: var(--sup-panel);
  border: var(--hairline) solid var(--regla);
  border-radius: var(--radio-tarjeta);
  box-shadow: var(--elev-3);
  max-width: 560px; width: 100%;
  max-height: min(86vh, 780px); overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.mp-modal-cuerpo { padding: var(--paso-5); }
.mp-modal-cabecera {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--paso-4); margin-bottom: var(--paso-4);
}
.mp-modal-etq {
  font-size: var(--txt-etq); font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--sello); margin: 0;
}
.mp-modal-titulo {
  font-family: var(--ff-serif) !important;
  font-size: var(--txt-seccion); font-weight: 700; letter-spacing: -0.02em;
  color: var(--tinta-1); margin: var(--paso-1) 0 0;
}
.mp-modal-cerrar {
  flex: 0 0 auto; width: 44px; height: 44px; margin: -6px -8px 0 0;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 0; cursor: pointer;
  font-size: 26px; line-height: 1; color: var(--tinta-3);
  border-radius: 999px;
}
.mp-modal-cerrar:hover { background: var(--sup-hondo); color: var(--tinta-1); }
.mp-modal-parrafo { font-size: var(--txt-cuerpo); line-height: 1.55; color: var(--tinta-2); margin: 0 0 var(--paso-4); }
.mp-modal-nota    { font-size: var(--txt-meta); line-height: 1.55; color: var(--tinta-3); margin: var(--paso-3) 0 0; }
.mp-modal-aviso {
  font-size: var(--txt-meta); line-height: 1.55; color: var(--sello-vivo);
  background: var(--sello-tenue); border: var(--hairline) solid var(--regla);
  border-radius: var(--radio); padding: var(--paso-3); margin: 0 0 var(--paso-4);
}
.mp-modal-acciones { display: flex; gap: var(--paso-2); margin-top: var(--paso-5); }
.mp-modal-acciones .mp-btn { flex: 1; }
.mp-modal-ancho { width: 100%; margin-top: var(--paso-4); }

/* Selector de dos opciones (mínimo / bien balanceado). Segmentado, no radios:
   son dos respuestas a la misma pregunta y se comparan de un vistazo. */
/* Hasta tres opciones (mínimo / equilibrado / bien balanceado). A tres, en
   iPhone no caben en fila sin estrujar la cifra, así que se apilan. */
.mp-opciones { display: flex; gap: var(--paso-2); margin: 0 0 var(--paso-4); }
@media (max-width: 479px) {
  .mp-opciones:has(.mp-opcion:nth-child(3)) { flex-direction: column; }
  .mp-opciones:has(.mp-opcion:nth-child(3)) .mp-opcion {
    flex-direction: row; align-items: baseline; gap: var(--paso-3);
  }
  .mp-opciones:has(.mp-opcion:nth-child(3)) .mp-opcion-etq { flex: 1 1 auto; white-space: nowrap; }
  .mp-opciones:has(.mp-opcion:nth-child(3)) .mp-opcion-nota { white-space: nowrap; }
}
.mp-opcion {
  flex: 1; display: flex; flex-direction: column; gap: 2px;
  padding: var(--paso-3); min-height: 44px;
  background: var(--sup); color: var(--tinta-2);
  border: var(--hairline) solid var(--regla);
  border-radius: var(--radio); cursor: pointer; text-align: left;
  transition: border-color var(--t-rapida) var(--easing),
              background-color var(--t-rapida) var(--easing);
}
.mp-opcion:hover { border-color: var(--regla-fuerte); }
.mp-opcion.activa {
  background: var(--sup-panel); border-color: var(--tinta-1);
  box-shadow: inset 0 0 0 1px var(--tinta-1);
}
.mp-opcion-etq   { font-size: var(--txt-etq); font-weight: 600; letter-spacing: .06em;
                   text-transform: uppercase; color: var(--tinta-3); }
.mp-opcion.activa .mp-opcion-etq { color: var(--sello); }
.mp-opcion-cifra { font-family: var(--ff-mono); font-variant-numeric: tabular-nums lining-nums;
                   font-size: var(--txt-titular); font-weight: 700; color: var(--tinta-1);
                   letter-spacing: -0.02em; }
.mp-opcion-nota  { font-size: var(--txt-etq); color: var(--tinta-4);
                   font-family: var(--ff-mono); font-variant-numeric: tabular-nums; }

/* Tabla del plan de compra. Los números en mono y alineados a la derecha para
   que las columnas se puedan comparar de un vistazo. */
.mp-tabla-envoltura { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.mp-tabla-plan { width: 100%; border-collapse: collapse; }
.mp-tabla-plan th {
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-etq); font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--tinta-3);
  text-align: right; padding: 0 0 var(--paso-2);
  border-bottom: var(--hairline) solid var(--regla);
}
.mp-tabla-plan th:first-child, .mp-tabla-plan td:first-child { text-align: left; }
.mp-tabla-plan td {
  padding: var(--paso-3) 0; text-align: right;
  font-size: var(--txt-meta); color: var(--tinta-2);
  border-bottom: var(--hairline) solid var(--regla-suave);
  white-space: nowrap;
}
.mp-tabla-plan td:not(:first-child) { padding-left: var(--paso-4); }
.mp-tabla-plan .mp-tabla-clave { font-weight: 600; color: var(--tinta-1); }
.mp-tabla-plan .mp-num, .mp-tabla-plan tfoot td {
  font-family: var(--ff-mono) !important;
  font-variant-numeric: tabular-nums lining-nums;
}
.mp-tabla-plan tfoot td {
  font-weight: 700; color: var(--tinta-1);
  border-bottom: 0; border-top: 2px solid var(--tinta-1);
  padding-top: var(--paso-3);
}
.mp-tabla-plan tfoot td:first-child {
  font-family: var(--ff-sans) !important; text-transform: uppercase;
  font-size: var(--txt-etq); letter-spacing: .07em;
}
.mp-tabla-delta { display: inline-block; margin-left: var(--paso-2); color: var(--tinta-4); font-size: var(--txt-etq); }
.mp-tabla-delta.lejos { color: var(--baja); }
.mp-tabla-sub { display: none; }
/* En el screener el nombre va SIEMPRE bajo el ticker, no solo en móvil: es una
   segunda línea de identidad, no una columna que se cae. */
.mp-tabla-plan .mp-tabla-clave .mp-tabla-sub {
  display: block; margin-top: 2px;
  font-size: var(--txt-etq); font-weight: 400; color: var(--tinta-3);
  white-space: normal;
}
.mp-insignia {
  display: inline-block; margin-left: var(--paso-2); vertical-align: 2px;
  padding: 1px 7px; border-radius: 999px;
  background: var(--sup-hondo); color: var(--tinta-3);
  font-family: var(--ff-sans); font-size: 10px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase;
}
/* La columna de identidad envuelve; las de cifras no. Con nowrap en todas, un
   nombre como "CRSP US Total Market" empujaba la tabla fuera del ancho del
   iPhone y el precio quedaba tras un scroll que nadie descubre. */
.mp-tabla-clicable td:first-child { white-space: normal; }
.mp-tabla-clicable tbody tr { cursor: pointer; }
.mp-tabla-clicable tbody tr:hover td { background: var(--sup-hondo); }
.mp-tabla-clicable tbody tr:focus-visible { outline: 2px solid var(--sello); outline-offset: -2px; }
/* En iPhone la cuarta columna no cabe y se iba fuera del scroll: el peso real
   baja a segunda línea bajo la emisora, que es donde se lee sin desplazar. */
@media (max-width: 479px) {
  .mp-tabla-plan .mp-tabla-peso { display: none; }
  .mp-tabla-sub {
    display: block; margin-top: 2px;
    font-size: var(--txt-etq); font-weight: 400; color: var(--tinta-3);
  }
  .mp-tabla-plan td:not(:first-child) { padding-left: var(--paso-3); }
}

/* Franja de prueba gratuita, bajo el masthead. Es una frase, no un dato: sans,
   caja normal y el mismo sello de la app. */
.mp-franja-prueba {
  display: block;
  width: 100%;
  background: var(--sello-tenue);
  border: 0;
  border-bottom: var(--hairline) solid var(--regla);
  color: var(--sello-vivo);
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-meta);
  font-weight: 600;
  letter-spacing: -0.006em;
  padding: var(--paso-2) var(--paso-4);
  text-align: center;
  cursor: pointer;
  min-height: 34px;
}
.mp-franja-prueba:hover { background: var(--sello-tenue2); }

/* ──────────────────── CINTILLA DE MERCADOS (bajo el masthead) ───────────── */
.mp-cintilla {
  /* La cintilla mezcla NOMBRE (prosa) y CIFRA (dato): cada uno con su voz.
     En mono completa, "IPC · NAFTRAC" se leía como salida de consola. */
  font-family: var(--ff-sans) !important;
  background: transparent;
  border: 0;
  padding: 0 var(--paso-5) var(--paso-2);
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.mp-cintilla::-webkit-scrollbar { display: none; }
.mp-cintilla-pista {
  display: flex;
  align-items: stretch;
  gap: var(--paso-2);
  min-width: min-content;
}
/* Cada dato es una pastilla propia sobre el papel, no una celda de tabla
   separada por filetes. Mismo lenguaje que las tarjetas: superficie, radio,
   elevación mínima. */
.mp-cintilla-nom {
  font-family: var(--ff-sans) !important;
  font-weight: 600;
  color: var(--tinta-2);
}
.mp-cintilla-val, .mp-cintilla-var {
  font-family: var(--ff-mono) !important;
  font-variant-numeric: tabular-nums lining-nums;
}
.mp-cintilla-item {
  display: flex;
  align-items: baseline;
  gap: var(--paso-2);
  padding: var(--paso-2) var(--paso-3);
  background: var(--sup-panel);
  border-radius: var(--radio-chico);
  box-shadow: var(--elev-1);
  white-space: nowrap;
  flex: 0 0 auto;
}
.mp-cintilla-nom {
  font-family: var(--ff-sans) !important;
  font-size: 11px;
  letter-spacing: -0.004em;
  text-transform: none;
  color: var(--tinta-4);
}
.mp-cintilla-val { font-size: 13px; color: var(--tinta-1); font-weight: 600; letter-spacing: -0.02em; }
.mp-cintilla-var { font-size: 12px; font-weight: 600; letter-spacing: -0.02em; }

/* Dirección de mercado — el ÚNICO uso legítimo de verde y rojo. */
.mp-alza { color: var(--alza) !important; }
.mp-baja { color: var(--baja) !important; }
.mp-plano { color: var(--tinta-3) !important; }

/* Marca de dirección en línea (sustituye flechas emoji). */
.mp-dir::before {
  font-family: var(--ff-mono);
  margin-right: 3px;
  font-weight: 600;
}
.mp-dir.mp-alza::before { content: '▲'; font-size: .72em; }
.mp-dir.mp-baja::before { content: '▼'; font-size: .72em; }

/* ───────────────── ENCABEZADO DE SECCIÓN (etiqueta + regla) ─────────────── */
/* "Sección A · desempeño ─────────────────────────────────────────────────" */
.mp-sec {
  display: flex;
  align-items: center;
  /* ENVUELVE. Sin esto, cuando las acciones de la derecha no caben junto a la
     etiqueta, .mp-sec-etq se encoge hasta 0 (tiene min-width:0) pero su TEXTO
     no se recorta, así que "PORTADA" quedaba impreso ENCIMA del botón Editar.
     Se veía al subir los tres botones de la portada de 11px a 36px de alto:
     el ancho que pedían dejó de caber a 390px. */
  flex-wrap: wrap;
  gap: var(--paso-2) var(--paso-3);
  margin-bottom: var(--paso-3);
  min-width: 0;
}

/* La etiqueta se lleva la regla consigo: es ella la que crece hasta el ancho
   disponible y dibuja la línea en su ::after. Así funciona igual suelta que
   dentro de un contenedor `flex justify-between` con una acción a la derecha,
   sin tener que editar ni un solo elemento padre en 3,400 líneas de markup. */
.mp-sec-etq {
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-etq) !important;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--tinta-3) !important;
  display: flex;
  align-items: center;
  gap: var(--paso-3);
  /* Base de 180px: por debajo de eso la etiqueta ya no cabe con su regla y
     prefiere bajar las acciones a la línea siguiente antes que estrujarse. */
  flex: 1 1 180px;
  min-width: 0;
}
.mp-sec-etq > * { flex: 0 0 auto; }
.mp-sec-etq::after {
  content: '';
  flex: 1 1 auto;
  border-top: 1px solid var(--regla);
  min-width: 12px;
}
/* El orden de sección ("SECCIÓN A ·") va en tinta de sello. */
.mp-sec-orden { color: var(--sello); white-space: nowrap; }

/* .mp-sec NO dibuja regla propia: la etiqueta ya la trae en su ::after. Si el
   contenedor también la pintara, quedaría un filete suelto DESPUÉS de la
   acción de la derecha (se veía como un guion colgando tras "Reporte PDF"). */
/* Pegado a la derecha cuando cabe; en línea propia cuando no. */
.mp-sec-fin { flex: 0 0 auto; margin-left: auto; display: flex; flex-wrap: wrap; gap: var(--paso-2); }

/* ────────────────────────── TITULARES DE NOTA ───────────────────────────── */
.mp-titular {
  font-family: var(--ff-serif) !important;
  font-weight: 700;
  color: var(--tinta-1);
  letter-spacing: -0.02em;
  line-height: 1.1;
  text-wrap: balance;
}
.mp-titular-xl { font-size: clamp(26px, 7.2vw, 42px); }
.mp-titular-l  { font-size: clamp(21px, 5.4vw, 30px); }
.mp-balazo {
  font-family: var(--ff-serif) !important;
  font-style: italic;
  font-size: 14.5px;
  line-height: 1.45;
  color: var(--tinta-2);
}
.mp-firma {
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-meta);
  letter-spacing: -0.006em;
  text-transform: none;
  color: var(--tinta-4);
}

/* ───────────────── RETÍCULA: celdas con hairline, no tarjetas ───────────── */
/* Se reescriben las superficies que el markup ya pinta con utilidades. */
.bg-surface-card,
[class*="bg-surface-card"],
.bg-zinc-900, .bg-zinc-900\/40, .bg-zinc-950, .bg-zinc-800\/70 {
  background-color: var(--sup-panel) !important;
}
/* Los paneles del markup viejo se dibujaban con `border` + esquina de 2px.
   Ahora son superficies del sistema: blanco, radio de tarjeta y elevación
   suave, igual que las tarjetas del Periódico. El filete desaparece porque
   dos señales de separación (borde Y sombra) es justo lo que satura una
   pantalla. */
main [class*="bg-surface-card"],
main .bg-surface-card {
  border-color: transparent !important;
  border-radius: var(--radio-tarjeta);
  box-shadow: var(--elev-1);
}
[class*="border-surface-border"],
.border-zinc-700, .border-zinc-800 {
  border-color: var(--regla) !important;
}

/* Celda de datos: hairline en vez de caja redondeada con sombra. */
.mp-celda {
  background: var(--sup-panel);
  border: 0;
  border-radius: var(--radio-tarjeta);
  box-shadow: var(--elev-1);
  padding: var(--paso-4);
  min-width: 0;
}
.mp-celda-plana {
  background: transparent;
  border: 0;
  border-bottom: var(--hairline) solid var(--regla);
  padding: 10px 0;
  min-width: 0;
}
/* Retícula de cifras: hairlines internas, sin cajas sueltas. */
.mp-reticula {
  display: grid;
  gap: 1px;
  border: 0;
  border-radius: var(--radio-tarjeta);
  overflow: hidden;
  background: var(--regla);
  box-shadow: var(--elev-1);
}
.mp-reticula > * {
  padding: var(--paso-3) var(--paso-4);
  background: var(--sup-panel);
  min-width: 0;
}

/* ────────────────────────────── COLOFÓN ─────────────────────────────────── */
.mp-colofon {
  border-top: 2px solid var(--tinta-1);
  margin-top: 40px;
  padding: 18px 0 calc(28px + var(--sa-bottom));
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-meta);
  line-height: 1.65;
  color: var(--tinta-3);
}
.mp-colofon strong { color: var(--tinta-2); font-weight: 600; }
.mp-colofon a { color: var(--sello); text-decoration: none; }
.mp-colofon a:hover { text-decoration: underline; }
/* Índice del colofón: enlaces en línea separados por un cuadratín. */
.mp-colofon-indice > a,
.mp-colofon-indice > button {
  display: inline !important;
  color: var(--sello);
  background: none !important;
  border: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  min-height: 0 !important;
  font: inherit !important;
  letter-spacing: inherit !important;
  text-transform: none !important;
  cursor: pointer;
  text-align: left;
}
.mp-colofon-indice > *:not(:last-child)::after {
  content: ' · ';
  color: var(--tinta-4);
}
.mp-colofon-titulo {
  font-family: var(--ff-serif) !important;
  font-size: 13px;
  font-weight: 700;
  color: var(--tinta-1);
  letter-spacing: -0.01em;
  margin-bottom: 6px;
  text-transform: none;
}

/* ─────────────────────────── ACENTO Y BOTONES ───────────────────────────── */
/* El acento ámbar cubre TODA la interacción. `accent-green` y `accent-red`
   quedan FUERA de este barrido a propósito: el tema de Tailwind ya los apunta
   al verde y rojo de mercado, y son los únicos dos colores que codifican un
   dato (dirección). Pintarlos de ámbar aquí borraría esa información. */
.text-accent-teal, .text-accent-blue, .text-accent-purple,
.text-accent-indigo, .text-accent-amber, .text-accent-orange, .text-accent-rose,
.text-amber-300, .text-amber-400, .text-amber-100, .text-sky-400, .text-cyan-400,
.text-violet-400, .text-pink-400, .text-yellow-400 {
  color: var(--sello) !important;
}
.mp-alza { color: var(--alza) !important; }
.mp-baja { color: var(--baja) !important; }

/* NO se sobreescriben aquí los fondos ni los bordes de color.
   Se intentó y salió mal dos veces:

   1) Un barrido a `[class*="bg-accent-"]` aplanaba TODO —incluidos los botones
      sólidos— a un tinte translúcido.
   2) Acotarlo con `[class*="/"]` para pillar solo las variantes con opacidad
      tampoco sirve: los selectores de atributo miran la cadena de clases
      COMPLETA, así que un botón sólido con `hover:bg-accent-amber/90` también
      contiene una barra y caía en la regla. Eso dejaba "Usar este portafolio"
      con fondo rgba(215,154,60,.12) y texto casi negro encima: se veía
      deshabilitado aunque funcionara. Además esa regla ganaba por
      especificidad (0,4,0) a la excepción `button.bg-accent-amber` (0,1,1).

   No hace falta nada de esto: el remapeo de `theme.extend.colors` ya apunta
   accent/amber/emerald/teal/sky/cyan/violet/pink al sello, y Tailwind genera
   por sí solo tanto la versión sólida como la translúcida con la opacidad
   correcta. Que el tema haga el trabajo evita la guerra de especificidad. */

/* Botón primario: sello sólido con tinta encima. */
.mp-btn, .mp-btn-primario {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--paso-2);
  font-family: var(--ff-sans);
  font-size: var(--txt-meta);
  font-weight: 600;
  letter-spacing: -0.008em;
  padding: var(--paso-3) var(--paso-5);
  min-height: 44px;
  border-radius: var(--radio);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color var(--t-rapida) var(--easing),
              border-color var(--t-rapida) var(--easing),
              color var(--t-rapida) var(--easing);
}
.mp-btn-primario {
  background: var(--sello-solido);
  color: var(--sobre-sello);
  border-color: var(--sello-solido);
}
.mp-btn-primario:hover { background: var(--sello-vivo); border-color: var(--sello-vivo); }
.mp-btn-secundario {
  background: transparent;
  color: var(--tinta-1);
  border-color: var(--regla-fuerte);
}
.mp-btn-secundario:hover { border-color: var(--tinta-3); background: var(--sup-hondo); }
/* Variante compacta para utilidades DENTRO del contenido (Editar, Perfiles,
   Reporte PDF…). 36px, no 44: el mínimo de 44 es para los controles que Apple
   revisa en el header y para las acciones principales; tres botones de 44px en
   una fila de encabezado no caben a 375px y obligan a inventar otro estilo,
   que es como nacieron las tres variantes distintas que había aquí. */
.mp-btn-chico {
  min-height: 36px;
  padding: var(--paso-2) var(--paso-3);
  font-size: var(--txt-meta);
}
.mp-btn-chico svg { width: 15px; height: 15px; }

.mp-btn-fantasma {
  background: transparent;
  color: var(--tinta-3);
  border-color: transparent;
}
.mp-btn-fantasma:hover { color: var(--tinta-1); }

/* Botones amarillos/verdes sueltos del markup viejo → sello sólido. */
button.bg-accent-green, button.bg-accent-teal, button.bg-accent-amber,
a.bg-accent-green, .bg-accent-green.text-zinc-950 {
  background-color: var(--sello-solido) !important;
  color: var(--sobre-sello) !important;
}

/* ───────────────────────── FORMULARIOS E INPUTS ─────────────────────────── */
input, select, textarea {
  font-family: var(--ff-sans) !important;
  background-color: var(--sup-panel) !important;
  border: 1px solid var(--regla) !important;
  border-radius: var(--radio) !important;
  color: var(--tinta-1) !important;
}
input[type="number"], input[inputmode="decimal"], input[inputmode="numeric"] {
  font-family: var(--ff-mono) !important;
  font-variant-numeric: tabular-nums lining-nums;
}
input:focus, select:focus, textarea:focus {
  outline: none !important;
  border-color: var(--sello) !important;
}
input::placeholder, textarea::placeholder {
  color: var(--tinta-4) !important;
  /* El campo va en VERSALITAS porque se teclea una clave de pizarra, pero el
     placeholder es una frase: en mayúsculas ocupa ~30% más y se salía del
     campo ("ESCRIBE UN TICKER (AAPL, WALM…"). La caja del texto tecleado y la
     de la pista no tienen por qué ser la misma. */
  text-transform: none;
  letter-spacing: normal;
}

/* ───────────────────────────── TABLAS ───────────────────────────────────── */
table { border-collapse: collapse; width: 100%; }
thead th {
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-etq) !important;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--tinta-3) !important;
  border-bottom: 1px solid var(--regla-fuerte) !important;
  background: transparent !important;
  text-align: left;
}
tbody td {
  border-bottom: var(--hairline) solid var(--regla) !important;
  color: var(--tinta-2);
  font-size: 12.5px;
}
tbody tr:hover td { background: var(--sup-hondo); }
tbody tr:last-child td { border-bottom: 0 !important; }
[class*="divide-surface-border"] > * + *,
[class*="divide-zinc"] > * + * { border-color: var(--regla) !important; }

/* ──────────────── MODALES, TOASTS, TOOLTIPS, ESTADOS ────────────────────── */
/* Overlays: papel de periódico sobre tinta, sin blur ni sombra. */
.mp-overlay, [id*="overlay"], [class*="backdrop"] {
  background-color: rgba(26, 26, 24, .40) !important;
}
.mp-hoja {
  background: var(--sup-panel);
  border: 0;
  border-radius: var(--radio-tarjeta);
  box-shadow: var(--elev-3);
}
.mp-hoja-cabeza {
  border-bottom: 2px solid var(--tinta-1);
  padding-bottom: 10px;
  margin-bottom: 14px;
}

/* Toast: barra de teletipo, no burbuja flotante. */
.mp-toast, #mp-toast, [id^="toast"], .toast {
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-meta) !important;
  font-weight: 500;
  background: var(--tinta-1) !important;
  color: var(--sup-panel) !important;
  border: 0 !important;
  border-radius: var(--radio) !important;
  box-shadow: var(--elev-3) !important;
  letter-spacing: -0.008em;
}

/* Tooltip del atributo data-tip (definido en index.html). */
[data-tip]:hover::after,
[data-tooltip]:hover::after {
  font-family: var(--ff-sans) !important;
  font-size: 12px !important;
  background: var(--tinta-1) !important;
  border: 0 !important;
  border-radius: var(--radio-chico) !important;
  box-shadow: var(--elev-2) !important;
  color: var(--sup-panel) !important;
  letter-spacing: -0.005em;
}

/* Estado vacío y de error: nota al pie, no tarjeta con ilustración. */
.mp-vacio, .mp-error {
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-cuerpo);
  line-height: 1.5;
  padding: var(--paso-5);
  border: 0;
  border-radius: var(--radio-tarjeta);
  background: var(--sup-panel);
  box-shadow: var(--elev-1);
  color: var(--tinta-3);
  text-align: center;
}
.mp-error { color: var(--baja); }

/* Skeleton: trama de papel, sin pulso de color frío. */
.skeleton {
  background-color: var(--sup-hondo) !important;
  border-radius: var(--radio-tarjeta) !important;
  animation: mp-latido 1.6s ease-in-out infinite !important;
}
@keyframes mp-latido {
  0%, 100% { background-color: var(--sup-hondo); }
  50%      { background-color: var(--regla-suave); }
}

/* ─────────────────────── ICONOGRAFÍA DE LÍNEAS ─────────────────────────── */
/* Marcas gráficas propias que sustituyen a los emoji del markup. */
.mp-marca {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.05em;
  height: 1.05em;
  flex: 0 0 auto;
  vertical-align: -0.14em;
  color: currentColor;
}
.mp-marca svg { width: 100%; height: 100%; stroke-width: 1.6; }

/* Viñeta de lista: cuadratín tipográfico, no bolita de color. */
.mp-vineta::before {
  content: '';
  display: inline-block;
  width: 5px; height: 5px;
  margin-right: 8px;
  vertical-align: 0.12em;
  background: var(--sello);
}
/* Punto de estado (el único círculo permitido). */
.mp-punto {
  display: inline-block;
  width: 5px; height: 5px;
  border-radius: 999px;
  background: var(--tinta-3);
  flex: 0 0 auto;
}
.mp-punto.mp-vivo { background: var(--sello); }

/* Racha: sello numérico en mono, sin fuego. */
.mp-racha {
  font-family: var(--ff-mono) !important;
  font-size: 10.5px;
  letter-spacing: 0.05em;
  color: var(--sello);
  border: 1px solid var(--sello-tenue);
  border-radius: var(--radio);
  padding: 3px 7px;
  white-space: nowrap;
}

/* ────────────────── NAV Y CABECERA (sin romper el sticky) ───────────────── */
#mp-topbar { background: var(--sup) !important; }
#mp-topbar header { border-bottom: 0 !important; background: transparent !important; }
/* La navegación principal usaba versalitas monoespaciadas con un filete de
   2px debajo: dos estilos de pestaña apilados —éste y el selector de mazos en
   píldoras— era el choque más visible de toda la pantalla. Ahora los dos
   hablan el mismo idioma. */
#mp-topbar nav {
  background: transparent !important;
  border-bottom: 0 !important;
  padding-bottom: var(--paso-2);
}
#mp-topbar .nav-tab:not(#btn-premium-header):not(#btn-cuenta-header) {
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-meta) !important;
  font-weight: 600;
  letter-spacing: -0.008em;
  text-transform: none;
  color: var(--tinta-3);
  border-radius: 999px;
  padding: var(--paso-2) var(--paso-3) !important;
  min-height: 36px;
  transition: background-color var(--t-rapida) var(--easing),
              color var(--t-rapida) var(--easing);
}
#mp-topbar .nav-tab:not(#btn-premium-header):not(#btn-cuenta-header):hover { color: var(--tinta-1); }
/* El activo se marca con relleno, no con un filete que a esta escala se
   pierde. El .nav-indicator del markup se apaga: sobra. */
#mp-topbar .nav-tab.activa,
#mp-topbar .nav-tab[aria-current="page"] {
  background: var(--tinta-1);
  color: var(--sup-panel) !important;
}
#mp-topbar .nav-indicator { display: none !important; }

/* Botones permanentes del header (Apple 2.1(b) y 5.1.1(v)): siempre visibles,
   siempre táctiles. El área mínima de 44px se garantiza aquí. */
#btn-premium-header, #btn-cuenta-header {
  /* 44px SIEMPRE, no 32. En vertical la regla móvil de ux_helpers.js ya los
     subía a 44, pero en horizontal (932x430) esa hoja no aplica y quedaban en
     32px: por debajo del mínimo táctil que pide Apple justo en los dos botones
     que el revisor tiene que poder tocar. */
  min-height: 44px;
  /* Eran 9.5px en mono y VERSALITAS: el tamaño de una nota al pie para los dos
     controles más importantes de la pantalla. Un botón se lee como palabra, no
     como dato; va en sans, a 13px y en caja normal. */
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-meta) !important;
  font-weight: 600;
  letter-spacing: -0.006em;
  text-transform: none;
  border-radius: var(--radio) !important;
  padding-left: var(--paso-3) !important;
  padding-right: var(--paso-3) !important;
  gap: var(--paso-2) !important;
}
/* En iPhone vertical el ícono cede el espacio: lo que el revisor de Apple
   tiene que poder leer y tocar es el TEXTO de ambos botones. */
@media (max-width: 479px) {
  #btn-premium-header svg, #btn-cuenta-header svg { display: none; }
  #btn-premium-header, #btn-cuenta-header { font-size: var(--txt-meta) !important; }
}
@media (min-width: 640px) {
  /* Antes aquí se reducía a 10.5px con letter-spacing de versalita: era el
     remate del tratamiento monoespaciado que ya no existe. En pantalla ancha
     hay sitio de sobra, así que los botones se quedan en la escala normal. */
  #btn-premium-header, #btn-cuenta-header {
    padding-left: var(--paso-4) !important;
    padding-right: var(--paso-4) !important;
  }
}
#btn-premium-header {
  background: var(--sello-solido) !important;
  color: var(--sobre-sello) !important;
  border: 1px solid var(--sello-solido) !important;
}
#btn-premium-header:hover { background: var(--sello-vivo) !important; }
#btn-cuenta-header {
  background: var(--sup-panel) !important;
  color: var(--tinta-1) !important;
  border: 1px solid var(--regla-fuerte) !important;
}
#btn-cuenta-header:hover { border-color: var(--tinta-3) !important; }

/* ───────────────────── GUARDAS ESTRUCTURALES DE LAYOUT ──────────────────── */
/* 1) `.nav-tab` es además el hook de ruteo de app.js, así que también lo
      llevan tarjetas de contenido dentro de <main>. La regla móvil de
      ux_helpers.js les aplicaba `white-space: nowrap`, y sus párrafos no
      podían romper línea: hasta 371px de scroll horizontal en iPhone.
      Aquí se devuelve el comportamiento normal a todo .nav-tab fuera de la
      barra superior. */
main .nav-tab,
main .quick-link {
  white-space: normal !important;
  min-width: 0 !important;
  font-size: inherit !important;
  letter-spacing: normal !important;
  text-transform: none !important;
  padding: revert !important;
}

/* 2) Los hijos de grid heredan min-width:auto y su min-content empujaba la
      retícula más allá del viewport (vista de transacciones). */
main .grid > * { min-width: 0; }

/* 3) Red de seguridad: la página nunca hace scroll horizontal, pase lo que
      pase con lo que inyecte el JS. `clip` no crea contexto de scroll, así
      que no rompe el `position: sticky` de #mp-topbar (que vive fuera de main). */
main { overflow-x: clip; }

/* Respeto de safe areas en horizontal (notch a los lados). */
body {
  padding-left: var(--sa-left);
  padding-right: var(--sa-right);
}

/* ───────────────── MODO NATIVO (la clase la pone Swift) ─────────────────── */
/* MPBridgeViewController añade .mp-nativo al <html> al arrancar. Cuando hay
   barra de pestañas nativa abajo, la sub-nav web de arriba sobra: tener las dos
   deja la misma navegación duplicada y es justo lo que hace que una app se
   sienta "un sitio web dentro de una caja". El masthead se queda —es la
   identidad— pero la navegación baja al pulgar. */
html.mp-nativo #mp-topbar nav { display: none; }

/* Hueco al pie para que la barra nativa no tape el final del contenido.
   El WebView además recibe contentInset desde Swift; esto cubre los elementos
   fijos que no participan del scroll. */
html.mp-nativo body { padding-bottom: 0; }
html.mp-nativo .mp-colofon { padding-bottom: calc(96px + var(--sa-bottom)); }

/* ──────────────────── MICRO-INTERACCIONES SOBRIAS ───────────────────────── */
/* Sin rebotes ni escalados llamativos: solo cambio de tinta. */
button:active, a:active, [role="button"]:active, .nav-tab:active {
  transform: none !important;
  opacity: .78;
  transition: opacity var(--t-rapida) var(--easing) !important;
}
.fade-up { animation-duration: var(--t-media) !important; }
.corr-cell { transition: none !important; }
.corr-cell:hover { transform: none !important; outline: 1px solid var(--tinta-1); }
[class*="animate-pulse"] { animation: none !important; }

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

/* ──────────────────────── BARRA DE DESPLAZAMIENTO ───────────────────────── */
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: var(--sup-hondo); }
::-webkit-scrollbar-thumb { background: var(--regla); border-radius: 0; }
::-webkit-scrollbar-thumb:hover { background: var(--regla-fuerte); }


/* ── CABECERA DE LA VISTA ─────────────────────────────────────────────────
   Título + fecha + refresco, y nada más. Todo el aire vive aquí, no repartido
   en cinco párrafos. */
.mp-cabecera {
  padding: var(--paso-5) var(--paso-5) var(--paso-2);
}
.mp-cabecera-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--paso-4);
}
.mp-titulo-vista {
  font-family: var(--ff-serif) !important;
  font-size: var(--txt-vista);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.028em;
  color: var(--tinta-1);
  margin: 0;
  min-width: 0;
}
.mp-cabecera-meta {
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-etq);
  letter-spacing: .04em;
  color: var(--tinta-4);
  margin: var(--paso-2) 0 0;
}
/* Botón de icono: área táctil de 44px con la marca gráfica al centro. */
.mp-btn-icono {
  flex: 0 0 auto;
  width: 44px; height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  border: 1px solid var(--regla);
  background: var(--sup-panel);
  color: var(--tinta-2);
  cursor: pointer;
  transition: background-color var(--t-rapida) var(--easing),
              border-color var(--t-rapida) var(--easing);
}
.mp-btn-icono svg { width: 19px; height: 19px; }
.mp-btn-icono:hover { background: var(--sup-alto); border-color: var(--regla-fuerte); }
.mp-btn-icono:focus-visible { outline: 2px solid var(--sello); outline-offset: 2px; }
.mp-btn-icono.girando svg { animation: mp-giro 700ms linear; }
@keyframes mp-giro { to { transform: rotate(360deg); } }

/* ══════════════════════════════════════════════════════════════════════════
   PERIÓDICO · MAZOS DE TARJETAS (estilo Apple Wallet)
   ══════════════════════════════════════════════════════════════════════════
   Cinco mazos en una pista horizontal con scroll-snap. Cada mazo es una PILA
   vertical de tarjetas solapadas: de cada una asoma solo su franja superior
   (--tj-paso) y la de más abajo se ve completa (--tj-cara).

   CÓMO SE ANIMA (y por qué así)
   -----------------------------
   Las tarjetas van en `position:absolute` y TODO su movimiento es
   `transform: translateY()` — nunca `top`, `margin` ni `height` animada — para
   que la compositora de WKWebView las mueva sin relayout (60 fps en iPhone).
   Las posiciones las calcula el JS (`_posicionar`) y el alto del contenedor se
   fija en píxeles para que la página siga teniendo scroll normal.

   El único cambio que NO es transform es el `height: var(--tj-cara)` → `auto`
   de la tarjeta que se abre. Es instantáneo y no se transiciona, y queda
   TAPADO por la tarjeta siguiente: al estar más arriba en el z-index, la de
   abajo cubre a la que crece y va destapándola conforme se desliza. Es el
   mismo truco de Wallet, y por eso el orden de apilado importa.
   ========================================================================== */

.mp-mazos {
  /* La franja está CALCULADA para que quepa exactamente lo que enseña, no
     elegida a ojo: 16 (padding) + 15 (rótulo de 11px con su interlínea) +
     8 (aire) + 48 (dos líneas de titular a 20px/1.2) + 9 (respiro) = 96.
     Estaba en 94 con un comentario que decía contar 13px de rótulo; medido,
     el rótulo ocupa 15 y el respiro real eran 5.5px, no 9. Si se cambia
     --txt-titular hay que rehacer esta cuenta, o la segunda línea vuelve a
     quedar rebanada por la tarjeta de encima. */
  --tj-paso: 96px;   /* franja visible de cada tarjeta apilada */
  --tj-cara: 164px;  /* alto de la cara completa (la de más abajo) */
  --tj-mini: 30px;   /* franja de las que quedan ARRIBA de la abierta */
  position: relative;
  padding: 0 var(--paso-5) var(--paso-7);
}

/* ── Pista horizontal ──────────────────────────────────────────────────── */
.mp-mazos-pista {
  display: flex;
  /* Sin transición: su alto lo fija el JS y tiene que ser medible al instante. */
  transition: none !important;
  /* flex-start y NO stretch: con `stretch` cada pane crecía hasta el alto de la
     pista, y como el alto de la pista se calcula a partir del pane más alto,
     scrollHeight se quedaba pegado al máximo histórico y la sección nunca
     volvía a encoger al cerrar una tarjeta. */
  align-items: flex-start;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  /* Que el gesto lateral no encadene con el swipe-back de iOS ni con el
     rebote de la página. */
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* touch-action se deja en `auto`: el navegador decide por dirección
     dominante, que es justo lo que queremos (lateral = mazo, vertical =
     página). Fijarlo a pan-x mataba el scroll vertical dentro de la pista. */
}
.mp-mazos-pista::-webkit-scrollbar { display: none; }

.mp-mazo-pane {
  flex: 0 0 100%;
  scroll-snap-align: start;
  min-width: 0;
  /* El aire de arriba es para la sombra de apoyo de la primera tarjeta: la
     pista recorta en vertical (overflow-y:hidden) y sin este margen la sombra
     salía cortada a cuchillo. _reajustarPista() en app.js SUMA estos 10px al
     alto que calcula; si se cambia aquí, hay que cambiarlo allá o la última
     tarjeta se queda sin sitio. */
  padding: 10px 2px 0;
}

/* Rótulo del mazo */
/* El rótulo del mazo dentro del panel se oculta: la pestaña activa del
   selector ya dice en qué mazo estás, y repetirlo con un número delante
   ("1 NOTICIAS") era ruido puro. Se conserva en el DOM para los lectores de
   pantalla, que sí necesitan el encabezado de la región. */
.mp-mazo-titulo {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  font-family: var(--ff-mono) !important;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--tinta-3);
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
}
.mp-mazo-titulo::after {
  content: '';
  flex: 1 1 auto;
  border-top: 1px solid var(--regla);
}
.mp-mazo-titulo .mp-mazo-n { color: var(--sello); }

/* ── La pila ───────────────────────────────────────────────────────────── */
.mp-mazo {
  position: relative;
  /* El alto lo fija el JS. El mínimo evita que el mazo colapse a 0 mientras
     carga y deje la sección "saltando" al llegar los datos. */
  min-height: 180px;
  /* El alto NO se transiciona: es solo la extensión de scroll de la pila, no
     algo que se vea moverse (lo que se ve moverse son los translateY de las
     tarjetas). Animarlo, además, hacía que medirlo justo después devolviera
     un valor a medio camino y la pista quedara corta. */
  transition: none !important;
}

/* ── Tarjeta ───────────────────────────────────────────────────────────── */
.mp-tarjeta {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: var(--tj-cara);
  overflow: hidden;
  border-radius: var(--radio-tarjeta);
  /* Color de categoría: fondo cromático y tinta del MISMO family. Los tres
     valores los inyecta el JS desde MP_CATEGORIAS.
     Encima del color va un barrido de luz que baja del canto superior: es lo
     que hace que la franja se lea como una superficie física y no como una
     banda de color plano. */
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, .55) 0%,
      rgba(255, 255, 255, .16) 34%,
      rgba(255, 255, 255, 0) 62%),
    var(--cat-sup, var(--sup-panel));
  color: var(--cat-tinta, var(--tinta-1));
  border: 0;   /* el canto lo dibujan las sombras internas, no un filete */

  /* ── EL APILADO ────────────────────────────────────────────────────────
     La sombra principal va HACIA ARRIBA (offset-y negativo). No es un
     capricho: en esta pila cada tarjeta se monta sobre la de ENCIMA, así que
     la sombra que separa dos tarjetas tiene que caer hacia arriba, sobre la
     anterior. Con la sombra hacia abajo (lo normal) el apilado se veía plano
     porque la sombra caía sobre la tarjeta que ya estaba tapada.
       1) luz de canto superior  → el borde de arriba brilla, como en Wallet
       2) rim del color          → define la silueta sin filete duro
       3) sombra corta arriba    → contacto, pega la tarjeta a la de encima
       4) sombra larga arriba    → separación, da la profundidad
       5) sombra abajo           → peso general del mazo sobre el papel      */
  /* NINGUNA sombra se sale por los costados. La regla es geométrica: el
     alcance lateral de un box-shadow es blur/2 + spread, así que con
     spread <= -blur/2 el alcance es cero o negativo y la sombra solo existe
     donde la empuja el offset vertical.
     Esto NO es un detalle de gusto. La pista de mazos es un scrollport con
     overflow-y:hidden y los paneles solo tienen 2px de aire lateral: la sombra
     anterior (blur 16, spread -4) alcanzaba 4px por lado, se topaba con el
     recorte y se veía como un filete gris de canto RECTO pegado a la tarjeta
     —un doble contorno—, y las de dos tarjetas contiguas se sumaban formando
     una costilla vertical más oscura cada 94px. Eso es lo que se veía como
     "sombras raras alrededor".
     Ya no hay luz de canto en inset: a 16px de radio esa línea recta asomaba
     por fuera de la curva como dos ganchitos blancos en las esquinas. El
     brillo del canto lo da el degradado del fondo, que sí sigue la curva. */
  box-shadow:
    inset 0 0 0 1px var(--cat-borde, var(--regla)),
    0 -1px 2px -1px rgba(20, 22, 27, .26),
    0 -8px 16px -8px rgba(20, 22, 27, .42);
  will-change: transform;
  /* !important porque la regla móvil de ux_helpers.js baja la duración de
     todo a 0.18s; aquí el resorte necesita sus 220 ms completos. */
  transition: transform 220ms var(--resorte) !important;
  /* SIN `contain: paint`: recortaría el reparto de sombras de arriba, que es
     justo lo que da el efecto de tarjetas encimadas. */
}
/* La PRIMERA tarjeta no tiene nada encima, así que no puede proyectar sombra
   hacia arriba: ahí la sombra ascendente no separaba de nada y solo servía
   para chocar contra el recorte de la pista y dibujar dos escuadras grises en
   las esquinas de arriba. Es lo que el usuario ve como "se corta raro".
   La de arriba lleva sombra de apoyo, como una tarjeta suelta sobre el papel. */
.mp-mazo .mp-tarjeta:first-of-type {
  box-shadow:
    inset 0 0 0 1px var(--cat-borde, var(--regla)),
    0 1px 2px rgba(20, 22, 27, .08),
    0 8px 16px -12px rgba(20, 22, 27, .30);
}
.mp-tarjeta.abierta,
.mp-mazo .mp-tarjeta.abierta:first-of-type {
  height: auto;
  /* Abierta, la tarjeta se despega del mazo. Misma regla de contención: el
     spread compensa el desenfoque para que no se derrame a los costados. */
  box-shadow:
    inset 0 0 0 1px var(--cat-borde, var(--regla)),
    0 -2px 6px -4px rgba(20, 22, 27, .22),
    0 16px 32px -20px rgba(20, 22, 27, .45),
    0 4px 12px -10px rgba(20, 22, 27, .28);
}
/* Mientras se arrastra hacia abajo para cerrar, manda el dedo: sin transición. */
.mp-tarjeta.arrastrando { transition: none !important; }
/* Colocación inicial (y recolocación por resize/rotación): posición aplicada de
   golpe. Va como clase en el ancestro —especificidad (0,2,0)— porque un
   `style.transition = 'none'` en línea NO le gana a las reglas !important que
   inyecta ux_helpers.js en móvil. */
.mp-mazo.sin-animacion .mp-tarjeta { transition: none !important; }

/* Cara: lo único que se ve cuando está apilada. */
.mp-tarjeta-cara {
  /* Columna flex de alto fijo (--tj-cara) con la meta empujada al fondo por
     `margin-top:auto`. Así la línea de metadatos SIEMPRE cae por debajo de la
     franja visible (--tj-paso) y nunca queda cortada a la mitad por la tarjeta
     de encima, sin depender de cuántas líneas ocupe el titular. */
  display: flex;
  flex-direction: column;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  padding: var(--paso-4) var(--paso-4) var(--paso-3);
  cursor: pointer;
  color: inherit;
  font: inherit;
  /* Alto FIJO, no min-height: la regla móvil de ux_helpers.js pone
     `min-height: 44px !important` a todos los botones y ganaba, dejando la cara
     en ~105 px. Con el alto fijo el `margin-top:auto` de la meta la manda
     siempre al fondo de la cara, es decir por debajo de la franja visible. */
  height: var(--tj-cara) !important;
  box-sizing: border-box;
}
.mp-tarjeta-cara:focus-visible {
  outline: 2px solid var(--cat-tinta, var(--tinta-1));
  outline-offset: -3px;
  border-radius: 14px;
}

.mp-tarjeta-etq {
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-etq);
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  /* Un color REAL en vez de opacity: ver la nota de MP_CATEGORIAS. Con
     opacity:.62 este rótulo daba 2.9:1 contra el fondo de su categoría. */
  color: var(--cat-suave, var(--tinta-3));
  display: block;
  /* Una sola línea SIEMPRE. Si el rótulo se parte en dos —pasa con fuentes
     largas como "Investor's Business Daily"— empuja el titular fuera de la
     franja de 94px y la tarjeta de abajo lo rebana. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: var(--paso-2);
}
.mp-tarjeta-titular {
  font-family: var(--ff-serif) !important;
  font-weight: 700;
  font-size: var(--txt-titular);
  line-height: 1.2;
  letter-spacing: -0.02em;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Abierta, el titular ya no compite con nada: se muestra completo. */
.mp-tarjeta.abierta .mp-tarjeta-titular { -webkit-line-clamp: 4; }
/* En los mazos 2-5 la franja lleva nombre a la izquierda y variación a la
   derecha, siempre en monoespaciada tabular. */
.mp-tarjeta-fila {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.mp-tarjeta-nom {
  font-family: var(--ff-serif) !important;
  /* El MISMO tamaño que .mp-tarjeta-titular: ocupan el mismo slot de la cara
     y antes el texto crecía 2px al deslizar de mazo, sin motivo. */
  font-weight: 700;
  font-size: var(--txt-titular);
  line-height: 1.2;
  letter-spacing: -0.02em;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mp-tarjeta-var {
  font-family: var(--ff-mono) !important;
  font-variant-numeric: tabular-nums lining-nums;
  font-size: var(--txt-titular);
  font-weight: 600;
  letter-spacing: -0.03em;
  flex: 0 0 auto;
}
.mp-tarjeta-meta {
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-etq);
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--cat-suave, var(--tinta-3));  /* color real, no opacity */
  margin-top: auto;      /* al fondo de la cara: siempre bajo la franja */
  padding-top: var(--paso-2);
  display: block;
}

/* ── Detalle (se revela al expandir) ───────────────────────────────────── */
.mp-tarjeta-detalle {
  padding: 0 var(--paso-4) var(--paso-5);
  opacity: 0;
  transition: opacity 200ms var(--easing);
}
.mp-tarjeta.abierta .mp-tarjeta-detalle { opacity: 1; }
.mp-tarjeta-detalle hr {
  border: 0;
  border-top: 1px solid currentColor;
  opacity: .18;
  margin: 0 0 12px;
}
.mp-tarjeta-resumen {
  font-family: var(--ff-serif) !important;
  font-size: var(--txt-cuerpo);
  line-height: 1.52;
  margin: 0 0 var(--paso-4);
}
.mp-tarjeta-metricas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  gap: 1px;
  margin: 0 0 var(--paso-4);
  background: currentColor;      /* hace de hairline entre celdas */
  border: 1px solid currentColor;
  border-radius: 3px;
  overflow: hidden;
}
.mp-tarjeta-metricas > div {
  background: var(--cat-sup, var(--sup-panel));
  padding: var(--paso-3) var(--paso-3);
  min-width: 0;
}
.mp-tarjeta-metricas dt {
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-etq);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--cat-suave, var(--tinta-3));
}
.mp-tarjeta-metricas dd {
  font-family: var(--ff-mono) !important;
  font-variant-numeric: tabular-nums lining-nums;
  font-size: var(--txt-titular);
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: var(--paso-1) 0 0;
}
/* El contenedor de la gráfica tiene alto DEFINIDO: Chart.js con
   maintainAspectRatio:false necesita que el padre mida algo para dibujar en el
   primer frame. Sin esto la gráfica salía en blanco hasta hacer scroll o
   resize — el bug que ya se arregló una vez y no se vuelve a introducir. */
.mp-tarjeta-grafica {
  position: relative;
  height: 164px;
  margin: 0 0 var(--paso-4);
}
.mp-tarjeta-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--paso-2);
  margin: 0 0 var(--paso-4);
}
.mp-chip-ticker {
  font-family: var(--ff-mono) !important;
  font-size: var(--txt-meta);
  font-weight: 600;
  letter-spacing: -0.005em;
  padding: var(--paso-2) var(--paso-3);
  min-height: 36px;
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  border: 1px solid currentColor;
  background: transparent;
  color: inherit;
  cursor: pointer;
}
.mp-chip-ticker:hover { background: rgba(26, 26, 24, .07); }
.mp-chip-ticker:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

/* Acción principal: BOTÓN, no un enlace de texto. */
.mp-tarjeta-accion {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: 100%;
  min-height: 48px;
  padding: var(--paso-3) var(--paso-4);
  border-radius: 10px;
  border: 1px solid currentColor;
  background: currentColor;
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-cuerpo);
  font-weight: 600;
  cursor: pointer;
}
/* El texto va del color del FONDO de la tarjeta: sobre el botón sólido (que
   es del color de la tinta de categoría) eso da el contraste invertido. */
.mp-tarjeta-accion > span { color: var(--cat-sup, var(--sup-panel)); }
.mp-tarjeta-accion:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

.mp-tarjeta-cerrar {
  position: absolute;
  top: 8px; right: 8px;
  width: 32px; height: 32px;
  display: none;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  border: 1px solid currentColor;
  background: transparent;
  color: inherit;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  z-index: 3;
}
.mp-tarjeta.abierta .mp-tarjeta-cerrar { display: inline-flex; }
/* Con el botón de cerrar visible, la cara le cede el hueco: si no, el titular
   de dos líneas se metía debajo del círculo. */
.mp-tarjeta.abierta .mp-tarjeta-cara { padding-right: 52px; }

/* Asa de arrastre: pista visual de que se cierra jalando hacia abajo. */
.mp-tarjeta-asa {
  display: none;
  width: 34px; height: 4px;
  border-radius: 999px;
  background: currentColor;
  opacity: .28;
  margin: 8px auto 2px;
}
.mp-tarjeta.abierta .mp-tarjeta-asa { display: block; }

/* ── Selector de mazo ──────────────────────────────────────────────────────
   Control segmentado, no cinco rótulos con un filete de 2px encima. El
   segmento activo se marca con RELLENO: es lo único que se lee de un vistazo
   a la distancia a la que se mira un teléfono. La barra entera se queda
   pegada bajo #mp-topbar mientras se recorre la pila, así siempre se sabe en
   qué mazo estás y se puede saltar sin volver arriba. El desplazamiento lo
   publica app.js en --mp-topbar-h (el alto de la barra cambia con el banner
   de demo y con el modo nativo sin sub-nav). */
.mp-mazos-ind {
  position: sticky;
  top: var(--mp-topbar-h, 0px);
  z-index: 20;
  display: flex;
  gap: var(--paso-1);
  padding: var(--paso-3) 0 var(--paso-3);
  margin: 0;
  background: var(--sup);
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.mp-mazos-ind::-webkit-scrollbar { display: none; }
.mp-mazos-ind button {
  flex: 1 1 0;
  min-width: max-content;
  white-space: nowrap;
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-meta);
  font-weight: 600;
  letter-spacing: -0.006em;
  text-transform: none;
  color: var(--tinta-3);
  background: transparent;
  border: 0;
  border-radius: 999px;
  padding: 0 var(--paso-3);
  min-height: 36px;
  cursor: pointer;
  transition: background-color var(--t-rapida) var(--easing),
              color var(--t-rapida) var(--easing);
}
.mp-mazos-ind button:hover { color: var(--tinta-1); }
.mp-mazos-ind button[aria-selected="true"] {
  color: var(--sobre-sello);
  background: var(--tinta-1);
}
.mp-mazos-ind button:focus-visible { outline: 2px solid var(--sello); outline-offset: 2px; }

/* ── Leyenda de categorías ────────────────────────────────────────────────
   Nota de pie bajo la pila. Cada tarjeta ya lleva escrito su rótulo de
   categoría, así que esto solo confirma el código de color; no merece estar
   en la primera pantalla. */
.mp-leyenda {
  display: flex;
  flex-wrap: wrap;
  gap: var(--paso-1) var(--paso-4);
  margin: var(--paso-5) 0 0;
  padding-top: var(--paso-3);
  border-top: var(--hairline) solid var(--regla);
  font-family: var(--ff-sans) !important;
  font-size: var(--txt-etq);
  letter-spacing: .02em;
  color: var(--tinta-4);
}
.mp-leyenda span { display: inline-flex; align-items: center; gap: var(--paso-2); }
.mp-leyenda i {
  width: 10px; height: 10px;
  border-radius: 3px;
  display: inline-block;
  box-shadow: inset 0 0 0 1px rgba(26, 26, 24, .12);
}

/* ── Horizontal y tabletas: dos mazos a la vez ─────────────────────────── */
@media (min-width: 820px) {
  .mp-mazo-pane { flex-basis: 50%; padding: 10px 10px 0; }
  .mp-mazos { --tj-cara: 140px; }
}

/* ══════════════ ESCRITORIO: la pila se deshace en lista ══════════════════
   El mazo apilado resuelve un problema del móvil —enseñar diez cosas en una
   columna de 390px sin obligar a recorrer— que en un monitor no existe: hay
   tres columnas a la vista y espacio vertical de sobra. Mantener el apilado
   ahí producía tres torres de franjas encimadas, cada una enseñando media
   tarjeta, que se leen como una lista rota.
   Arriba de 1024px las tarjetas vuelven al flujo normal. _posicionar() en
   app.js detecta el mismo umbral y se aparta, borrando los transform y el
   alto en línea que pone el modo apilado. Si se cambia este 1024, hay que
   cambiar _modoLista() también. */
@media (min-width: 1024px) {
  /* La pista deja de ser carrusel: no hay nada que deslizar cuando cabe todo.
     Los mazos pasan a ser secciones de ancho completo, una debajo de otra, y
     sus tarjetas se reparten en una rejilla que se adapta al ancho. Probé
     antes dejarlos como cinco columnas y a 1440px salían de 246px: demasiado
     estrecho para un titular de dos líneas, que es justo lo que hay que poder
     leer de un vistazo. */
  .mp-mazos-pista {
    display: block;
    overflow: visible;
    scroll-snap-type: none;
    height: auto !important;   /* el JS lo fija para el modo carrusel */
  }
  .mp-mazo-pane {
    width: 100%;
    scroll-snap-align: none;
    padding: 0;
    margin-bottom: var(--paso-7);
  }
  .mp-mazo-pane:last-child { margin-bottom: 0; }
  .mp-mazo {
    height: auto !important;   /* el alto lo pone el contenido */
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--paso-4);
    align-items: start;
  }
  /* La abierta se lleva toda la fila para que quepa su gráfica sin estrujar. */
  .mp-tarjeta.abierta { grid-column: 1 / -1; }

  .mp-tarjeta {
    position: static;
    height: auto;
    transform: none !important;
    margin-bottom: 0;          /* el hueco lo pone el gap de la rejilla */
    /* Sin apilado no hay costura que separar: la sombra deja de apuntar hacia
       arriba y pasa a ser la de una tarjeta apoyada en el papel. */
    box-shadow:
      inset 0 0 0 1px var(--cat-borde, var(--regla)),
      0 1px 2px rgba(20, 22, 27, .06),
      0 10px 20px -14px rgba(20, 22, 27, .28);
  }
  .mp-mazo .mp-tarjeta:first-of-type { box-shadow: inherit; }
  .mp-tarjeta:hover {
    box-shadow:
      inset 0 0 0 1px var(--cat-borde, var(--regla)),
      0 2px 4px rgba(20, 22, 27, .07),
      0 14px 28px -14px rgba(20, 22, 27, .34);
  }
  /* La cara ya no se recorta a una franja: se ve entera. */
  .mp-tarjeta-cara { height: auto !important; min-height: 116px; }
  /* Y el detalle se colapsa DE VERDAD mientras está cerrado. En el modo
     apilado bastaba con opacity:0 porque la tarjeta tenía alto fijo y lo
     recortaba; aquí el alto lo pone el contenido, así que un detalle invisible
     pero presente hinchaba cada tarjeta con cientos de píxeles vacíos. */
  .mp-tarjeta:not(.abierta) .mp-tarjeta-detalle { display: none; }

  /* El rótulo del mazo SÍ se enseña: es la única forma de saber qué columna es
     cuando hay tres a la vista. En móvil lo dice la píldora activa. */
  /* El título y el selector comparten la línea de la sección. Son HERMANOS
     dentro del pane, así que la rejilla va en el pane: poner flex en el título
     no los junta, solo reparte sus hijos. */
  .mp-mazo-pane:has(.mp-periodos) {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: end;
    column-gap: var(--paso-4);
  }
  .mp-mazo-pane:has(.mp-periodos) > .mp-mazo,
  .mp-mazo-pane:has(.mp-periodos) > .mp-vacio,
  .mp-mazo-pane:has(.mp-periodos) > p { grid-column: 1 / -1; }
  .mp-mazo-pane:has(.mp-periodos) > .mp-periodos { margin-bottom: var(--paso-4); }
  .mp-mazo-titulo {
    position: static;
    width: auto; height: auto;
    clip-path: none;
    overflow: visible;
    font-family: var(--ff-serif) !important;
    font-size: var(--txt-seccion);
    font-weight: 700;
    letter-spacing: -0.02em;
    text-transform: none;
    color: var(--tinta-1);
    margin: 0 0 var(--paso-4);
    padding-bottom: var(--paso-3);
    border-bottom: var(--hairline) solid var(--regla);
  }
  /* Las píldoras y el desvanecido de los bordes son de la vista deslizable. */
  .mp-mazos-ind { display: none; }
  .mp-mazos-pista[data-borde] {
    -webkit-mask-image: none !important;
            mask-image: none !important;
  }
}

@media (min-width: 1180px) {
  .mp-mazo { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
}

/* Sin animación cuando el usuario la desactivó (además del barrido global). */
@media (prefers-reduced-motion: reduce) {
  .mp-tarjeta, .mp-mazo, .mp-tarjeta-detalle { transition: none !important; }
  .mp-mazos-pista { scroll-behavior: auto; }
}
