/* ════════════════════════════════════════════════════════════════
   APEX — Navegación adaptable + hogares Start / Performance Lab
   Fase 6.A. Se encola globalmente (depende de apex-tokens.css).
   Brand Kit v2: Lima #C8FF00 sobre Dark Teal, isotipo, SVG monocromos,
   radios 3/6/12, sin emojis, tuteo neutro.

   ALCANCE / NO ROMPER:
   - En páginas internas (dashboard, cursos…) la barra .apex-mob-nav YA se
     estila en apex-shell.css. Aquí NO se redefine su base: solo se añade el
     switch de modo, la hoja "Próximamente" y el botón de menú del topbar.
   - Las páginas-app (body.apex-app = Start / Lab) NO cargan apex-shell.css,
     así que aquí se define su layout completo, todo scoped a body.apex-app.
   ════════════════════════════════════════════════════════════════ */

:root {
  --apex-pos: #6ee7a0;
  --apex-neg: #ff7a7a;
  --apex-nav-h: 60px;
  /* Alto de la tira de fichas cuando está presente. 0 por defecto: las
     pantallas sin fichas (la pestaña "Yo", la vitrina del Lab) no reservan
     nada. Lo enciende la clase `apex-has-subnav` que pone apex-niveles.php.
     Un solo número gobierna TRES cosas —el hueco al pie del contenido, dónde
     empieza la tira, y cuánto suben el FAB y el switch de zona— para que no
     queden tres constantes distintas que alguien tenga que sincronizar a mano. */
  --apex-subnav-h: 0px;
}
body.apex-has-subnav { --apex-subnav-h: 48px; }

/* ════════════════════════════════════════════════════════════════
   1 · SELLO "PRÓXIMAMENTE" (inline, reutilizable)
   ════════════════════════════════════════════════════════════════ */
.apex-soon-tag {
  display: inline-flex; flex-direction: column; align-items: flex-start;
  font-family: var(--font-mono); font-size: 9px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  padding: 3px 8px; border-radius: var(--radius);
  background: var(--accent-bg); color: var(--accent);
  border: 1px solid var(--accent-bd);
}
/* ── L10 (2026-08-29) · EL SELLO QUE SÍ CAMBIA ────────────────────────────
   El sello ahora declara el ALCANCE de la tarjeta (ver la nota larga en
   apex-lab.php). Las que siguen al selector de período llevan `--periodo` y
   se pintan en acento pleno; las de "todo tu historial" quedan atenuadas.

   Es la señal que pidió Sergio —"no sé si darle un borde en línea lima
   resaltando: solo esto cambia"— resuelta con el componente que ya existía en
   todas las tarjetas, sin agregar un elemento nuevo ni tocar el layout: al
   mover los botones de arriba, los sellos en acento son literalmente los
   únicos que cambian de texto. Medido: solo 3 de 12 tarjetas responden al
   período, así que el contraste entre unas y otras es la información. */
.apex-soon-tag--periodo {
  background: var(--accent);
  color: var(--accent-t);
  border-color: var(--accent);
}

/* ════════════════════════════════════════════════════════════════
   2 · SWITCH DE ZONA (Start · Academia · Flow Pro)
   Control segmentado flotante, centrado, justo encima de la barra
   inferior — nunca choca con el topbar y es alcanzable con el pulgar.
   Una pastilla por zona disponible; la activa se resalta en lima.
   ════════════════════════════════════════════════════════════════ */
.apex-modeswitch {
  position: fixed; left: 50%; transform: translateX(-50%); z-index: 60;
  bottom: calc(var(--apex-nav-h) + var(--apex-subnav-h) + 12px + env(safe-area-inset-bottom, 0px));
  display: inline-flex; gap: 3px; padding: 4px;
  max-width: calc(100vw - 24px);
  background: var(--bg-deeper); border: 1px solid var(--border2);
  border-radius: 999px; box-shadow: 0 10px 30px rgba(0, 0, 0, .5);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  transition: transform .2s ease, max-width .2s ease;
}

/* 2026-08-02 · Cuando el FAB "EN VIVO" aparece, comparte fila con este switch
   (mismo `bottom`) y por defecto lo tapa: el switch se centra en TODA la
   pantalla sin saber que hay un botón fijo a la derecha. `--apex-vivo-fab-w`
   la fija el propio FAB en JS con su ancho YA renderizado (texto + contador),
   así que el hueco reservado siempre es el real, nunca un número adivinado
   (ver apex-lab.php). El switch se recentra en el espacio que le queda
   —viewport menos el FAB y un margen de respiro— y nunca lo toca. */
body.apex-tiene-vivo-fab .apex-modeswitch {
  max-width: calc(100vw - 24px - var(--apex-vivo-fab-w, 0px) - 10px);
  transform: translateX(calc(-50% - (var(--apex-vivo-fab-w, 0px) + 10px) / 2));
}
.apex-modeswitch-opt {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-size: 10px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; text-decoration: none;
  color: var(--gray); padding: 8px 15px; border-radius: 999px;
  transition: color .18s ease, background .18s ease; white-space: nowrap;
}
.apex-modeswitch-ico { display: inline-flex; }
.apex-modeswitch-ico svg { display: block; }
.apex-modeswitch-opt.active {
  color: var(--accent-t); background: var(--accent);
  box-shadow: 0 2px 12px rgba(200, 255, 0, .35);
}
.apex-modeswitch-opt:not(.active):hover { color: var(--text); background: rgba(255, 255, 255, .06); }

/* Con 3 zonas en pantallas muy angostas, apretar el padding para no desbordar. */
@media (max-width: 400px) {
  .apex-modeswitch[data-zonas="3"] .apex-modeswitch-opt { padding: 8px 11px; letter-spacing: .02em; }
}

/* En escritorio y en páginas internas (con sidebar), el switch flotante se
   oculta: la barra inferior solo existe en móvil. En páginas-app (Start/Lab)
   no hay sidebar, así que el switch se mantiene a todos los anchos. */
@media (min-width: 781px) {
  body:not(.apex-app) .apex-modeswitch { display: none; }
}

/* Páginas internas (dashboard, cursos…) en móvil: .content ya reserva 80px
   para la barra inferior (apex-shell.css), pero no para el switch flotante
   que vive encima de ella. Sin esto, el switch tapa los últimos ~30px de
   contenido al hacer scroll cuando el alumno tiene Academy + Performance.
   Solo afecta a quien tiene ambos niveles; el resto de alumnos no cambia. */
@media (max-width: 780px) {
  body.apex-has-modeswitch:not(.apex-app) .content {
    padding-bottom: 148px !important;
  }
}

/* En páginas internas, el switch flota sobre el contenido; el contenido ya
   tiene scroll propio, así que no hace falta empujar nada salvo asegurar que
   la barra inferior no lo tape (ya están escalonados por el bottom). */

/* ════════════════════════════════════════════════════════════════
   3 · HOJA "PRÓXIMAMENTE" (para ítems aún no construidos)
   ════════════════════════════════════════════════════════════════ */
.apex-soon-overlay {
  display: none; position: fixed; inset: 0; z-index: 998;
  background: rgba(6, 15, 20, .6); backdrop-filter: blur(2px);
}
.apex-soon-overlay.visible { display: block; }
.apex-soon-sheet {
  position: fixed; left: 50%; bottom: 0; transform: translateX(-50%) translateY(110%);
  width: min(440px, 100vw); z-index: 999;
  background: var(--bg2); border: 1px solid var(--border2);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 14px 22px calc(26px + env(safe-area-inset-bottom, 0px));
  text-align: center; transition: transform .3s cubic-bezier(.22, 1, .36, 1);
}
.apex-soon-sheet.visible { transform: translateX(-50%) translateY(0); }
.apex-soon-grip { width: 38px; height: 4px; border-radius: 2px; background: var(--bg5); margin: 0 auto 16px; }
.apex-soon-seal {
  display: inline-flex; font-family: var(--font-mono); font-size: 9px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; padding: 4px 10px;
  border-radius: var(--radius); background: var(--accent-bg);
  color: var(--accent); border: 1px solid var(--accent-bd); margin-bottom: 12px;
}
.apex-soon-title {
  font-family: var(--font-display); font-size: 19px; font-weight: 800;
  color: var(--text); text-transform: uppercase; letter-spacing: .01em; margin-bottom: 8px;
}
.apex-soon-text { font-family: var(--font-body, 'Barlow', sans-serif); font-size: 14px; color: var(--gray); line-height: 1.5; margin: 0 0 18px; }
.apex-soon-btn {
  width: 100%; height: 46px; border: none; cursor: pointer;
  background: var(--accent); color: var(--accent-t);
  font-family: var(--font-display); font-weight: 700; font-size: 14px;
  letter-spacing: .06em; text-transform: uppercase; border-radius: var(--radius-md);
}

/* ════════════════════════════════════════════════════════════════
   3b · HOJA "REPORTAR / PROPONER" — feedback del Lab (nivel Pro, 2026-08-02)
   Mismo patrón visual que la hoja "Próximamente" de arriba (mismas variables,
   mismo timing de transición) — clases propias porque esta hoja tiene un
   formulario adentro y no una tarjeta estática, y por eso no se reutilizan
   las clases .apex-soon-* directamente (salvo .apex-soon-grip, que es
   genérica). Los estilos de campos de formulario (input/select/textarea/botón)
   están calcados de css/apex-soporte.css — ese archivo NO se carga en el Lab
   (que es "página-app" sin el shell de /soporte/), así que se re-declaran acá
   bajo su propio nombre en vez de depender de una hoja que no está presente.
   ════════════════════════════════════════════════════════════════ */
.apex-lab-pie-link {
  display: block; width: 100%; margin: 14px 0 0; padding: 10px 0 0;
  background: none; border: none; cursor: pointer;
  font-family: var(--font-mono); font-size: 11.5px; color: var(--text-dim, #8a9fa8);
  text-align: center; text-decoration: underline; text-underline-offset: 3px;
}
.apex-lab-pie-link:hover { color: var(--text); }
/* El pie del Lab puede tener dos enlaces (glosario + feedback). Sin esto se
   pegaban uno al otro y parecían un solo bloque de texto subrayado. */
a.apex-lab-pie-link { margin-top: 10px; }

/* ══ GLOSARIO DE MÉTRICAS (?seccion=glosario, 2026-08-02) ══════════════════
   Lista de definiciones, no tarjetas: son ~45 entradas y una tarjeta por cada
   una serían 45 pantallas de scroll. El buscador de arriba es lo que hace
   usable esa cantidad — filtra por nombre Y por explicación, sin acentos. */
.apex-glo-buscar {
  display: flex; align-items: center; gap: 8px;
  background: var(--bg2, #0f2028); border: 1px solid var(--border, #1d3540);
  border-radius: 8px; padding: 9px 12px; margin: 0;
  color: var(--text-dim, #8a9fa8);
}
.apex-glo-buscar:focus-within { border-color: var(--accent, #C8FF00); }
.apex-glo-buscar svg { flex: 0 0 auto; }
.apex-glo-buscar input {
  flex: 1 1 auto; min-width: 0; background: none; border: 0; outline: none;
  color: var(--text); font-family: inherit; font-size: 13.5px; padding: 0;
}
.apex-glo-buscar input::placeholder { color: var(--text-dim, #8a9fa8); opacity: .8 }
.apex-glo-sinres { margin: 12px 0 0; font-size: 12.5px; color: var(--text-dim, #8a9fa8); line-height: 1.55 }

.apex-glo-lista { margin: 10px 0 0; padding: 0 }
.apex-glo-item { padding: 14px 0; border-top: 1px solid var(--border, #1d3540) }
.apex-glo-item:first-child { border-top: 0; padding-top: 6px }
.apex-glo-t {
  margin: 0 0 7px; font-family: var(--font-display); font-weight: 800;
  font-size: 14.5px; line-height: 1.3; color: var(--text);
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
}
/* De qué ventana habla la métrica. Es la confusión número uno del Lab —"este
   número no me cuadra con el otro"— y casi siempre la respuesta es que uno es
   del período y el otro de todo el historial. */
.apex-glo-vent {
  font-family: var(--font-mono); font-size: 9px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  padding: 2.5px 7px; border-radius: 20px; white-space: nowrap;
  border: 1px solid currentColor; opacity: .85;
}
.apex-glo-vent--per { color: #4db8ff }
.apex-glo-vent--his { color: #9d8cff }
.apex-glo-vent--amb { color: var(--text-dim, #8a9fa8) }
.apex-glo-d { margin: 0 }
.apex-glo-d p { margin: 0 0 6px; font-size: 13px; line-height: 1.6; color: var(--text-dim, #a8bfc9) }
.apex-glo-d p:last-child { margin-bottom: 0 }
.apex-glo-et {
  display: block; font-family: var(--font-mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--accent, #C8FF00);
  margin-bottom: 2px; opacity: .9;
}
@media (min-width: 620px) {
  /* En pantalla ancha la etiqueta se va al margen izquierdo y las tres líneas
     quedan alineadas — se lee como una ficha, no como tres párrafos sueltos.
     ⚠️ SOLO cuando hay etiqueta (:has(.apex-glo-et)) — bug real encontrado
     2026-08-29 (reporte Sergio, docx "análisis escritorio"): un término
     simple (sin Qué dice/De dónde sale/Para qué sirve, ej. "Apalancamiento")
     es un <p> con un solo nodo de texto, sin hijos. display:grid con
     grid-template-columns:118px 1fr metía TODO el texto en la primera
     columna de 118px por falta de un segundo elemento que ocupara la
     segunda — se veía envuelto en una columna angosta con ~700px vacíos al
     lado. Confirmado en producción: `hasEt:false` en el <p> afectado. */
  .apex-glo-d p:has(.apex-glo-et) { display: grid; grid-template-columns: 118px 1fr; gap: 10px; align-items: baseline }
  .apex-glo-et { margin-bottom: 0; text-align: right }
}

.apex-fb-overlay {
  display: none; position: fixed; inset: 0; z-index: 998;
  background: rgba(6, 15, 20, .6); backdrop-filter: blur(2px);
}
.apex-fb-overlay.visible { display: block; }
.apex-fb-sheet {
  position: fixed; left: 50%; bottom: 0; transform: translateX(-50%) translateY(110%);
  width: min(460px, 100vw); max-height: 88vh; overflow-y: auto; z-index: 999;
  background: var(--bg2); border: 1px solid var(--border2);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 14px 22px calc(24px + env(safe-area-inset-bottom, 0px));
  transition: transform .3s cubic-bezier(.22, 1, .36, 1);
}
.apex-fb-sheet.visible { transform: translateX(-50%) translateY(0); }
.apex-fb-title {
  font-family: var(--font-display); font-size: 17px; font-weight: 800;
  color: var(--text); text-align: center; margin-bottom: 6px;
}
.apex-fb-sub { font-family: var(--font-body, 'Barlow', sans-serif); font-size: 12.5px; color: var(--gray); line-height: 1.5; text-align: center; margin: 0 0 18px; }
.apex-fb-row { margin-bottom: 14px; }
.apex-fb-label {
  display: block; font-family: var(--font-mono); font-size: 10px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--gray); margin-bottom: 6px;
}
.apex-fb-select, .apex-fb-textarea {
  width: 100%; background: var(--bg); border: 1px solid var(--border);
  border-radius: 3px; padding: 11px 13px; font-family: inherit; font-size: 13px;
  color: var(--text); transition: border-color .15s; box-sizing: border-box;
}
.apex-fb-select:focus, .apex-fb-textarea:focus { outline: none; border-color: var(--accent); }
.apex-fb-textarea { resize: vertical; min-height: 110px; line-height: 1.55; font-family: inherit; }
.apex-fb-select {
  cursor: pointer; appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238a9fa8' stroke-width='2'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat; background-position: right 13px center; padding-right: 38px;
}
.apex-fb-counter { font-family: var(--font-mono); font-size: 9px; color: var(--gray2); text-align: right; margin-top: 4px; letter-spacing: .04em; }
.apex-fb-counter.warn { color: #ffce6b; }
.apex-fb-counter.over { color: var(--apex-neg); }
.apex-fb-submit-row {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border);
}
.apex-fb-info { font-size: 11.5px; color: var(--gray); }
.apex-fb-btn {
  font-family: var(--font-mono); font-size: 11px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; background: var(--accent);
  color: var(--accent-t); border: 0; padding: 12px 22px; border-radius: 3px;
  cursor: pointer; transition: opacity .15s; flex: 0 0 auto;
}
.apex-fb-btn:hover:not(:disabled) { opacity: .9; }
.apex-fb-btn:disabled { opacity: .5; cursor: not-allowed; }
.apex-fb-msg { padding: 11px 13px; border-radius: 3px; font-size: 12.5px; line-height: 1.5; margin-bottom: 14px; display: none; }
.apex-fb-msg.show { display: block; }
.apex-fb-msg.success { background: rgba(46, 204, 113, .08); border: 1px solid rgba(46, 204, 113, .3); color: #2ecc71; }
.apex-fb-msg.error { background: rgba(231, 76, 60, .08); border: 1px solid rgba(231, 76, 60, .3); color: #e74c3c; }
@media (max-width: 480px) {
  .apex-fb-submit-row { flex-direction: column; align-items: stretch; }
  .apex-fb-btn { justify-content: center; }
}

/* ════════════════════════════════════════════════════════════════
   4 · BOTÓN DE MENÚ EN EL TOPBAR (zona Academy, solo móvil)
   Inyectado por JS para no perder acceso al drawer (perfil, biblioteca…).
   ════════════════════════════════════════════════════════════════ */
.apex-topbar-burger {
  display: none; align-items: center; justify-content: center;
  width: 36px; height: 36px; margin-right: 4px; flex: 0 0 36px;
  background: var(--bg3); border: 1px solid var(--border); border-radius: var(--radius-md);
  color: var(--text); cursor: pointer;
}
@media (max-width: 780px) { .apex-topbar-burger { display: inline-flex; } }

/* ════════════════════════════════════════════════════════════════
   5 · LAYOUT DE PÁGINAS-APP (Start / Performance Lab)
   Todo scoped a body.apex-app — no afecta a las páginas internas.
   ════════════════════════════════════════════════════════════════ */
body.apex-app {
  min-height: 100vh; background: var(--bg); color: var(--text);
  font-family: var(--font-body, 'Barlow', -apple-system, sans-serif);

  /* 2026-08-28 · F1 de la versión de escritorio. El 560 estaba escrito a mano en
     CUATRO lugares (shell, barra inferior, barra de guardado y tira de fichas):
     cambiar el ancho de la app obligaba a encontrarlos todos, y olvidarse de uno
     dejaba una barra descolgada del contenido. Ahora es UNA variable.
     ⚠️ El valor por defecto es el mismo de siempre, así que para el teléfono no
     cambia absolutamente nada — es una refactorización, no un rediseño. Solo
     css/apex-flow-desktop.css la pisa, y solo a partir de 1024px.
     Regla 3.3 de 05_WEB/2026-08-28_plan_web_escritorio_v02.md: ningún `560px`
     nuevo escrito a mano, en ningún archivo. */
  --apex-shell-max: 560px;
}
.apex-app-shell { min-height: 100vh; display: flex; flex-direction: column; max-width: var(--apex-shell-max); margin: 0 auto; }

/* Topbar */
.apex-app-topbar {
  position: sticky; top: 0; z-index: 40;
  height: calc(56px + env(safe-area-inset-top, 0px));
  padding: env(safe-area-inset-top, 0px) 16px 0;
  display: flex; align-items: center; gap: 12px;
  background: rgba(10, 30, 38, .97); backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
.apex-app-iso {
  width: 38px; height: 38px; flex: 0 0 38px; border-radius: var(--radius-md);
  background: var(--bg4); border: 1px solid var(--accent-bd);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-size: 19px; font-weight: 900;
  color: var(--text); text-decoration: none; line-height: 1; letter-spacing: -.01em;
}
.apex-app-iso i { color: var(--accent); font-style: normal; }
.apex-app-titles { min-width: 0; }
.apex-app-kicker { font-family: var(--font-mono); font-size: 9px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--gray2); }
.apex-app-title { font-family: var(--font-display); font-size: 19px; font-weight: 800; color: var(--text); text-transform: uppercase; letter-spacing: .02em; line-height: 1.1; }
.apex-app-access {
  margin-left: auto; flex-shrink: 0;
  font-family: var(--font-mono); font-size: 10px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; text-decoration: none;
  color: var(--gray); padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--radius);
  transition: color .15s, border-color .15s;
}
.apex-app-access:hover { color: var(--text); border-color: var(--border2); }

/* Distintivo "APEX Flow Pro" en el topbar (solo para quien pagó/regalo). Señala
   que las dos zonas —Start y Lab— están actualizadas a Pro. */
.apex-flowpro-badge {
  margin-left: auto; flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
  color: var(--accent-t); background: var(--accent);
  padding: 6px 11px; border-radius: 999px;
  box-shadow: 0 2px 10px rgba(200, 255, 0, .3);
}
.apex-flowpro-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent-t); opacity: .7; }
/* Si además hay botón de acceso (Start), que el badge empuje y el acceso lo siga. */
.apex-flowpro-badge + .apex-app-access { margin-left: 8px; }

/* ══ BOTÓN DE IDENTIDAD DEL TOPBAR (2026-08-02) ════════════════════════════
   Reemplaza al badge de arriba, que era un <span> que no llevaba a ningún
   lado. Avatar de iniciales SIEMPRE (el del plan gratis también necesita
   cerrar sesión) + "Pro" solo si corresponde. Área táctil de 38px: es el
   único acceso a la pantalla donde se cancela la suscripción, no puede ser
   un blanco difícil de acertar con el pulgar. */
.apex-cta-topbar {
  margin-left: auto; flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 4px 4px 4px 4px; border-radius: 999px;
  text-decoration: none; border: 1px solid transparent;
  transition: background .15s, border-color .15s;
}
a.apex-cta-topbar:hover { background: rgba(255,255,255,.06); border-color: var(--border2, #24404d); }
a.apex-cta-topbar:focus-visible { outline: 2px solid var(--accent, #C8FF00); outline-offset: 2px; }
.apex-cta-topbar.is-active { background: rgba(200,255,0,.10); border-color: var(--accent-bd, rgba(200,255,0,.35)); }
.apex-cta-topbar-ini {
  width: 30px; height: 30px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--bg3, #12242d);
  border: 1px solid var(--border2, #24404d);
  font-family: var(--font-mono); font-size: 11px; font-weight: 700;
  letter-spacing: .02em; color: var(--text);
}
.apex-cta-topbar.is-pro .apex-cta-topbar-ini {
  background: var(--accent); border-color: var(--accent); color: var(--accent-t);
}
.apex-cta-topbar-pro {
  font-family: var(--font-mono); font-size: 9px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--accent);
  padding-right: 6px;
}
/* En pantallas chicas queda solo el avatar: el topbar del Lab ya lleva kicker,
   título y, en la sección En vivo, el indicador — "Pro" es lo primero que sobra. */
@media (max-width: 400px) { .apex-cta-topbar-pro { display: none } }

/* ══ PANTALLA MI CUENTA (?seccion=cuenta) ══════════════════════════════════ */
.apex-cta-id { display: flex; align-items: center; gap: 16px }
.apex-cta-avatar {
  width: 56px; height: 56px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--accent); color: var(--accent-t);
  font-family: var(--font-display); font-size: 20px; font-weight: 900; letter-spacing: .02em;
}
.apex-cta-id-txt { min-width: 0 }
.apex-cta-id-txt h3 {
  margin: 0 0 3px; font-family: var(--font-display); font-size: 19px;
  font-weight: 800; color: var(--text); line-height: 1.15;
  overflow-wrap: anywhere;
}
.apex-cta-mail {
  margin: 0 0 7px; font-family: var(--font-mono); font-size: 11.5px;
  color: var(--text-dim, #8a9fa8); overflow-wrap: anywhere;
}
.apex-cta-badge {
  display: inline-block; font-family: var(--font-mono); font-size: 9.5px;
  font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  padding: 4px 9px; border-radius: 999px; border: 1px solid currentColor;
}
.apex-cta-badge--ok     { color: #2ecc71 }
.apex-cta-badge--prueba { color: var(--accent, #C8FF00) }
.apex-cta-badge--regalo { color: #9d8cff }
.apex-cta-badge--aviso  { color: #ffb020 }
.apex-cta-badge--alerta { color: #ff6b6b }
.apex-cta-badge--off    { color: var(--text-dim, #8a9fa8) }
.apex-cta-aviso-ok { color: #2ecc71; margin: -4px 0 12px }

/* La prueba gratis, destacada: es el único dato por el que alguien puede
   sentirse estafado si no lo vio a tiempo. */
.apex-cta-prueba {
  display: flex; align-items: center; gap: 14px;
  background: var(--accent-bg, rgba(200,255,0,.07));
  border: 1px solid var(--accent-bd, rgba(200,255,0,.35));
  border-radius: var(--radius-md, 10px); padding: 14px 16px; margin: 0 0 16px;
}
.apex-cta-prueba-dias {
  flex-shrink: 0; font-family: var(--font-display); font-size: 34px;
  font-weight: 900; line-height: 1; color: var(--accent);
}
.apex-cta-prueba-txt strong { display: block; font-size: 13.5px; color: var(--text); margin-bottom: 3px }
.apex-cta-prueba-txt span   { display: block; font-size: 12.5px; line-height: 1.55; color: var(--text-dim, #a8bfc9) }

.apex-cta-nota { margin: 0 0 14px; font-size: 13px; line-height: 1.6; color: var(--text-dim, #a8bfc9) }
.apex-cta-nota--aviso  { color: #ffb020 }
.apex-cta-nota--alerta { color: #ff6b6b }

.apex-cta-datos { margin: 0 0 16px; padding: 0; display: grid; gap: 1px; background: var(--border, #1d3540); border-radius: 8px; overflow: hidden }
.apex-cta-datos > div { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; background: var(--bg2, #0f2028); padding: 11px 14px }
.apex-cta-datos dt { font-size: 12.5px; color: var(--text-dim, #8a9fa8) }
.apex-cta-datos dd { margin: 0; font-size: 13px; font-weight: 700; color: var(--text); text-align: right }

.apex-cta-form { margin: 0 }
.apex-cta-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 12px }
.apex-cta-row:has(.apex-cta-ro) { grid-template-columns: 1fr }
@media (max-width: 480px) { .apex-cta-row { grid-template-columns: 1fr } }
.apex-cta-form label { display: block }
.apex-cta-form label > span { display: block; font-family: var(--font-mono); font-size: 9.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim, #8a9fa8); margin-bottom: 5px }
.apex-cta-form input {
  width: 100%; box-sizing: border-box; padding: 10px 12px;
  background: var(--bg2, #0f2028); border: 1px solid var(--border, #1d3540);
  border-radius: 8px; color: var(--text); font-family: inherit; font-size: 14px;
}
.apex-cta-form input:focus { outline: none; border-color: var(--accent, #C8FF00) }
.apex-cta-form input[disabled] { opacity: .6; cursor: not-allowed }
.apex-cta-msg { display: inline-block; margin-left: 12px; font-size: 12.5px; color: var(--text-dim, #8a9fa8) }
.apex-cta-msg.is-ok  { color: #2ecc71 }
.apex-cta-msg.is-err { color: #ff6b6b }

.apex-cta-acciones { display: flex; flex-wrap: wrap; gap: 10px }
.apex-cta-acciones .flow-btn { flex: 1 1 auto; justify-content: center; text-align: center }

/* Contenido (deja espacio para la barra inferior fija) */
.apex-app-content {
  flex: 1; padding: 18px 16px;
  padding-bottom: calc(var(--apex-nav-h) + var(--apex-subnav-h) + 28px + env(safe-area-inset-bottom, 0px));
}
body.apex-app.apex-has-modeswitch .apex-app-content {
  padding-bottom: calc(var(--apex-nav-h) + var(--apex-subnav-h) + 70px + env(safe-area-inset-bottom, 0px));
}

/* Barra inferior en páginas-app (apex-shell.css no se carga aquí) */
body.apex-app .apex-mob-nav {
  position: fixed; bottom: 0; left: 50%; transform: translateX(-50%);
  width: 100%; max-width: var(--apex-shell-max); z-index: 50;
  height: calc(var(--apex-nav-h) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  display: flex; align-items: stretch;
  background: var(--bg-deeper); border-top: 1px solid var(--border);
}
body.apex-app .apex-mob-nav-item {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; text-decoration: none; color: var(--gray2);
  font-family: var(--font-mono); font-size: 10px; font-weight: 600; letter-spacing: .04em;
  transition: color .15s; position: relative;
}
body.apex-app .apex-mob-nav-item.active { color: var(--accent); }
body.apex-app .apex-mob-nav-item:hover { color: var(--text); }
body.apex-app .apex-mob-nav-item.active::before {
  content: ''; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 26px; height: 2px; background: var(--accent); border-radius: 0 0 2px 2px;
}
body.apex-app .apex-mob-nav-ico { display: flex; }

/* 2026-08-09 — CUATRO ítems, los mismos para gratis y para Pro.
   Antes eran 6 para el gratis y 5 para el Pro, y encima el Pro tenía DOS barras
   distintas (una por zona). A 375px, 4 ítems dan 93px cada uno contra los 62px
   de antes; incluso a 320px quedan 80px. Con ese aire ya no hace falta apretar
   el texto —la regla de 400px que lo bajaba a 8px se retira— y la etiqueta
   sube a 10px, que es la diferencia entre leerla y adivinarla en un teléfono.
   La etiqueta más larga es "Mi operativa"; el ellipsis de abajo queda igual
   como red de seguridad, no como comportamiento esperado. */
@media (max-width: 360px) {
  body.apex-app .apex-mob-nav-item { letter-spacing: 0; gap: 3px; }
}
body.apex-app .apex-mob-nav-item > span:last-child {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ════════════════════════════════════════════════════════════════
   6 · PERFORMANCE LAB — tarjetas demo
   ════════════════════════════════════════════════════════════════ */
.apex-lab-hero {
  background: linear-gradient(160deg, var(--bg3), var(--bg2));
  border: 1px solid var(--accent-bd); border-radius: var(--radius-lg);
  padding: 18px; margin-bottom: 14px;
}
.apex-lab-hero-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.apex-lab-hero-label { font-family: var(--font-mono); font-size: 10px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--gray); }
/* 2026-07-25 · Pedido de Sergio: operaciones y días van PEGADOS A LA DERECHA del
   score, no debajo. En el celular el héroe ocupaba media pantalla solo para decir
   dos cifras. `.apex-lab-hero-fila` es el contenedor nuevo que los pone en fila;
   la meta se alinea a la derecha y pierde el margen superior que la empujaba. */
.apex-lab-hero-fila { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.apex-lab-hero-score { display: flex; align-items: baseline; gap: 8px; }
.apex-lab-score-num { font-family: var(--font-display); font-size: 64px; font-weight: 900; color: var(--accent); line-height: 1; letter-spacing: -.02em; }
.apex-lab-score-max { font-family: var(--font-mono); font-size: 14px; color: var(--gray2); }
/* Antes tenía `margin-left:auto` para empujarse contra el borde del cuadro. Con
   la fila nueva, ese auto lo despegaba del score y lo mandaba al medio: ahora va
   pegado al "/100", que es donde se lee como tendencia del número. */
.apex-lab-score-tend { font-family: var(--font-mono); font-size: 13px; font-weight: 600; color: var(--apex-pos); }
.apex-lab-score-tend.pos { color: var(--apex-pos, #4ade80); }
.apex-lab-score-tend.neg { color: var(--apex-neg, #f87171); }
/* Score con muestra insuficiente: se muestra igual, atenuado. Esconderlo sería
   tratar al alumno de tonto; cantarlo en firme sería mentirle. */
.apex-lab-score-num.apex-lab-score-flojo { opacity: .55; }
.apex-lab-hero-aviso { margin: 6px 0 0; font-size: 12px; color: #ffcf85; }
.apex-lab-hero-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; margin-top: 0; font-size: 13px; line-height: 1.35; color: var(--text); text-align: right; }
.apex-lab-hero-meta span { color: var(--gray); }
.apex-lab-hero-meta b { color: var(--text); font-weight: 700; }
.apex-lab-hero-sub { margin: 10px 0 0; font-family: var(--font-mono); font-size: 11px; color: var(--gray2); }
.apex-lab-hero-cero { margin: 8px 0 0; font-size: 12.5px; color: var(--gray); }
.apex-lab-hero-cero a { color: var(--accent); text-decoration: underline; }
.apex-lab-hero-note { margin: 12px 0 0; font-size: 12px; color: var(--gray2); font-style: italic; }

.apex-lab-card { background: var(--bg2); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 16px; margin-bottom: 14px; }
.apex-lab-card-head { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; }
.apex-lab-card-ico { display: flex; color: var(--accent); }
.apex-lab-card-head h3 { font-family: var(--font-display); font-size: 15px; font-weight: 800; color: var(--text); text-transform: uppercase; letter-spacing: .03em; margin: 0; }
.apex-lab-card-head .apex-soon-tag { margin-left: auto; }

.apex-lab-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
/* 2026-09-01 · Total depositado / Total retirado / Neto, los tres en una fila
   — pedido literal de Sergio ("tres cuadrados en fila"). Valores cortos
   (montos, no textos largos), así que entran los tres sin colapsar a 1
   columna como hace `.apex-vivo-pos` más abajo con sus etiquetas más largas. */
.apex-lab-stats--3 { grid-template-columns: 1fr 1fr 1fr; }
.apex-lab-stat { background: var(--bg3); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 12px; display: flex; flex-direction: column; gap: 3px; }
.apex-lab-stat .v { font-family: var(--font-display); font-size: 22px; font-weight: 800; color: var(--text); line-height: 1; }
.apex-lab-stat .v.pos { color: var(--apex-pos); }
.apex-lab-stat .v.neg { color: var(--apex-neg); }
.apex-lab-stat .k { font-family: var(--font-mono); font-size: 9px; font-weight: 500; letter-spacing: .06em; text-transform: uppercase; color: var(--gray); }
.apex-lab-muestra { margin: 12px 0 0; font-size: 11px; color: var(--gray2); }

.apex-lab-chart-demo { height: 120px; background: var(--bg3); border: 1px solid var(--border); border-radius: var(--radius-md); margin-bottom: 12px; overflow: hidden; }
.apex-lab-chart-demo svg { width: 100%; height: 100%; display: block; opacity: .85; }

.apex-lab-locked .apex-lab-locked-text { font-size: 13px; color: var(--gray); line-height: 1.5; margin: 0; }

/* ══ VITRINA DEL LAB para el plan gratis (2026-08-08) ══
   Todo en gris con candado: se ve QUÉ hay adentro sin fingir que hay datos.
   Deliberadamente sin números de ejemplo — ver apex-lab-vitrina.php. */
.apex-lab-vitrina { padding: 4px 0 8px; }
.apex-lab-vitrina-head { margin-bottom: 18px; }
.apex-lab-vitrina-tag {
  display: inline-block; font-family: var(--font-mono); font-size: 9px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--accent);
  background: var(--accent-bg); border: 1px solid var(--accent-bd);
  border-radius: var(--radius); padding: 3px 8px; margin-bottom: 10px;
}
.apex-lab-vitrina-head h2 { font-family: var(--font-display); font-size: 22px; font-weight: 800; color: var(--text); margin: 0 0 8px; line-height: 1.2; }
.apex-lab-vitrina-head p { font-size: 13px; color: var(--gray); line-height: 1.6; margin: 0; }

.apex-lab-vitrina-lista { display: flex; flex-direction: column; gap: 8px; }
/* El "plomo" que pidió Sergio: el ítem entero apagado, sin hover ni cursor de
   link — nada invita a tocarlo porque no lleva a ningún lado. */
.apex-lab-vit-item {
  display: flex; align-items: flex-start; gap: 11px;
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 13px;
  opacity: .62;
}
.apex-lab-vit-ico { flex: 0 0 auto; color: var(--gray2); margin-top: 1px; }
.apex-lab-vit-txt { flex: 1; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.apex-lab-vit-t { font-size: 14px; font-weight: 800; color: var(--text); }
.apex-lab-vit-q { font-size: 12px; color: var(--gray); line-height: 1.5; }
/* El candado sí conserva color: es lo único que tiene que leerse de un vistazo. */
.apex-lab-vit-candado { flex: 0 0 auto; color: var(--gray2); margin-top: 2px; }

.apex-lab-vitrina-cta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 20px 0 0; }
.apex-lab-vitrina-trial { font-size: 12px; color: var(--gray); }
.apex-lab-vitrina-nota {
  font-size: 11px; color: var(--gray2); line-height: 1.6; margin: 18px 0 0;
  padding-top: 14px; border-top: 1px solid var(--border);
}
.apex-lab-vitrina-nota b { color: var(--gray); }
/* Entrada para quien YA es Pro y llegó sin sesión. Va al pie y discreta: el
   objetivo de esta pantalla es el que NO tiene cuenta. */
.apex-lab-vitrina-login { font-size: 12px; color: var(--gray2); text-align: center; margin: 18px 0 0; }
.apex-lab-vitrina-login a { color: var(--accent); font-weight: 700; }

/* Pie legal del Lab (F3.12, 2026-08-01). Discreto pero legible: si hay que
   entrecerrar los ojos para leerlo, no cumple su función. Sin caja ni borde
   —no es una tarjeta más—, separado del contenido por espacio y por una línea
   fina, y por encima de la barra inferior. */
.apex-lab-legal {
  max-width: 720px;
  margin: 28px auto 0;
  padding: 16px 4px 0;
  border-top: 1px solid var(--border);
  font-size: 12px;
  line-height: 1.6;
  color: var(--gray);
  text-align: left;
  text-wrap: pretty;
}

/* Seguimiento en vivo (2026-07-31) — una tarjeta por posición abierta. */
.apex-vivo-pos { background: var(--bg3); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 12px; margin-bottom: 10px; }
.apex-vivo-pos:last-child { margin-bottom: 0; }
.apex-vivo-pos-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.apex-vivo-side { font-family: var(--font-display); font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; padding: 3px 9px; border-radius: 999px; }
.apex-vivo-side--buy { color: var(--apex-pos, #6ee7a0); background: rgba(110,231,160,.16); }
.apex-vivo-side--sell { color: var(--apex-neg, #ff7a7a); background: rgba(255,122,122,.16); }
.apex-vivo-vol { font-family: var(--font-mono); font-size: 12px; color: var(--gray); }
.apex-vivo-pnl { margin-left: auto; font-family: var(--font-display); font-size: 16px; font-weight: 800; }
.apex-vivo-pnl.pos { color: var(--apex-pos); }
.apex-vivo-pnl.neg { color: var(--apex-neg); }
/* 3 columnas propias: la tarjeta de vivo siempre tiene 3 datos por posición
   (R, stop, equilibrio real) — el grid de 2 columnas de .apex-lab-stats
   dejaría el tercero solo en su fila. */
.apex-vivo-pos .apex-lab-stats { grid-template-columns: 1fr 1fr 1fr; }
.apex-vivo-aviso { margin: 10px 0 0; padding: 9px 11px; border-radius: var(--radius-md); font-size: 12.5px; line-height: 1.5; }
.apex-vivo-aviso--critica { background: rgba(255,122,122,.12); border: 1px solid rgba(255,122,122,.3); color: var(--text); }
.apex-vivo-aviso--aviso { background: rgba(255,176,32,.12); border: 1px solid rgba(255,176,32,.3); color: var(--text); }
.apex-vivo-aviso--logro { background: rgba(110,231,160,.12); border: 1px solid rgba(110,231,160,.3); color: var(--text); }
/* 2026-08-10 · Los avisos ahora vienen del motor y pueden ser varios por
   operación, con título y detalle. El título en negrita se lee de un vistazo
   —que es como se lee una alarma— y el detalle explica abajo, más apagado. */
.apex-vivo-aviso--info { background: rgba(158,195,209,.10); border: 1px solid rgba(158,195,209,.22); color: var(--text); }
.apex-vivo-aviso + .apex-vivo-aviso { margin-top: 7px; }
.apex-vivo-aviso-t { display: block; font-weight: 600; }
.apex-vivo-aviso-d { display: block; margin-top: 3px; color: var(--gray); font-size: 12px; }
/* Avisos del DÍA, no de una operación: van arriba de las tarjetas. */
.apex-vivo-sesion { margin-bottom: 14px; }
.apex-vivo-sesion .apex-vivo-aviso:first-child { margin-top: 0; }
/* "Poniendo al día tu Lab" tras cerrar una operación. Deliberadamente sobrio:
   es información de estado, no una alerta — no compite con los avisos de riesgo. */
.apex-vivo-sync { margin: 10px 0 0; font-size: 12px; color: var(--gray2); font-style: italic; }

/* ════════════════════════════════════════════════════════════════
   VISTA "EN VIVO" a pantalla completa (2026-07-31)
   Una tarjeta grande por operación abierta, con gráfico.
   ════════════════════════════════════════════════════════════════ */
.apex-vivo-cargando,
.apex-vivo-gr-cargando { padding: 22px 12px; text-align: center; font-size: 13px; color: var(--gray); }
.apex-vivo-gr-vacio { padding: 26px 12px; text-align: center; font-size: 12.5px; color: var(--gray2); }

.apex-vivo-full {
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 14px; margin-bottom: 14px;
}
.apex-vivo-full-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 12px; }
.apex-vivo-sim { font-family: var(--font-display); font-size: 15px; font-weight: 800; color: var(--text); letter-spacing: .02em; }
.apex-vivo-pnl-big { margin-left: auto; font-family: var(--font-display); font-size: 22px; font-weight: 800; line-height: 1; }
.apex-vivo-pnl-big.pos { color: var(--apex-pos); }
.apex-vivo-pnl-big.neg { color: var(--apex-neg); }

.apex-vivo-grafico { background: var(--bg3); border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; margin-bottom: 12px; }
/* Alto fijo con preserveAspectRatio="none": el gráfico se estira al ancho del
   celular sin dejar franjas vacías ni obligar a scroll horizontal. */
.apex-vivo-svg { display: block; width: 100%; height: 240px; }
/* Pie del gráfico: selector de temporalidad + cuánto abarca lo que se ve.
   Reemplazó al conteo de velas, que era un número interno sin significado
   (2026-08-10, pregunta de Sergio). */
.apex-vivo-gr-pie {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 6px 9px 8px; font-family: var(--font-mono); font-size: 9px;
  letter-spacing: .06em; text-transform: uppercase; color: var(--gray2);
}
.apex-vivo-tfs { display: flex; gap: 4px; }
.apex-vivo-tf {
  background: transparent; border: 1px solid var(--border); color: var(--gray2);
  border-radius: 6px; padding: 3px 8px; font-family: var(--font-mono);
  font-size: 10px; letter-spacing: .04em; cursor: pointer;
  /* 28px de alto mínimo: es un control que se toca con el dedo en el celular. */
  min-height: 26px; min-width: 32px; transition: color .15s, border-color .15s, background .15s;
}
.apex-vivo-tf:hover { color: var(--text); border-color: var(--gray2); }
.apex-vivo-tf.is-on {
  color: #06202a; background: var(--accent, #C8FF00);
  border-color: var(--accent, #C8FF00); font-weight: 700;
}
.apex-vivo-abarca { margin-left: auto; }

/* ── "Lo que elegiste": R:B del plan vs. la regla propia (2026-08-09) ──
   Pedido de Sergio. Va JUSTO debajo del gráfico y encima de los números
   sueltos: es la lectura de su DECISIÓN (dónde puso stop y objetivo), no del
   resultado. El borde izquierdo de color es el veredicto — verde cumple, rojo
   no llega — para que se entienda sin leer.
   Neutro por defecto: si el alumno no declaró un R:B objetivo no se pinta ni
   verde ni rojo, porque no hay contra qué compararlo. */
.apex-vivo-plan {
  display: flex; align-items: center; gap: 13px;
  background: var(--bg3); border: 1px solid var(--border);
  border-left: 3px solid var(--gray2);
  border-radius: var(--radius-md); padding: 10px 13px; margin-bottom: 12px;
}
.apex-vivo-plan--ok { border-left-color: var(--apex-pos, #6ee7a0); }
.apex-vivo-plan--no { border-left-color: var(--apex-neg, #ff7a7a); }
.apex-vivo-plan-rr { display: flex; flex-direction: column; align-items: center; line-height: 1; flex: none; }
.apex-vivo-plan-rr .v { font-family: var(--font-display); font-size: 21px; font-weight: 800; color: var(--text); }
.apex-vivo-plan-rr .k {
  font-family: var(--font-mono); font-size: 8.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--gray2); margin-top: 3px;
}
.apex-vivo-plan-det { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.apex-vivo-plan-linea { font-size: 12.5px; color: var(--gray); }
.apex-vivo-plan-linea b { font-family: var(--font-mono); font-weight: 700; }
.apex-vivo-plan-linea b.pos { color: var(--apex-pos, #6ee7a0); }
.apex-vivo-plan-linea b.neg { color: var(--apex-neg, #ff7a7a); }
.apex-vivo-plan-regla { font-size: 12px; font-weight: 600; color: var(--text); }
.apex-vivo-plan--ok .apex-vivo-plan-regla { color: var(--apex-pos, #6ee7a0); }
.apex-vivo-plan--no .apex-vivo-plan-regla { color: var(--apex-neg, #ff7a7a); }
.apex-vivo-plan-regla--sin { color: var(--gray2); font-weight: 400; }
/* Sin stop, sin objetivo, o stop ya en ganancia: no hay ratio que mostrar,
   solo el motivo. Una sola línea, sin el número grande al lado. */
.apex-vivo-plan--vacio, .apex-vivo-plan--libre { border-left-color: var(--gray2); }
.apex-vivo-plan--libre { border-left-color: var(--apex-pos, #6ee7a0); }
.apex-vivo-plan-nota { font-size: 12.5px; color: var(--gray); }

.apex-vivo-costos {
  margin: 10px 0 0; font-size: 12px; line-height: 1.5; color: var(--gray);
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 9px 11px;
}
.apex-vivo-costos b { color: var(--text); }

/* 6 datos por operación: 3 columnas en pantallas normales, 2 en angostas. */
.apex-vivo-stats4 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 480px) { .apex-vivo-stats4 { grid-template-columns: repeat(2, 1fr); } }

.apex-vivo-meta { margin: 10px 0 0; font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em; color: var(--gray2); }

/* ── GRÁFICO DE BANDA DEL DÍA (Volatilidad) ────────────────────────
   2026-08-28 · F3 / D6. Estilos del SVG que dibuja apex-grafico-banda.php.

   Vive en la hoja BASE y no en apex-flow-desktop.css a propósito: el gráfico
   NO es una mejora de escritorio, es el contenido mejor dicho, y se ve en los
   dos anchos. Lo único que cambia con el ancho es el alto (--apex-vol-graf-h),
   más bajo en teléfono para que no se coma la pantalla. Un componente, dos
   tamaños — cero bifurcación (Regla 1).

   Ni un color literal: todo sale de apex-tokens.css, así que el día del portal
   somosapex (Flow y Academia con paletas propias) este gráfico se ve correcto
   en las dos ramas sin abrirlo. */
   ⚠️ 2026-09-01 · ERA UN SVG Y DEJÓ DE SERLO. Sergio: "no se logran ver los
   números del gráfico, es muuuuuy pequeño". Medido en el navegador: el
   `viewBox` de 1000 de ancho se renderiza a ~309px en teléfono, así que TODO
   lo de adentro quedaba al 31% — un `<text>` de 13px terminaba en **5px
   reales**. En un SVG con viewBox eso no se arregla con CSS: el texto escala
   con la figura por definición, y subir el font-size lo arregla en teléfono
   y lo rompe en escritorio. Ahora las bandas son divs en % y las cifras son
   HTML: los px de abajo son px de verdad, en cualquier ancho. */
.apex-vol-grafico { margin: 14px 0 10px; }

/* La referencia, arriba y centrada sobre la línea que la marca. */
.apex-vol-g-ref { text-align: center; margin-bottom: 8px; }
.apex-vol-g-ref-num {
  display: block; font-family: var(--font-display); font-size: 20px;
  font-weight: 800; color: var(--text); line-height: 1.1;
}
.apex-vol-g-ref-eti {
  display: block; font-family: var(--font-mono); font-size: 9px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--gray2); margin-top: 3px;
}

/* La pista: alto fijo, las bandas adentro posicionadas en %.
   ⚠️ 2026-09-02 — Sergio, mirándolo en el teléfono: "el único que se nota es
   el lima, los demás son el mismo tono... si no fuera por las líneas que
   apenas se ven no se notaría la diferencia". Tenía razón: 80 y 95 no tenían
   ningún relleno, solo un borde de 1px en --border2 —el MISMO gris que usa
   cualquier borde de la interfaz—, así que a simple vista eran del color de
   la pista. La pista arranca ahora bien oscura (--bg-deeper, más oscura que
   la propia tarjeta que la contiene) y cada banda tiene su relleno real,
   aclarando a medida que se acerca al centro: --bg-deeper (pista) → --bg3
   (95%) → --bg5 (80%) → lima (68%, sin cambios — ya se notaba bien). Los
   tres tonos salen de la MISMA rampa de fondos del sistema (apex-tokens.css),
   ninguno es un color nuevo. */
.apex-vol-g-pista {
  position: relative; width: 100%;
  height: var(--apex-vol-graf-h, 84px);
  background: var(--bg-deeper);
  border: 1px solid var(--border);
  border-radius: 6px;
}
/* Cada banda es una capa: cuanto más angosta, más cerca del centro, más clara
   y más presente. La de 68 sigue siendo la única en acento pleno (es la que
   la ficha muestra primero) — 80 y 95 ahora SÍ tienen relleno propio, solo
   que en tonos neutros de la rampa, no en lima. */
.apex-vol-g-b {
  position: absolute; top: 8px; bottom: 8px;
  border: 1px solid var(--border2); border-radius: 6px;
}
.apex-vol-g-b--95 { top: 0; bottom: 0; background: var(--bg3); }
.apex-vol-g-b--80 { top: 4px; bottom: 4px; background: var(--bg5); }
.apex-vol-g-b--68 {
  background: linear-gradient(180deg, var(--accent-bg), rgba(200,255,0,.03));
  border-color: var(--accent-bd);
  box-shadow: 0 0 0 1px rgba(200,255,0,.05), 0 2px 14px rgba(200,255,0,.06);
}
/* La línea de la referencia: el dato duro de hoy, el único trazo en acento
   pleno. Sobresale arriba y abajo para que se lea como un eje, no como el
   borde de una caja. */
.apex-vol-g-centro {
  position: absolute; left: 50%; top: -7px; bottom: -7px;
  width: 2px; margin-left: -1px; background: var(--accent); border-radius: 1px;
  box-shadow: 0 0 10px rgba(200,255,0,.35);
}
/* Guías a los bordes del 68%: atan la figura con los precios de abajo. */
.apex-vol-g-guia {
  position: absolute; top: 8px; bottom: -6px; width: 1px; margin-left: -.5px;
  background: linear-gradient(180deg, transparent, var(--accent-bd) 40%);
}

/* Los extremos del 68%, cada uno debajo de su borde. */
.apex-vol-g-pies {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 8px; margin-top: 8px;
}
.apex-vol-g-pie {
  font-family: var(--font-mono); font-size: 12px; color: var(--text); white-space: nowrap;
}


/* Los chips dicen sólo el número y la palabra va una vez, al principio: con
   "68% de los cierres" ×3 la leyenda se partía en dos líneas en teléfono. */
.apex-vol-g-leyenda {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-top: 12px;
}
.apex-vol-g-leyenda-eti {
  font-family: var(--font-mono); font-size: 9px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--gray2);
}
.apex-vol-g-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em; color: var(--gray);
}
.apex-vol-g-chip i {
  width: 14px; height: 10px; border-radius: 2px;
  border: 1px solid var(--border2); flex: 0 0 14px;
}
/* Mismos tres tonos que las bandas de arriba (2026-09-02): antes 80 y 95 no
   tenían relleno acá tampoco, así que la leyenda no servía como clave de
   color — dos cuadraditos vacíos no dicen cuál es cuál. */
.apex-vol-g-chip--95 i { background: var(--bg3); }
.apex-vol-g-chip--80 i { background: var(--bg5); }
.apex-vol-g-chip--68 i { background: var(--accent-bg); border-color: var(--accent-bd); }

.apex-vol-g-extremo {
  margin: 10px 0 0; font-size: 12px; line-height: 1.55; color: var(--gray);
}
.apex-vol-g-extremo b { color: var(--text); }

/* ── ESCALERA DE PERCENTILES (Contexto) ────────────────────────────
   2026-08-28 · F3 / D6 · reescrito en HTML el 2026-09-01.

   ⚠️ ERA UN SVG. El texto de un SVG con `viewBox` escala con la figura: con
   viewBox de 300, en escritorio (790px) las etiquetas de 8,5px se veían a
   22,4px y la figura pasaba de 92 a 232px de alto; en teléfono, a 8,9px.
   Medido en el navegador. Ahora las marcas son divs en % y el texto es HTML,
   en px de pantalla — se lee igual en cualquier ancho. Misma corrección que
   apex-grafico-banda.php. Cero colores literales. */
.apex-ctx-grafico { margin: 12px 0 4px; }
/* El padding-top reserva la franja de la etiqueta de HOY, que va posicionada
   en absoluto. ⚠️ No se hace con `margin-top` en la pista: ese margen COLAPSA
   hacia el contenedor, así que el `top:0` del absoluto terminaba justo encima
   de la pista y la etiqueta se cruzaba con la línea de hoy. Medido. */
.apex-ctx-g { position: relative; padding-top: 26px; }

/* La etiqueta de HOY, anclada a su posición en el eje. */
.apex-ctx-g-hoy-eti {
  position: absolute; top: 0; transform: translateX(-50%);
  font-family: var(--font-mono); font-size: 11px; font-weight: 700;
  color: var(--accent); white-space: nowrap;
}
/* En los extremos se ancla al borde para no salirse del marco. */
.apex-ctx-g-hoy-eti--izq { left: 0 !important; transform: none; }
.apex-ctx-g-hoy-eti--der { left: auto !important; right: 0; transform: none; }

.apex-ctx-g-pista { position: relative; height: 34px; }
.apex-ctx-g-eje {
  position: absolute; left: 0; right: 0; top: 50%; height: 1px;
  margin-top: -.5px; background: var(--border2);
}
.apex-ctx-g-tick {
  position: absolute; top: 50%; width: 1px; height: 14px; margin: -7px 0 0 -.5px;
  background: var(--gray2);
}
/* La mediana se distingue: es la referencia contra la que se lee "más" o
   "menos", no un escalón más de la escalera. */
.apex-ctx-g-tick--mediana { height: 22px; margin-top: -11px; width: 2px; margin-left: -1px; background: var(--gray); }
/* Hoy, con el acento: es el único dato de la tarjeta que cambia cada día. */
.apex-ctx-g-hoy {
  position: absolute; top: 50%; width: 2px; height: 30px; margin: -15px 0 0 -1px;
  background: var(--accent); border-radius: 1px;
}
.apex-ctx-g-hoy-punto {
  position: absolute; top: 50%; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px;
  background: var(--accent); border-radius: 50%;
  box-shadow: 0 0 0 3px var(--bg2);
}

.apex-ctx-g-etis { position: relative; height: 14px; margin-top: 4px; }
.apex-ctx-g-eti {
  position: absolute; top: 0; transform: translateX(-50%);
  font-family: var(--font-mono); font-size: 10px; color: var(--gray2); white-space: nowrap;
}
.apex-ctx-g-eti--mediana { color: var(--gray); font-weight: 600; }

/* ── ρ POR PERÍODO (Relaciones) ────────────────────────────────────
   2026-08-28 · F3 / D6 · reescrito en HTML el 2026-09-01.

   ⚠️ ERA UN SVG DE LÍNEA. Además del problema de escala de arriba (9px que en
   escritorio se veían a 23,7px), la línea escondía el dato: eran 3 puntos y,
   con correlaciones que suelen ir de 0,85 a 0,95, el trazo salía casi plano y
   los NÚMEROS no estaban en ninguna parte. Ahora cada ventana es una fila con
   su barra en la escala fija −1…+1 y su valor escrito. */
.apex-rel-grafico { margin: 12px 0 4px; }
.apex-rel-g { display: flex; flex-direction: column; gap: 8px; }
.apex-rel-g-fila { display: flex; align-items: center; gap: 10px; }
.apex-rel-g-vent {
  flex: 0 0 34px; text-align: right;
  font-family: var(--font-mono); font-size: 11px; color: var(--gray2);
}
.apex-rel-g-pista {
  position: relative; flex: 1 1 auto; height: 18px;
  background: var(--bg3); border: 1px solid var(--border); border-radius: 4px;
}
/* El cero sí se marca: cruzarlo cambia el SIGNO de la relación, que es un
   salto cualitativo, no una diferencia de grado. */
.apex-rel-g-cero {
  position: absolute; left: 50%; top: -3px; bottom: -3px; width: 1px;
  margin-left: -.5px; background: var(--border2);
}
/* La barra sale del cero hacia ρ: el signo se ve como dirección. */
.apex-rel-g-barra {
  position: absolute; top: 3px; bottom: 3px;
  background: var(--accent-bg); border-radius: 2px;
}
.apex-rel-g-punto {
  position: absolute; top: 50%; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px;
  background: var(--accent); border-radius: 50%;
}
/* La ventana más corta es "dónde estamos hoy": se despega con un halo. */
.apex-rel-g-fila--hoy .apex-rel-g-punto { box-shadow: 0 0 0 3px var(--bg2), 0 0 8px rgba(200,255,0,.4); }
.apex-rel-g-fila--hoy .apex-rel-g-vent { color: var(--text); font-weight: 600; }
.apex-rel-g-val {
  flex: 0 0 46px; text-align: right;
  font-family: var(--font-mono); font-size: 13px; font-weight: 700; color: var(--text);
}
.apex-rel-g-val--vacio { font-size: 10px; font-weight: 400; color: var(--gray2); }
/* Los bordes de ±1 son tenues a propósito: recuerdan que la escala es fija sin
   competir con el dato. */
.apex-rel-g-eje {
  display: flex; justify-content: space-between;
  margin: 2px 46px 0 44px;
  font-family: var(--font-mono); font-size: 10px; color: var(--gray2);
}

/* ── OPERACIONES: MAESTRO–DETALLE · ESTADO POR DEFECTO ─────────────
   2026-08-29 · F3. El panel (#apex-op-detalle) empieza OCULTO con el
   atributo `hidden` del propio HTML — no con una clase — así el default es
   idéntico en los dos anchos sin escribir una regla acá para lograrlo.
   En teléfono, tocar una fila lo revela DEBAJO de la tabla (donde el JS lo
   deja por orden natural del DOM); en escritorio pasa a columna lateral,
   ver apex-flow-desktop.css.

   Las filas ahora son interactivas (antes eran solo texto) — el cursor y el
   foco lo dicen en los dos anchos, no solo en escritorio: tocar una fila
   abre detalle también en el teléfono. */
.apex-an-tabla--operaciones .apex-an-tabla-r { cursor: pointer; }
.apex-an-tabla--operaciones .apex-an-tabla-r:hover,
.apex-an-tabla--operaciones .apex-an-tabla-r:focus-visible {
  background: var(--bg3);
}
.apex-an-tabla--operaciones .apex-an-tabla-r.is-abierta {
  background: var(--accent-bg);
  box-shadow: inset 3px 0 0 var(--accent);
}
.apex-op-d-dir { margin-left: auto; font-family: var(--font-mono); font-size: 11px; color: var(--gray); }
.apex-op-d-fecha { font-size: 12px; color: var(--gray2); margin: -4px 0 10px; }
.apex-op-d-resultado { font-family: var(--font-display); font-size: 26px; font-weight: 800; margin-bottom: 12px; }
/* `.pos`/`.neg` solas (fuera de `.apex-an-tabla-r`) no traen color propio —
   el panel de detalle no vive dentro de la tabla, así que lo declara acá. */
.apex-op-d-resultado.pos { color: var(--apex-pos); }
.apex-op-d-resultado.neg { color: var(--apex-neg); }
.apex-op-detalle-vacio { font-size: 13px; color: var(--gray2); text-align: center; padding: 24px 16px; border: 1px dashed var(--border2); border-radius: var(--radius-lg); }

/* ── NOTICIAS: MAESTRO–DETALLE · ESTADO POR DEFECTO ────────────────
   2026-08-29 · F3. Desde hoy la lista de noticias se renderiza SIEMPRE, también
   cuando hay una nota abierta (`?n=`) — antes era un if/else en PHP.

   En teléfono eso NO debe cambiar nada: se sigue viendo una cosa por vez. Por
   eso, cuando hay ficha, la lista se esconde acá. El envoltorio es
   `display:contents` para que no introduzca una caja nueva en el layout.

   Igual que el menú lateral y el índice de Conceptos: el default vive en la
   hoja BASE, no en la de escritorio. Si apex-flow-desktop.css no llegara al
   servidor, el peor caso es "el escritorio se ve como antes", nunca "el
   teléfono muestra la nota y la lista pegadas una abajo de la otra". */
.apex-md-news { display: contents; }
.apex-md-news--con-ficha .apex-start-noticias { display: none; }

/* ── MAESTRO–DETALLE · ESTADO POR DEFECTO ──────────────────────────
   2026-08-28 · F3. Envoltorio de las pantallas con índice lateral (Conceptos,
   Glosario). El markup se emite en todos los anchos — Regla 1, una sola base —
   y acá se lo neutraliza para el teléfono:

   · `display:contents` en el envoltorio y en el cuerpo: los dos desaparecen
     del layout y sus hijos quedan como hijos directos de .apex-app-content,
     exactamente donde estaban antes de F3. Sin esto, envolver el contenido en
     dos <div> agregaría bloques nuevos y podría mover márgenes — el markup
     cambia, el resultado visual no.
   · El índice, oculto.

   El default vive acá y NO en apex-flow-desktop.css por la misma razón que el
   menú lateral (ver abajo): si el CSS de escritorio no llegara al servidor, el
   peor caso tiene que ser "el escritorio se ve como hoy", nunca "el teléfono
   muestra un índice suelto arriba del contenido". */
.apex-md,
.apex-md-cuerpo { display: contents; }
.apex-md-indice { display: none; }

/* ── MENÚ LATERAL DE ESCRITORIO · ESTADO POR DEFECTO ───────────────
   2026-08-28 · F1. El componente (apex-nav-desktop.php) se dibuja en el HTML
   de TODOS los anchos —Regla 1 del plan: prohibido bifurcar el markup por
   superficie— y es el CSS el que decide si se ve.

   Su estado por defecto es OCULTO, y esa regla vive acá, en la hoja base, no
   en apex-flow-desktop.css. Dos razones, la segunda es la que importa:

   1 · Coherencia: el default de un componente es parte de su definición, no
       del layout ancho que lo enciende.
   2 · ⚠️ SEGURIDAD DE DESPLIEGUE. Si apex-flow-desktop.css no llegara al
       servidor (un scp que falla en silencio — pasó tres veces en este tema),
       con la regla allá el menú aparecería EN EL TELÉFONO como una lista de
       viñetas suelta arriba de la app. Acá, el peor caso es que el escritorio
       siga viéndose como hoy: feo, no roto.

   Esto no es hipotético: pasó al construir F1. Todos los estilos del menú
   quedaron dentro del @media y a 375px se dibujó la lista cruda. Lo cazó la
   comparación contra las capturas de F0 — que es exactamente para lo que ese
   contrato existe. */
.apex-desknav { display: none; }

/* ── SELLO DE ALCANCE ──────────────────────────────────────────────
   2026-08-28 · F1 de la versión de escritorio, pero NO es una mejora de
   escritorio: corrige el producto en los dos anchos, por eso vive acá y no en
   apex-flow-desktop.css.

   EL PROBLEMA QUE ARREGLA (auditoría §1, medido en producción con datos reales):
   "Score de disciplina" dice 60/100 en Resumen y 54/100 en Mente, al mismo
   tiempo y en la misma cuenta. Uno es del período elegido, el otro es de todo
   el historial — y nada en pantalla lo decía. Solo 3 de las 7 secciones del Lab
   tienen selector de período (apex-lab.php:205) y las otras 4 no avisan que
   están mostrando otra ventana de tiempo.

   Sergio, 2026-08-28: "deben estar muy bien diferenciadas a las que no, para que
   no exista confusión en el usuario".

   Un sello por PANTALLA (no por tarjeta — eso es F2). Dos estados, y el que
   corresponde lo decide apex-lab.php a partir de la misma condición que ya
   decide si se dibuja el selector, para que no puedan discrepar. */
/* 2026-09-01 · Volatilidad — la letra chica bajó al pie (ver el comentario en
   apex-start-volatilidad.php). Se separa con una línea para que se lea como
   "notas al pie" y no como más contenido de la ficha. */
.apex-vol-pie-notas {
  margin-top: 22px; padding-top: 18px;
  border-top: 1px solid var(--border);
}
.apex-vol-pie-notas .apex-lab-alcance:last-child { margin-bottom: 0; }
/* El sello de frescura, ya sin su párrafo al lado, no necesita el margen que
   lo separaba de él. */
.apex-vol-sello-solo { margin-bottom: 18px; }

.apex-lab-alcance {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 14px;
  font-family: var(--font-mono);
  font-size: 10px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--gray2);
}
.apex-lab-alcance-eti {
  padding: 3px 8px;
  border: 1px solid var(--border2);
  border-radius: var(--radius);
  color: var(--gray);
}
/* El acento marca "esto NO es la ventana que elegiste arriba" — sirve igual
   para el historial completo que para el "ahora mismo" de En vivo. Por eso el
   modificador se llama `--fuera` y no `--historial`: son dos estados distintos
   con el mismo significado para el ojo. El de período va neutro, porque ahí el
   selector de arriba ya está diciendo qué se mira. */
.apex-lab-alcance--fuera .apex-lab-alcance-eti {
  border-color: var(--accent-bd);
  background: var(--accent-bg);
  color: var(--accent);
}
.apex-lab-alcance-nota { color: var(--gray2); letter-spacing: .04em; text-transform: none; font-size: 11px; }

/* ── Botón flotante "EN VIVO" ──────────────────────────────────────
   Va encima del switch de zona y de la barra inferior, alineado a la
   derecha para no taparlos. Solo existe si hay algo abierto. */
.apex-vivo-fab {
  position: fixed; right: 14px; z-index: 61;
  bottom: calc(var(--apex-nav-h) + var(--apex-subnav-h) + 12px + env(safe-area-inset-bottom, 0px));
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 15px; border-radius: 999px; text-decoration: none;
  background: var(--apex-neg, #ff7a7a); color: #2a0b0b;
  font-family: var(--font-display); font-size: 12px; font-weight: 800;
  letter-spacing: .06em; box-shadow: 0 6px 20px rgba(255, 122, 122, .35);
}
.apex-vivo-fab[hidden] { display: none; }
.apex-vivo-fab-dot { width: 7px; height: 7px; border-radius: 50%; background: #2a0b0b; animation: apexlatir 1.6s ease-in-out infinite; }
@keyframes apexlatir { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
.apex-vivo-fab-n:not(:empty) {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  background: rgba(0, 0, 0, .22); display: inline-flex; align-items: center;
  justify-content: center; font-size: 11px;
}
/* Quien prefiere menos movimiento no debería tener un punto latiendo en pantalla. */
@media (prefers-reduced-motion: reduce) { .apex-vivo-fab-dot { animation: none; } }
@media (max-width: 480px) {
  .apex-vivo-pos .apex-lab-stats { grid-template-columns: 1fr; }
}
.apex-lab-alerts { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.apex-lab-alerts li { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text); }
.apex-lab-alerts .dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 8px; }
.apex-lab-alerts .dot.ok { background: var(--apex-pos); }
.apex-lab-alerts .dot.warn { background: #ffce6b; }

.apex-lab-report-rows { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.apex-lab-report-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px; background: var(--bg3); border: 1px solid var(--border); border-radius: var(--radius-md); font-size: 13px; color: var(--text); }
.apex-lab-report-row > span:first-child { display: inline-flex; align-items: center; gap: 8px; }
.apex-lab-report-row svg { color: var(--gray); }

/* ════════════════════════════════════════════════════════════════
   6.B · PERFORMANCE LAB — sección ANÁLISIS (Fase 7.B, motor cTrader)
   ════════════════════════════════════════════════════════════════ */
.apex-an-kpis { grid-template-columns: 1fr 1fr; }
@media (min-width: 720px) { .apex-an-kpis { grid-template-columns: repeat(4, 1fr); } }
.apex-an-kpis3 { grid-template-columns: repeat(3, 1fr); }

.apex-an-chart { background: var(--bg3); border: 1px solid var(--border); border-radius: var(--radius-md); margin-bottom: 12px; overflow: hidden; }
.apex-an-chart svg { width: 100%; height: 200px; display: block; }
/* Dispersión riesgo/resultado (2026-08-10): viewBox más alto que el resto
   (232 vs 200) para el margen de los ejes — necesita su propia altura fija,
   si no el SVG queda "flotando" con franjas vacías dentro de los 200px del
   resto de los gráficos. */
.apex-an-chart--disp svg { height: 232px; }

/* Puntos del scatter: tocables y con feedback visual claro al seleccionar
   (mobile no tiene hover, así que el feedback tiene que ser post-tap). */
.apex-disp-punto { cursor: pointer; }
.apex-disp-punto.is-on { r: 5.5; opacity: 1; stroke: var(--text); stroke-width: 1.3; }

.apex-disp-detalle {
  display: flex; align-items: center; gap: 9px;
  background: var(--bg3); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 9px 10px; margin-bottom: 10px; font-size: 12.5px;
}
.apex-disp-detalle-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.apex-disp-detalle-txt { flex: 1; color: var(--text); font-family: var(--font-mono); }
.apex-disp-detalle-x {
  background: transparent; border: 0; color: var(--gray2); font-size: 13px;
  cursor: pointer; padding: 2px 5px; line-height: 1; flex: none;
}
.apex-disp-detalle-x:hover { color: var(--text); }

.apex-an-subhead { font-family: var(--font-mono); font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--gray); margin: 16px 0 10px; }

/* Histograma de barras */
.apex-an-hist { display: flex; align-items: flex-end; gap: 4px; height: 110px; padding: 6px 2px 0; background: var(--bg3); border: 1px solid var(--border); border-radius: var(--radius-md); }
.apex-an-hist-col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; min-width: 0; }
.apex-an-hist-bar { width: 70%; border-radius: 3px 3px 0 0; background: var(--gray2); min-height: 0; }
.apex-an-hist-bar.pos { background: var(--apex-pos); }
.apex-an-hist-bar.neg { background: var(--apex-neg); }
.apex-an-hist-lbl { font-family: var(--font-mono); font-size: 8px; color: var(--gray2); padding: 3px 0 4px; white-space: nowrap; }

/* 2026-08-10 · Histograma con cola de outliers (apex_lab_histograma). El
   número queda VISIBLE arriba de las barras altas (≥55% de altura) porque la
   escala en raíz cuadrada comprime a propósito el pico dominante — sin el
   número, se perdería el dato exacto que la compresión existe para no
   esconder. Las columnas de cola (≤ / ≥, todo lo que quedó fuera del rango
   típico) llevan una textura rayada: siguen siendo del mismo color pos/neg,
   pero visualmente distintas de un bin normal — son una suma, no una medida. */
.apex-an-hist-n { font-family: var(--font-mono); font-size: 8.5px; font-weight: 700; color: var(--text); margin-bottom: 2px; line-height: 1; }
.apex-an-hist-col--cola .apex-an-hist-lbl { color: var(--text); font-weight: 600; }
.apex-an-hist-bar--cola { background-image: repeating-linear-gradient(135deg, rgba(255,255,255,.16) 0 3px, transparent 3px 6px); }

/* "Regla" de años bajo P&L por mes (2026-08-10): agrupa las columnas de un
   mismo año con una línea + su etiqueta, en vez de repetir el año en cada
   barra. `flex-grow` (inline, = cantidad de meses de ese año) reparte el
   ancho en la misma proporción que las columnas de arriba, que también usan
   flex:1 — por eso alinea sin tener que calcular píxeles. */
.apex-an-anios { display: flex; margin-top: 4px; }
.apex-an-anio-grupo { flex-shrink: 1; flex-basis: 0; min-width: 0; border-top: 1px solid var(--border); padding-top: 4px; text-align: center; }
.apex-an-anio-lbl { font-family: var(--font-mono); font-size: 9px; color: var(--gray2); letter-spacing: .04em; }

/* Cortes: fila etiqueta + barra + valor */
.apex-an-corte { display: flex; flex-direction: column; gap: 8px; }
.apex-an-corte-row { display: grid; grid-template-columns: minmax(64px, 1fr) auto 2fr minmax(72px, auto); align-items: center; gap: 8px; }
.apex-an-corte-lbl { font-size: 12px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.apex-an-corte-meta { font-family: var(--font-mono); font-size: 9px; color: var(--gray2); white-space: nowrap; }
.apex-an-corte-barwrap { background: var(--bg3); border-radius: 3px; height: 10px; overflow: hidden; }
.apex-an-corte-bar { height: 100%; border-radius: 3px; background: var(--gray2); }
.apex-an-corte-bar.pos { background: var(--apex-pos); }
.apex-an-corte-bar.neg { background: var(--apex-neg); }
/* 2026-09-02 · "sin muestra" (adherencia sin medir, mes con <10 ops): gris, nunca rojo. */
.apex-an-corte-bar.sinmuestra, .apex-an-hist-bar.sinmuestra { background: var(--border2, #2a3038); opacity: .8; }
.apex-an-corte-val { font-family: var(--font-mono); font-size: 11px; font-weight: 600; color: var(--text); text-align: right; white-space: nowrap; }
.apex-an-corte-val.pos { color: var(--apex-pos); }
.apex-an-corte-val.neg { color: var(--apex-neg); }

/* Tabla compacta (costos / operaciones) */
.apex-an-tabla { display: flex; flex-direction: column; border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; }
.apex-an-tabla-h, .apex-an-tabla-r { display: grid; grid-template-columns: 1.4fr .6fr 1fr 1fr 1fr; gap: 6px; padding: 9px 12px; font-size: 12px; align-items: center; }
/* L15 (2026-08-29): la tabla de evolución mensual de Mente pasó a 6 columnas
   (se agregó "Peor op." — la cola). La regla de arriba fija 5 y la comparten
   varias tablas del Lab, así que se sobrescribe SOLO acá en vez de tocarla. */
.apex-an-tabla--evolucion .apex-an-tabla-h,
.apex-an-tabla--evolucion .apex-an-tabla-r { grid-template-columns: 1.2fr .5fr .9fr .9fr .8fr 1fr; }
/* L14 (2026-08-30): "¿Mejorás en cada instrumento?" tiene 7 columnas
   (activo · ops · WR antes/después · P&L antes/después · veredicto). Mismo
   motivo que arriba: la regla base fija 5 y la comparten varias tablas. */
.apex-an-tabla--evolact .apex-an-tabla-h,
.apex-an-tabla--evolact .apex-an-tabla-r { grid-template-columns: 1.1fr .5fr .7fr .7fr 1fr 1fr .9fr; }
/* 2026-09-01 · Movimientos de caja tiene 4 columnas, pero sin esta regla
   heredaba la base de 5 (1.4fr .6fr 1fr 1fr 1fr): el motor de grillas arma
   igual las 5 pistas aunque sobre una sin usar, así que las 4 columnas reales
   vivían apretadas en 4 de esas 5 fracciones — perdían ~1/6 del ancho de la
   fila para nada. Esa columna robada era la razón por la que "Balance
   después" y "Monto" no entraban en una línea y el signo saltaba solo a la
   fila de arriba (ver también el cambio de formato en apex-lab-rendimiento.php).
   Detalle un poco más ancho que Fecha porque a veces trae la nota cruda del
   bróker ("Movimiento #7"), más larga que "12 ene". */
.apex-an-tabla--caja .apex-an-tabla-h,
.apex-an-tabla--caja .apex-an-tabla-r { grid-template-columns: .9fr 1.3fr 1fr 1fr; }
/* Los importes se leen alineados a la derecha — mismo dígito de las unidades
   en la misma columna vertical, fila tras fila. Es lo que pidió Sergio
   ("que los números estén alineados"): antes, al no tener ancho de columna
   propio, un valor corto y uno largo arrancaban del mismo borde izquierdo y
   el ojo tenía que recorrer todo el ancho para compararlos. */
.apex-an-tabla--caja .apex-an-tabla-h > :nth-child(3),
.apex-an-tabla--caja .apex-an-tabla-r > :nth-child(3),
.apex-an-tabla--caja .apex-an-tabla-h > :nth-child(4),
.apex-an-tabla--caja .apex-an-tabla-r > :nth-child(4) { text-align: right; }
.apex-an-tabla-h { background: var(--bg3); font-family: var(--font-mono); font-size: 9px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--gray); }
.apex-an-tabla-r { border-top: 1px solid var(--border); color: var(--text); }
.apex-an-tabla-r .pos { color: var(--apex-pos); }
.apex-an-tabla-r .neg { color: var(--apex-neg); }

/* Tabla ANCHA — sección Activos (2026-08-01).
   8 columnas no entran en un celular de 360px. En vez de achicar la letra hasta
   volverla ilegible, la tabla scrollea DENTRO de su tarjeta: el ancho mínimo
   mantiene las columnas legibles y la página nunca scrollea en horizontal.
   La primera columna (el símbolo) queda fija, que es lo que hace que el scroll
   sea usable: sin ella, al deslizar se pierde de qué activo es cada fila. */
.apex-an-tabla-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.apex-an-tabla--activos { min-width: 560px; }
.apex-an-tabla--activos .apex-an-tabla-h,
.apex-an-tabla--activos .apex-an-tabla-r {
  grid-template-columns: 1.2fr .5fr .6fr 1.1fr .8fr 1fr .8fr .8fr;
}
.apex-an-tabla--activos .apex-an-tabla-h > :first-child,
.apex-an-tabla--activos .apex-an-tabla-r > :first-child { font-weight: 600; }
.apex-an-tabla--activos .apex-an-tabla-r .pos { color: var(--apex-pos); }
.apex-an-tabla--activos .apex-an-tabla-r .neg { color: var(--apex-neg); }

/* Semáforos de reglas */
.apex-an-semaforos { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.apex-an-sem-row { display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: var(--bg3); border: 1px solid var(--border); border-radius: var(--radius-md); }
.apex-an-sem-dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 10px; }
.apex-an-sem-dot.ok { background: var(--apex-pos); }
.apex-an-sem-dot.warn { background: #ffce6b; }
.apex-an-sem-dot.bad { background: var(--apex-neg); }
/* muted = sin dato o muestra insuficiente (F3.0). Un cuarto estado propio: una
   regla que no se pudo juzgar no es un incumplimiento, y pintarla de rojo le
   diría al alumno que falló algo que nunca se midió. */
.apex-an-sem-dot.muted { background: transparent; border: 1px solid var(--gray); }
.apex-an-sem-lbl { font-size: 13px; color: var(--text); text-transform: capitalize; }
.apex-an-sem-pct { margin-left: auto; font-family: var(--font-mono); font-size: 12px; font-weight: 600; color: var(--gray); }
.apex-an-sem-pct small { font-family: var(--font-body, inherit); font-weight: 400; opacity: .7; }

/* Score de disciplina con desglose */
.apex-an-score { display: flex; flex-direction: column; gap: 14px; }
@media (min-width: 640px) { .apex-an-score { flex-direction: row; align-items: center; gap: 22px; } }
.apex-an-score-num { font-family: var(--font-display); font-size: 52px; font-weight: 900; color: var(--accent); line-height: 1; white-space: nowrap; }
.apex-an-score-bars { flex: 1; display: flex; flex-direction: column; gap: 8px; width: 100%; }
.apex-an-score-row { display: grid; grid-template-columns: minmax(120px, 1fr) 2fr auto; align-items: center; gap: 8px; }
.apex-an-score-lbl { font-size: 11px; color: var(--gray); }
.apex-an-score-val { font-family: var(--font-mono); font-size: 10px; color: var(--gray2); white-space: nowrap; }

/* Heatmap hora × día */
.apex-an-heat-scroll { overflow-x: auto; }
.apex-an-heat { border-collapse: collapse; min-width: 100%; }
.apex-an-heat th { font-family: var(--font-mono); font-size: 9px; font-weight: 600; color: var(--gray2); padding: 3px 4px; text-align: center; }
.apex-an-heat td { padding: 2px; text-align: center; }
.apex-an-heat-cell { display: inline-block; width: 22px; height: 18px; border-radius: 3px; }

/* ════════════════════════════════════════════════════════════════
   7 · APEX START — shell público
   ════════════════════════════════════════════════════════════════ */
.apex-start-hero { padding: 14px 0 22px; }
.apex-start-hero-title { font-family: var(--font-display); font-size: clamp(26px, 7vw, 34px); font-weight: 900; color: var(--text); text-transform: uppercase; letter-spacing: .01em; line-height: 1.08; margin: 0 0 12px; }
.apex-start-hero-sub { font-size: 15px; color: var(--gray); line-height: 1.5; margin: 0 0 20px; }
.apex-start-cta {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--accent-t); text-decoration: none;
  font-family: var(--font-display); font-weight: 700; font-size: 14px;
  letter-spacing: .06em; text-transform: uppercase;
  padding: 14px 22px; border-radius: var(--radius-md);
}

.apex-start-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.apex-start-tile {
  display: flex; flex-direction: column; gap: 6px; text-decoration: none;
  background: var(--bg2); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: 16px; transition: border-color .15s, transform .15s;
}
.apex-start-tile:hover { border-color: var(--accent-bd); transform: translateY(-2px); }
.apex-start-tile-ico { display: flex; color: var(--accent); margin-bottom: 4px; }
.apex-start-tile-t { font-family: var(--font-display); font-size: 15px; font-weight: 800; color: var(--text); text-transform: uppercase; letter-spacing: .02em; line-height: 1.1; }
.apex-start-tile-s { font-size: 12px; color: var(--gray); line-height: 1.4; }
.apex-start-tile-accent { background: var(--accent-bg); border-color: var(--accent-bd); }

.apex-start-empty { text-align: center; padding: 40px 16px; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.apex-start-empty-ico { display: flex; align-items: center; justify-content: center; width: 56px; height: 56px; border-radius: var(--radius-lg); background: var(--bg3); border: 1px solid var(--border); color: var(--accent); }
.apex-start-empty-ico svg { width: 24px; height: 24px; }
.apex-start-empty h2 { font-family: var(--font-display); font-size: 22px; font-weight: 800; color: var(--text); text-transform: uppercase; letter-spacing: .02em; margin: 4px 0 0; }
.apex-start-empty p { font-size: 14px; color: var(--gray); line-height: 1.5; max-width: 320px; margin: 0; }
.apex-start-back { font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); text-decoration: none; margin-top: 6px; }

/* ════════════════════════════════════════════════════════════════
   8 · SAFE-AREA — switch de modo en modo standalone (páginas-app)
   En páginas internas el safe-area de .apex-mob-nav ya lo maneja apex-pwa.css.
   ════════════════════════════════════════════════════════════════ */
@media (display-mode: standalone) {
  body.apex-standalone.apex-app .apex-mob-nav { height: calc(var(--apex-nav-h) + env(safe-area-inset-bottom, 0px)); }
}

/* ════════════════════════════════════════════════════════════════
   9 · FASE 7.C — Caja "Conectar / desconectar cuenta cTrader" (Lab + Start)
   El HTML lo genera apex-flow-ctrader-connect.php; estas clases no existían
   en ningún stylesheet del tema (el botón salía como texto plano).
   ════════════════════════════════════════════════════════════════ */
.apex-cc-aviso{margin:0 0 14px;padding:12px 16px;border-radius:var(--radius-md);font-size:13px;line-height:1.5;background:var(--bg3);border:1px solid var(--border);color:var(--text)}
.apex-cc-aviso--ok{border-color:rgba(46,204,113,.45)}
.apex-cc-aviso--warn{border-color:rgba(245,158,11,.45)}
.apex-ctrader-connect{display:flex;align-items:center;gap:14px;flex-wrap:wrap;background:var(--bg3);border:1px solid var(--border2);border-radius:var(--radius-md);padding:14px 18px;margin:0 0 18px}
.apex-ctrader-connect--ok{border-color:rgba(46,204,113,.4)}
/* 2026-08-08: antes esto no existía porque el estado 'error' no existía —
   ver apex-ctrader-webhook.php y apex-flow-ctrader-connect.php. */
.apex-ctrader-connect--error{border-color:rgba(255,95,107,.4)}
.apex-cc-dot{flex:0 0 auto;width:10px;height:10px;border-radius:50%;background:#2ecc71;box-shadow:0 0 8px rgba(46,204,113,.6)}
.apex-cc-txt{flex:1 1 240px;display:flex;flex-direction:column;gap:3px}
.apex-cc-txt strong{font-size:14px;color:var(--text)}
.apex-cc-txt span{font-size:12px;color:var(--text-dim,#8a9fa8);line-height:1.5}
.apex-cc-btn{flex:0 0 auto;display:inline-flex;align-items:center;font-family:var(--font-display);font-size:13px;font-weight:800;letter-spacing:.03em;text-transform:uppercase;padding:11px 20px;border-radius:var(--radius-md);text-decoration:none;background:var(--accent);color:var(--accent-t);transition:filter .15s}
.apex-cc-btn:hover{filter:brightness(1.08)}
.apex-cc-btn--out{background:transparent;color:var(--text);border:1px solid var(--border2)}
.apex-cc-btn--out:hover{border-color:#ef4444;color:#ef4444;filter:none}

/* ── Cabecera compacta del Lab (2026-07-25) ─────────────────────────────────
   Pedido de Sergio desde el celular: el bloque de "tu cuenta está conectada"
   ocupaba tres renglones para no decir lo único que importa —QUÉ cuenta y si es
   dinero real—. Ahora: estado con la luz verde arriba a la derecha, y debajo el
   número de cuenta, el bróker y REAL/DEMO. Dos renglones, alineados a la
   derecha, con el ancho de una línea de texto en vez de una tarjeta entera. */
.apex-cc-mini{display:flex;flex-direction:column;align-items:flex-end;gap:2px;padding:8px 14px;margin:0 0 12px}
.apex-cc-mini-estado{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;color:var(--text)}
.apex-cc-mini-datos{font-family:var(--font-mono);font-size:12px;color:var(--text-dim,#8a9fa8);letter-spacing:.02em}
/* 2026-08-08 · multi-cuenta — enlace a "Mis cuentas" desde la cabecera compacta. */
.apex-cc-mini-link{font-size:11.5px;color:var(--accent);text-decoration:none}
.apex-cc-mini-link:hover{text-decoration:underline}
.apex-cc-solo-lectura{font-size:11px;color:var(--text-dim,#8a9fa8);font-weight:400;letter-spacing:.01em}
/* Ojo mostrar/ocultar el número de cuenta (2026-08-02, pedido de Sergio).
   Por defecto OCULTO: el alumno puede mostrar sus parámetros y su bróker en
   vivo —que se vea que la cuenta es real— sin exponer su número. El estado
   "ver" lo pone el JS en el wrapper; sin JS queda oculto, que es el lado
   seguro del fallo. */
.apex-cc-num-wrap{display:inline-flex;align-items:center;gap:6px}
.apex-cc-num-visible{display:none}
.apex-cc-num-wrap.apex-cc-num--ver .apex-cc-num-oculto{display:none}
.apex-cc-num-wrap.apex-cc-num--ver .apex-cc-num-visible{display:inline}
.apex-cc-ojo{display:inline-flex;align-items:center;justify-content:center;padding:3px;margin:0;background:none;border:0;border-radius:5px;color:var(--text-dim,#8a9fa8);cursor:pointer;line-height:0;transition:color .15s,background .15s}
.apex-cc-ojo:hover{color:var(--text);background:rgba(255,255,255,.06)}
.apex-cc-ojo:focus-visible{outline:2px solid var(--accent,#C8FF00);outline-offset:1px}
.apex-cc-ojo .apex-cc-ojo-on{display:none}
.apex-cc-num-wrap.apex-cc-num--ver .apex-cc-ojo .apex-cc-ojo-off{display:none}
.apex-cc-num-wrap.apex-cc-num--ver .apex-cc-ojo .apex-cc-ojo-on{display:inline}
/* REAL en verde y DEMO en ámbar: el alumno tiene que poder distinguirlos de un
   vistazo, sin leer. Si el motor no sabe cuál es, no se dibuja ninguno. */
.apex-cc-tipo--real{color:#2ecc71}
.apex-cc-tipo--demo{color:#ffb020}
/* Desconectar, al pie: acción destructiva, lejos del contenido y del pulgar. */
.apex-cc-pie{display:flex;flex-direction:column;align-items:center;gap:8px;margin:26px 0 6px;padding-top:18px;border-top:1px solid var(--border)}
.apex-cc-pie .apex-cc-btn--out{font-size:12px;padding:9px 18px}
.apex-cc-pie-nota{font-size:11.5px;color:var(--text-dim,#8a9fa8);text-align:center;max-width:340px;line-height:1.45}

/* Link inline dentro de un .apex-lab-muestra (p.ej. "Definir mis reglas" /
   "Ver o cambiar" del enganche con la sección Reglas, F3.9). */
.apex-lab-link{color:var(--accent);text-decoration:underline}
.apex-lab-link:hover{color:var(--text)}

/* ════════════════════════════════════════════════════════════════
   10 · PANTALLA DE REGLAS (F3.9, 2026-08-01)
   Declarar reglas propias: acordeones inline, interruptor por regla,
   tarjeta de preset y barra fija de guardado. Reusa .apex-lab-card /
   .apex-lab-card-head / .apex-lab-muestra / .apex-lab-locked tal cual
   (§8 del diseño). `.apex-soon-sheet` (sección 3 de este archivo) es una
   hoja fija de "Próximamente" para una sola acción, no un acordeón
   inline — las clases de acá calcan su tono visual (fondo, borde,
   radios), no su marcado, tal como pide el diseño.
   ════════════════════════════════════════════════════════════════ */

.apex-rg-empty-cta{display:flex;flex-wrap:wrap;gap:10px;margin-top:14px}
.apex-rg-empty-cta .flow-btn{flex:1 1 auto;justify-content:center}

.apex-rg-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.apex-rg-chip{font-family:var(--font-mono);font-size:10.5px;font-weight:600;color:var(--text);background:var(--bg3);border:1px solid var(--border);border-radius:999px;padding:5px 10px}

.apex-rg-linkbtn{background:none;border:none;padding:0;cursor:pointer;color:var(--accent);font-family:var(--font-mono);font-size:11px;font-weight:600;text-decoration:underline;letter-spacing:.02em}
.apex-rg-linkbtn:hover{color:var(--text)}

/* Tarjeta de preset */
.apex-rg-preset-txt{font-size:13px;color:var(--gray);line-height:1.5;margin:0 0 14px}
.apex-rg-preset-txt strong{color:var(--text)}

/* Acordeones: Lo esencial · las 5 familias · Todavía no las medimos */
.apex-rg-accordions{display:flex;flex-direction:column;gap:10px;margin-bottom:14px}
.apex-rg-accordion{background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden}
.apex-rg-acc-head{width:100%;display:flex;align-items:center;gap:10px;background:none;border:none;cursor:pointer;text-align:left;padding:14px 16px;color:var(--text)}
.apex-rg-acc-title{font-family:var(--font-display);font-size:13px;font-weight:800;text-transform:uppercase;letter-spacing:.03em}
.apex-rg-acc-count{margin-left:auto;font-family:var(--font-mono);font-size:10.5px;color:var(--gray2);white-space:nowrap}
.apex-rg-acc-chev{width:8px;height:8px;flex:0 0 8px;border-right:2px solid var(--gray2);border-bottom:2px solid var(--gray2);transform:rotate(45deg);transition:transform .18s ease}
.apex-rg-accordion.is-open .apex-rg-acc-chev{transform:rotate(-135deg)}
.apex-rg-accordion:not(.is-open) .apex-rg-acc-count{display:none}
.apex-rg-acc-body{display:none;padding:0 16px 16px}
.apex-rg-accordion.is-open .apex-rg-acc-body{display:block}

/* Fila de una regla */
.apex-rg-fila{display:flex;gap:12px;padding:12px 0;border-top:1px solid var(--border)}
.apex-rg-accordion .apex-rg-fila:first-of-type{border-top:none}
.apex-rg-fila-main{flex:1;min-width:0}
.apex-rg-fila-head{display:flex;align-items:center;gap:8px}
.apex-rg-fila-lbl{font-size:13.5px;font-weight:600;color:var(--text)}
.apex-rg-help{flex:0 0 auto;width:18px;height:18px;border-radius:50%;border:1px solid var(--border2);background:none;color:var(--gray2);font-family:var(--font-mono);font-size:10px;cursor:pointer;line-height:1}
.apex-rg-help:hover{color:var(--accent);border-color:var(--accent-bd)}
.apex-rg-ayuda{margin:6px 0 0;font-size:12px;color:var(--gray2);line-height:1.5}
.apex-rg-ayuda[hidden]{display:none}
.apex-rg-nota-fija{margin:6px 0 0;font-size:12px;color:var(--gray);font-style:italic;line-height:1.5}
.apex-rg-motivo{margin:6px 0 0;font-size:11px;color:var(--gray2)}
.apex-rg-error{margin:6px 0 0;font-size:11.5px;color:var(--apex-neg,#ff7a7a)}
.apex-rg-error[hidden]{display:none}

/* Interruptor — mismo lenguaje visual que .toggle de apex-perfil.css, pero
   propio: esa hoja no se carga en las páginas-app (Lab/Start). */
.apex-rg-switch{flex:0 0 auto;width:38px;height:22px;border-radius:999px;background:var(--bg4);border:1px solid var(--border2);position:relative;cursor:pointer;padding:0;transition:background .2s,border-color .2s;align-self:flex-start;margin-top:2px}
.apex-rg-switch.on{background:var(--accent);border-color:var(--accent)}
.apex-rg-switch-knob{position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:#fff;transition:transform .2s}
.apex-rg-switch.on .apex-rg-switch-knob{transform:translateX(16px);background:var(--accent-t)}

/* Control (aparece solo con la regla encendida) */
.apex-rg-control{display:flex;align-items:center;gap:8px;margin-top:10px;flex-wrap:wrap}
.apex-rg-control[hidden]{display:none}
.apex-rg-input{background:var(--bg3);border:1px solid var(--border2);border-radius:var(--radius);color:var(--text);font-family:var(--font-body,inherit);font-size:13px;padding:9px 11px;min-width:0}
input.apex-rg-input[type="number"]{width:90px}
select.apex-rg-input{flex:1 1 auto}
.apex-rg-textarea{width:100%;min-height:64px;resize:vertical;font-family:inherit}
.apex-rg-unidad{font-family:var(--font-mono);font-size:11px;color:var(--gray2)}
.apex-rg-checks{display:flex;flex-wrap:wrap;gap:8px}
.apex-rg-check{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--text)}

/* "Antes de guardar" — zona horaria + nota */
.apex-rg-zona{font-size:13px;color:var(--gray);line-height:1.6;margin:0 0 14px}
.apex-rg-zona strong{color:var(--text)}
.apex-rg-nota-label{display:block;font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--gray);margin-bottom:6px}

/* Historial (Zona 3, solo lectura) */
.apex-rg-hist-item{display:flex;gap:10px;padding:12px 0;border-top:1px solid var(--border)}
.apex-rg-historial .apex-rg-hist-item:first-of-type{border-top:none}
.apex-rg-hist-dot{flex:0 0 8px;width:8px;height:8px;border-radius:50%;background:var(--gray2);margin-top:5px}
.apex-rg-hist-item.is-activa .apex-rg-hist-dot{background:var(--accent)}
.apex-rg-hist-item.is-futura .apex-rg-hist-dot{background:transparent;border:1px solid var(--accent)}
.apex-rg-hist-fecha{font-size:12.5px;font-weight:600;color:var(--text);display:flex;align-items:center;flex-wrap:wrap;gap:8px}
.apex-rg-hist-tag{font-family:var(--font-mono);font-size:9px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--accent);background:var(--accent-bg);border:1px solid var(--accent-bd);border-radius:var(--radius);padding:2px 7px}
.apex-rg-hist-chips{margin:4px 0 0;font-size:12px;color:var(--gray2)}
.apex-rg-hist-nota{margin:4px 0 0;font-size:12px;color:var(--gray);font-style:italic}

/* Barra fija de guardado — aparece solo con cambios sin guardar, apoyada
   justo arriba de la barra inferior (mismo criterio que .apex-modeswitch). */
.apex-rg-savebar{position:fixed;left:50%;bottom:var(--apex-nav-h);transform:translateX(-50%);width:100%;max-width:var(--apex-shell-max);z-index:55;background:var(--bg-deeper);border-top:1px solid var(--border2);padding:12px 16px;box-shadow:0 -8px 24px rgba(0,0,0,.35)}
.apex-rg-savebar[hidden]{display:none}
.apex-rg-savebar-banner{margin:0 0 10px;font-size:11.5px;color:var(--gray2);line-height:1.5}
.apex-rg-savebar-btn{width:100%;justify-content:center}

/* Toast propio de la pantalla (el de apex-perfil.php vive en un script que
   no se carga en las páginas-app). */
.apex-rg-toast{position:fixed;left:50%;bottom:calc(var(--apex-nav-h) + 90px);transform:translateX(-50%);z-index:70;max-width:calc(100vw - 32px);background:var(--bg-deeper);border:1px solid var(--accent-bd);border-radius:var(--radius-md);color:var(--text);font-size:12.5px;padding:10px 16px;box-shadow:0 8px 24px rgba(0,0,0,.4)}
.apex-rg-toast[hidden]{display:none}
.apex-rg-toast.is-error{border-color:rgba(255,122,122,.5);color:#ffb3b3}

/* ── Aviso de versión nueva del Service Worker (2026-08-15) ──────────────
   Vive en TODAS las páginas (wp_footer, no una plantilla puntual) — por eso
   se resuelve acá, en la hoja base que carga siempre, y no con .flow-btn
   (css/apex-flow.css, que solo se encola en algunas plantillas). Reusa
   .apex-rg-toast tal cual para el cuerpo del aviso; solo agrega el botón,
   que ese componente no tenía. */
/* ⚠️ ARREGLADO 2026-08-16, visto en pantalla y no en el código: el toast
   heredaba de .apex-rg-toast un `max-width` pero NINGÚN ancho propio, así que
   se encogía al contenido. Con el botón adentro (que no se comprime), al
   <span> del texto le quedaban 45px de 188 y "Hay una versión nueva de APEX
   Flow." se partía en seis líneas de una o dos palabras. El aviso funcionaba
   —aparecía y el botón actualizaba— pero se veía roto, y aparece en CADA
   despliegue. */
.apex-sw-toast {
  display: flex; align-items: center; gap: 12px; z-index: 80;
  width: min(92vw, 420px);
}
.apex-sw-toast > span { flex: 1 1 auto; line-height: 1.4; }
.apex-sw-toast .apex-sw-toast-btn { flex: 0 0 auto; }
.apex-sw-toast-btn {
  flex: 0 0 auto; font-family: var(--font-display); font-size: 11px; font-weight: 800;
  letter-spacing: .04em; text-transform: uppercase; color: var(--accent-t);
  background: var(--accent); border: none; border-radius: var(--radius); cursor: pointer;
  padding: 8px 14px; white-space: nowrap;
}
.apex-sw-toast-btn:disabled { opacity: .6; cursor: default; }

/* ════════════════════════════════════════════════════════════════
   11 · ONBOARDING DE REGLAS (F3.10, 2026-08-01)
   Wizard modal de 4 pasos al primer ingreso al Lab siendo Pro, más la
   tarjeta persistente para quien lo saltea.

   `.apex-soon-overlay` / `.apex-soon-sheet` (sección 3) son la referencia
   de TONO — mismo fondo velado con blur, mismos radios, mismo lenguaje de
   tipografía. Pero esto es un modal CENTRADO, no una hoja que sube desde
   abajo: no hereda su `position:fixed; bottom:0` ni el `translateY(110%)`
   de entrada, y el overlay de acá SÍ es un flex container (la hoja no lo
   necesitaba porque se posicionaba sola).

   La tarjeta no tiene clases propias de color a propósito: es una
   `.apex-lab-card` normal, no un banner de alerta (§4 del diseño).
   ════════════════════════════════════════════════════════════════ */

/* Mientras el wizard está abierto, el Lab de atrás no scrollea. */
html.apex-onb-abierto, html.apex-onb-abierto body{overflow:hidden}

.apex-onb-overlay{
  position:fixed;inset:0;z-index:1000;
  display:flex;align-items:center;justify-content:center;
  padding:16px;
  background:rgba(6,15,20,.72);backdrop-filter:blur(3px);
}
.apex-onb-overlay[hidden]{display:none}

.apex-onb-modal{
  width:min(440px,100%);max-height:calc(100vh - 32px);overflow-y:auto;
  background:var(--bg2);border:1px solid var(--border2);border-radius:var(--radius-lg);
  padding:14px 22px calc(22px + env(safe-area-inset-bottom,0px));
  box-shadow:0 18px 48px rgba(0,0,0,.5);
}

/* Fila superior: progreso a la izquierda, cerrar a la derecha. Se renderiza
   en TODAS las pantallas para que la X no se mueva de lugar. */
.apex-onb-top{display:flex;align-items:center;gap:12px;margin-bottom:18px}
.apex-onb-dots{display:flex;align-items:center;gap:7px}
.apex-onb-dot{width:8px;height:8px;border-radius:50%;background:transparent;border:1px solid var(--border2);transition:background .18s,border-color .18s}
.apex-onb-dot.is-on{background:var(--accent);border-color:var(--accent)}
.apex-onb-x{
  margin-left:auto;flex:0 0 auto;width:30px;height:30px;line-height:1;
  background:none;border:1px solid var(--border);border-radius:var(--radius);
  color:var(--gray2);font-size:19px;cursor:pointer;
}
.apex-onb-x:hover{color:var(--text);border-color:var(--border2)}

/* Una pantalla por vez: bienvenida · los 4 pasos · pantalla final. */
.apex-onb-pantalla{display:none}
.apex-onb-pantalla.is-activa{display:block}

.apex-onb-kicker{margin:0 0 6px;font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--gray2)}
.apex-onb-title{font-family:var(--font-display);font-size:19px;font-weight:800;color:var(--text);line-height:1.25;margin:0 0 12px}
.apex-onb-texto{font-size:13.5px;color:var(--gray);line-height:1.6;margin:0 0 14px}
.apex-onb-texto strong{color:var(--text)}

/* El campo del paso: número grande, unidad al lado. */
.apex-onb-campo{display:flex;align-items:center;gap:10px;margin:18px 0 10px}
.apex-onb-input{
  width:130px;background:var(--bg3);border:1px solid var(--border2);border-radius:var(--radius-md);
  color:var(--text);font-family:var(--font-display);font-size:26px;font-weight:800;
  padding:10px 14px;text-align:center;
}
.apex-onb-input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-bg)}
.apex-onb-input.is-error{border-color:rgba(255,122,122,.6)}
.apex-onb-unidad{font-family:var(--font-mono);font-size:15px;font-weight:600;color:var(--gray2)}

.apex-onb-porque{margin:0;font-size:12.5px;color:var(--gray2);line-height:1.55}
.apex-onb-error{margin:0 0 8px;font-size:12px;color:#ff7a7a;line-height:1.5}
.apex-onb-error[hidden]{display:none}
.apex-onb-aviso{margin:14px 0 0;font-size:12px;color:#ffb3b3;line-height:1.5;text-align:center}
.apex-onb-aviso[hidden]{display:none}

/* Acciones: el botón principal abajo, ancho completo; los secundarios arriba,
   como link, en el orden del mockup (§3). */
.apex-onb-acciones{display:flex;flex-direction:column;gap:12px;margin-top:22px}
.apex-onb-secundarias{display:flex;align-items:center;justify-content:flex-end;gap:16px;min-height:16px}
.apex-onb-btn{width:100%;justify-content:center;text-align:center}
.apex-onb-linkbtn{background:none;border:none;padding:0;cursor:pointer;color:var(--gray2);font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.02em;text-decoration:underline}
.apex-onb-linkbtn:hover{color:var(--text)}

/* Tarjeta persistente: sin color de alerta a propósito. Solo el botón,
   que en una .apex-lab-card no debe estirarse a todo el ancho. */
.apex-onb-tarjeta-btn{margin-top:14px;display:inline-flex}

@media (max-width:380px){
  .apex-onb-modal{padding:12px 16px calc(18px + env(safe-area-inset-bottom,0px))}
  .apex-onb-title{font-size:17px}
  .apex-onb-input{width:110px;font-size:22px}
}

/* ════════════════════════════════════════════════════════════════
   9 · VERSIÓN DE LA APP — banner de actualización + badge + novedades
   (2026-08-02, pedido de Sergio)

   El banner va ARRIBA a propósito: la zona de abajo (modeswitch + barra +
   FAB "En vivo") ya está apretada — es justo el problema que Sergio señaló
   con el aviso del navegador. Poniendo esto arriba, estructuralmente no
   puede volver a chocar con nada de lo de abajo.
   ════════════════════════════════════════════════════════════════ */
.apex-ver-banner {
  position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
  transform: translateY(-110%); transition: transform .3s cubic-bezier(.22, 1, .36, 1);
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: calc(12px + env(safe-area-inset-top, 0px)) 16px 12px;
  background: var(--bg-deeper); border-bottom: 1px solid var(--accent-bd);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .4);
}
.apex-ver-banner.visible { transform: translateY(0); }
.apex-ver-banner-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.apex-ver-banner-txt strong {
  font-family: var(--font-display); font-size: 13px; font-weight: 800;
  color: var(--accent); letter-spacing: .01em;
}
.apex-ver-banner-txt span {
  font-family: var(--font-body, 'Barlow', sans-serif); font-size: 12.5px; color: var(--gray);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.apex-ver-banner-acciones { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.apex-ver-banner-btn {
  font-family: var(--font-mono); font-size: 11px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; background: var(--accent);
  color: var(--accent-t); border: 0; padding: 9px 16px; border-radius: 999px;
  cursor: pointer; white-space: nowrap;
}
.apex-ver-banner-x {
  background: none; border: none; color: var(--gray2); font-size: 22px;
  line-height: 1; cursor: pointer; padding: 4px 6px;
}
.apex-ver-banner-x:hover { color: var(--text); }
@media (max-width: 420px) {
  .apex-ver-banner-txt span { display: none; } /* en pantallas chicas, solo el número — el resumen está a un toque en la hoja de novedades */
}

/* ── Badge de versión (pie de Start→Inicio y Lab→Resumen) ── */
.apex-ver-badge {
  display: block; width: 100%; margin: 10px 0 0; padding: 0;
  background: none; border: none; cursor: pointer;
  font-family: var(--font-mono); font-size: 10.5px; color: var(--gray2);
  text-align: center; letter-spacing: .04em;
}
.apex-ver-badge:hover { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }

/* ── Hoja "Novedades" (reusa .apex-fb-overlay/.apex-fb-sheet como base) ── */
.apex-ver-list { display: flex; flex-direction: column; gap: 16px; margin-top: 4px; }
.apex-ver-item { padding-bottom: 14px; border-bottom: 1px solid var(--border); }
.apex-ver-item:last-child { border-bottom: none; padding-bottom: 0; }
.apex-ver-item-top { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; flex-wrap: wrap; }
.apex-ver-num { font-family: var(--font-display); font-size: 14px; font-weight: 800; color: var(--text); }
.apex-ver-item--actual .apex-ver-num { color: var(--accent); }
.apex-ver-tag {
  font-family: var(--font-mono); font-size: 8.5px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; padding: 2px 7px; border-radius: 999px;
  background: var(--accent-bg); color: var(--accent); border: 1px solid var(--accent-bd);
}
.apex-ver-fecha { font-family: var(--font-mono); font-size: 10px; color: var(--gray2); margin-left: auto; }
.apex-ver-resumen { font-family: var(--font-body, 'Barlow', sans-serif); font-size: 13px; color: var(--gray); line-height: 1.5; margin: 0; }

/* ── Cambios categorizados (2026-08-14): nuevo / mejora / arreglo ──
   Reemplaza a .apex-ver-resumen SOLO en las entradas que traen `cambios` —
   las viejas siguen mostrando el párrafo de siempre (ver apex-version.php). */
.apex-ver-cambios { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.apex-ver-cambio { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.apex-ver-cambio-tag {
  font-family: var(--font-mono); font-size: 9.5px; font-weight: 700; letter-spacing: .03em;
  color: var(--gray2); white-space: nowrap; flex: 0 0 auto;
}
.apex-ver-cambio-texto {
  font-family: var(--font-body, 'Barlow', sans-serif); font-size: 13px; color: var(--gray);
  line-height: 1.5; flex: 1 1 160px; min-width: 0;
}

/* ── Chips de conteo en el banner flotante — solo si la entrada trae `cambios` ── */
.apex-ver-banner-chips { display: flex; gap: 6px; margin-top: 1px; }
.apex-ver-banner-chip {
  font-family: var(--font-mono); font-size: 10px; font-weight: 700;
  color: var(--gray2); white-space: nowrap;
}
@media (max-width: 420px) {
  .apex-ver-banner-chips { display: none; } /* mismo criterio que .apex-ver-banner-txt span: en pantallas chicas, solo el número */
}

/* ══ SUB-NAVEGACIÓN DE PESTAÑA (2026-08-09) ════════════════════════════════
   La tira de fichas de Mercado, Aprende y Mi operativa. Un solo componente
   (apex-subnav.php) para las tres: antes solo Aprende tenía una, escrita a mano
   dentro de apex-start.php.

   QUÉ SE ARREGLÓ ACÁ, y se vio en el teléfono y no en el CSS: la tira de Aprende
   scrolleaba, pero la última ficha ("Glosario") quedaba cortada a la mitad y se
   leía "GLOS" — indistinguible de un texto roto. Ahora:
     · una máscara de degradado a la derecha dice "hay más" sin cortar palabras;
     · scroll-snap para que las fichas queden alineadas al soltar;
     · la barra de scroll nativa se oculta (en un teléfono no aporta y roba 4px);
     · el JS del componente trae la ficha activa a la vista al cargar.
   El área tocable no baja de 36px de alto en ningún ancho. */
.apex-subnav {
  /* ── FICHAS FIJAS, Y ABAJO (2026-08-09, dos pedidos de Sergio) ────────────
     Primero pidió que no desaparecieran al scrollear; después, mirándolo en el
     teléfono: *"las fichas deberían estar abajo también, por comodidad de uso
     del teléfono. O sea, la parte de más abajo las 4 áreas y de ahí cada área
     su sección."*

     Tiene razón, y es ergonomía y no gusto: en un teléfono el pulgar alcanza
     cómodo el tercio inferior, y el borde superior es la zona más incómoda de
     toda la pantalla. Con la navegación primaria abajo y la secundaria arriba,
     cambiar de sección obligaba a cruzar la pantalla entera. Ahora las dos
     capas quedan juntas y en orden de jerarquía, leídas de abajo hacia arriba:

         ┌─────────────────────────────┐
         │  contenido                  │
         ├─────────────────────────────┤
         │  Resumen · En vivo · Riesgo │  ← la sección, dentro del área
         ├─────────────────────────────┤
         │  Mercado · Mi operativa · …  │  ← el área
         └─────────────────────────────┘

     `fixed` y no `sticky`: pegada al fondo del viewport, no al final del
     contenido. Funciona porque ningún ancestro crea contexto de posicionamiento
     — es la misma cadena de la que ya cuelga `.apex-mob-nav`.
     El ancho copia el del shell (--apex-shell-max, centrado) para que en tablet
     no quede una tira de borde a borde bajo una app angosta. */
  position: fixed;
  left: 50%; transform: translateX(-50%);
  width: 100%; max-width: var(--apex-shell-max);
  bottom: calc(var(--apex-nav-h) + env(safe-area-inset-bottom, 0px));
  height: var(--apex-subnav-h);
  z-index: 49;                 /* debajo de la barra (50), encima del contenido */
  display: flex; align-items: center;
  margin: 0; padding: 0 16px;
  background: var(--bg-deeper, rgba(10, 30, 38, .97));
  border-top: 1px solid var(--border);
}
.apex-subnav-track {
  display: flex; gap: 8px;
  overflow-x: auto; padding-bottom: 2px;
  /* La máscara va acá y NO en el contenedor: en el contenedor volvía
     semitransparente el fondo de la barra fija, y el contenido que scrollea por
     debajo se veía a través del degradado. Sobre el track funciona igual de
     bien —la máscara se aplica al border-box, que no se mueve al scrollear— y
     el fondo opaco queda intacto. */
  -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 28px), transparent 100%);
          mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 28px), transparent 100%);
  scroll-snap-type: x proximity;
  scrollbar-width: none;              /* Firefox */
  -ms-overflow-style: none;           /* Edge viejo */
  -webkit-overflow-scrolling: touch;
}
.apex-subnav-track::-webkit-scrollbar { display: none; }
.apex-subnav-item {
  flex: 0 0 auto; scroll-snap-align: start;
  display: inline-flex; align-items: center; min-height: 36px;
  font-family: var(--font-mono); font-size: 11px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--gray);
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 7px 13px; white-space: nowrap;
  text-decoration: none; transition: color .15s, border-color .15s;
}
.apex-subnav-item:hover { color: var(--text); border-color: var(--border2); }
.apex-subnav-item.active {
  color: var(--accent-t); background: var(--accent); border-color: var(--accent);
}
/* La última ficha necesita aire propio: sin esto el padding del contenedor la
   deja pegada al borde justo donde empieza la máscara. */
.apex-subnav-track::after { content: ''; flex: 0 0 12px; }

/* Contador de la ficha "En vivo" (2026-08-09). Lo llena el sondeo que ya hace
   el botón flotante del Lab — ver apex-lab.php. Empieza `hidden`: sin
   operaciones abiertas no se pinta nada, en vez de un "0" que es ruido. */
.apex-subnav-n {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 16px; height: 16px; margin-left: 6px; padding: 0 4px;
  border-radius: 8px; background: var(--accent); color: var(--accent-t);
  font-size: 9px; font-weight: 800; line-height: 1;
}
.apex-subnav-n[hidden] { display: none; }
/* En la ficha encendida el fondo YA es el acento: el contador se invierte para
   no desaparecer sobre sí mismo. */
.apex-subnav-item.active .apex-subnav-n { background: var(--accent-t); color: var(--accent); }

/* ════════════════════════════════════════════════════════════════════════
   Mercado → Contexto (F1, 2026-08-15)
   Diseño: 05_WEB/2026-08-14_modelo_mercado_contexto_v01.md
   ════════════════════════════════════════════════════════════════════════ */

/* ── Selector de activo por CATEGORÍA (2026-08-15 v2 — la v1 fue un <select>
   nativo con <optgroup>; Sergio la probó en el celular y pidió otra cosa: los
   5 botones de categoría SIEMPRE visibles —"los activos van a seguir
   creciendo"— con el panel de activos de la categoría elegida desplegándose
   debajo. Los botones de categoría reusan .apex-ctx-chip/--activo tal cual:
   es LA MISMA idea visual que ya existía para el activo elegido, solo un
   nivel arriba. */
.apex-ctx-cat-selector {
  display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px;
}
.apex-ctx-cat-btn { cursor: pointer; }

/* "Viendo: X" (2026-08-15) — el único indicador fijo de qué activo está
   eligiendo la ficha con los paneles cerrados. Lima porque es EL MISMO
   significado que ya tiene ese color en toda la ficha ("esto es lo
   elegido"), no un acento nuevo que aprender. */
.apex-ctx-viendo {
  font-family: var(--font-mono); font-size: 12px; font-weight: 700;
  letter-spacing: .02em; color: var(--accent); margin: 0 0 10px;
}

/* El panel se anima con la técnica grid-template-rows 0fr→1fr: a diferencia
   de max-height, no hay que adivinar una altura — funciona con cualquier
   cantidad de chips. Un solo panel abierto a la vez (acordeón): abrir Forex
   cierra Índices, no las apila una debajo de la otra. */
.apex-ctx-cat-panel {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .25s ease;
}
.apex-ctx-cat-panel--abierta { grid-template-rows: 1fr; margin-bottom: 10px; }
.apex-ctx-cat-panel-inner { overflow: hidden; min-height: 0; }

/* Lista VERTICAL de activos dentro del panel — a diferencia de
   .apex-ctx-selector (fila horizontal con scroll, la de categorías y la de
   ventana histórica), acá cada activo ocupa su propia línea, ancho completo:
   pedido explícito de Sergio, "no que aparezca en una línea horizontal". Los
   chips siguen siendo los mismos (.apex-ctx-chip/--activo) — cambia el
   acomodo del contenedor, no la pieza. */
/* ⚠️ REDISEÑADA 2026-08-15 — la v1 reusaba .apex-ctx-chip (píldora lima
   sólida) a ancho completo, y en la lista vertical se veían como "botones
   grandes que cubren toda la pantalla" (palabras de Sergio). Referencia que
   dio: el look compacto que ya tenía la fila horizontal original, "un fondo
   como otras apps de selección" — es decir, una LISTA agrupada con un fondo
   compartido (como un picker de iOS/Android), no una pila de botones lima
   independientes. Se abandona .apex-ctx-chip acá adentro a propósito: ya no
   es la pieza correcta para este contexto. */
.apex-ctx-cat-activos {
  display: flex; flex-direction: column;
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: var(--radius-md); overflow: hidden; margin-top: 2px;
}
.apex-ctx-cat-activo {
  display: block; width: 100%; box-sizing: border-box; text-align: left;
  font-family: var(--font-mono); font-size: 13px; color: var(--text);
  background: transparent; border: none; border-bottom: 1px solid var(--border);
  border-left: 3px solid transparent;
  padding: 11px 14px; text-decoration: none; cursor: pointer;
}
.apex-ctx-cat-activo:last-child { border-bottom: none; }
/* Lo elegido se marca con acento lima EN EL BORDE y el texto, no con un
   relleno sólido — el mismo lenguaje ("esto está elegido") pero a la escala
   de una fila de lista, no de un botón independiente. */
.apex-ctx-cat-activo--activo {
  color: var(--accent); font-weight: 700; border-left-color: var(--accent);
  background: var(--accent-bg);
}

/* ── Selectores de activo y ventana ── */
.apex-ctx-selector {
  display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; margin-bottom: 10px;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.apex-ctx-selector::-webkit-scrollbar { display: none; }
.apex-ctx-chip {
  flex: 0 0 auto; font-family: var(--font-mono); font-size: 11px; font-weight: 700;
  letter-spacing: .02em; color: var(--gray); background: var(--bg3);
  border: 1px solid var(--border); border-radius: 999px; padding: 8px 14px;
  text-decoration: none; white-space: nowrap;
}
.apex-ctx-chip--activo {
  color: var(--accent-t); background: var(--accent); border-color: var(--accent);
}
.apex-ctx-selector--ventana .apex-ctx-chip { font-size: 10px; padding: 6px 12px; }

/* ── Estado de sesión ── */
.apex-ctx-sesion {
  display: flex; align-items: center; gap: 8px; font-family: var(--font-body, 'Barlow', sans-serif);
  font-size: 12.5px; color: var(--gray); margin-bottom: 14px;
}
.apex-ctx-sesion-punto {
  flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--gray2);
}
.apex-ctx-sesion-punto--abierta { background: var(--green); box-shadow: 0 0 0 3px var(--green-bg); }

/* ── Aviso de calidad insuficiente (el caso VIX) ── */
.apex-ctx-aviso {
  font-family: var(--font-body, 'Barlow', sans-serif); font-size: 13px; line-height: 1.5;
  color: var(--gray); background: var(--amber-bg); border: 1px solid rgba(245,158,11,0.25);
  border-radius: var(--radius-md); padding: 14px 16px;
}

/* ── Grilla de tarjetas ── */
.apex-ctx-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 640px) { .apex-ctx-grid { grid-template-columns: 1fr 1fr; } }

.apex-ctx-metrica { display: flex; flex-direction: column; gap: 8px; }

/* Estado → dato → frase (§21 del diseño): el estado es lo primero que se lee,
   nunca un número solo. Colores reusados del resto de la app (mismo criterio
   que las alertas de "Seguimiento en vivo" en apex-lab-vivo.php) — no son un
   semáforo de "bueno/malo", describen distancia respecto a lo típico. */
.apex-ctx-estado {
  font-family: var(--font-display); font-size: 15px; font-weight: 800;
  letter-spacing: .01em; text-transform: uppercase;
}
.apex-ctx-estado--bajo { color: var(--info); }
.apex-ctx-estado--normal { color: var(--gray); }
.apex-ctx-estado--elevado { color: var(--amber); }
.apex-ctx-estado--muy-elevado { color: var(--danger); }

.apex-ctx-frase {
  font-family: var(--font-body, 'Barlow', sans-serif); font-size: 13px; color: var(--gray);
  line-height: 1.55; margin: 0;
}
.apex-ctx-n {
  font-family: var(--font-mono); font-size: 10px; color: var(--gray2); margin: 0;
}

/* ── Detalle plegable de la escalera de percentiles (2026-08-15) ──
   "Estado → dato → interpretación" (regla del diseño): la escalera de
   P25/mediana/P75/P90/P95 es la parte que el diseño mismo llama "nunca
   protagonista" — vive plegada, un toque la trae. <details> nativo: sin JS,
   sin estado que romper entre AJAX y SSR. */
.apex-ctx-detalle { margin: 8px 0 0; }
.apex-ctx-detalle summary {
  font-family: var(--font-mono); font-size: 10px; color: var(--gray2);
  cursor: pointer; user-select: none; list-style: none;
}
.apex-ctx-detalle summary::-webkit-details-marker { display: none; }
.apex-ctx-detalle summary::before { content: '▸ '; }
.apex-ctx-detalle[open] summary::before { content: '▾ '; }
.apex-ctx-dist {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--gray);
  line-height: 1.5; margin: 6px 0 0;
}

/* ── Relaciones (F3, 2026-08-15): número de correlación + su fuerza ──
   No reusa .apex-ctx-estado a propósito: ahí el color codifica "qué tan
   inusual es hoy" (bajo→muy elevado). Acá la fuerza no es buena ni mala —
   es descriptiva (baranda 2) — así que la escala de color es de intensidad
   neutra (gris→acento), nunca de alarma (nunca ámbar/rojo). */
.apex-rel-rho { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.apex-rel-rho-num {
  font-family: var(--font-display); font-size: 22px; font-weight: 800; color: var(--text); line-height: 1;
}
.apex-rel-rho-fuerza {
  font-family: var(--font-mono); font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--gray2);
}
.apex-rel-rho-fuerza--muy-alta,
.apex-rel-rho-fuerza--alta      { color: var(--accent-t, var(--text)); background: var(--accent); border-radius: 4px; padding: 2px 6px; }
.apex-rel-rho-fuerza--moderada  { color: var(--gray); }
.apex-rel-rho-fuerza--baja,
.apex-rel-rho-fuerza--muy-baja  { color: var(--gray2); }

.apex-rel-ratio { margin-top: 6px; }

/* ── Secciones apiladas de Relaciones (R-5, 2026-08-15) ──
   Correlación / Volatilidad relativa / Contexto intermercado, cada una con
   su título + subtítulo en lenguaje llano. El subtítulo es la pregunta que
   esa sección responde — existe para que las tres nunca se confundan entre
   sí, que fue justo el problema que esto vino a resolver (ver el análisis en
   05_WEB/2026-08-15_analisis_ficha_relaciones_v01.md §5). */
.apex-rel-seccion { margin-top: 28px; }
.apex-rel-seccion:first-child { margin-top: 0; }
.apex-rel-seccion-titulo {
  font-family: var(--font-display); font-size: 15px; font-weight: 800;
  color: var(--text); text-transform: uppercase; letter-spacing: .03em; margin: 0 0 2px;
}
.apex-rel-seccion-sub { font-size: 12px; color: var(--gray); margin: 0 0 12px; }

/* ── Comparador A↔B (R-2, 2026-08-15) ──
   El título de cada tarjeta es el link de entrada — sin selector nuevo,
   tocar la tarjeta ES elegir el par. Texto plano hasta el hover, para que la
   vista rápida no se vea como una lista de links azules. */
.apex-rel-par-link { color: inherit; text-decoration: none; }
.apex-rel-par-link:hover { text-decoration: underline; }
.apex-rel-volver { margin: 0 0 14px; }
.apex-rel-volver a {
  font-family: var(--font-mono); font-size: 11px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--accent); text-decoration: none;
}
.apex-rel-volver a:hover { text-decoration: underline; }

/* ── Divergencia (R-7, 2026-08-15) ──
   NO reusa .apex-ctx-estado: ahí el color codifica "qué tan inusual es el
   nivel de hoy" (bajo→muy elevado). Acá el significado es otro —"este par se
   apartó de su propia relación"— y mezclar las dos escalas haría que el mismo
   color dijera dos cosas distintas en la misma pantalla. Sin ámbar ni rojo:
   la divergencia es descriptiva, no una alarma (baranda 2). */
.apex-rel-div { margin-top: 8px; }
.apex-rel-div--activa {
  border-left: 2px solid var(--accent); padding-left: 10px;
}
.apex-rel-div-tag {
  display: block; font-family: var(--font-mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--accent); margin-bottom: 3px;
}
.apex-rel-nota { font-size: 11px; color: var(--gray2); margin: 10px 0 0; }

/* ── Selector de sesión de mercado (S-E, 2026-08-16) ──
   Reusa .apex-ctx-chip como el de ventanas: es el MISMO gesto ("elegí una de
   estas"), no un control nuevo que aprender. Lo único propio es el % de
   participación, que va en un tono secundario para que no compita con el
   nombre de la sesión. */
.apex-ctx-selector--sesion { margin-top: 4px; }
.apex-ctx-sesion-pct {
  font-family: var(--font-mono); font-size: 9.5px; font-weight: 700;
  opacity: .75; margin-left: 5px;
}
.apex-ctx-sesion-nota { font-size: 11px; color: var(--gray2); margin: 6px 0 12px; line-height: 1.45; }

/* Correlación dentro de la sesión principal (S-E.2, 2026-08-16). Discreta a
   propósito: es un dato que MATIZA el número grande, no otro titular. */
.apex-rel-ensesion { margin-top: 8px; font-size: 12.5px; color: var(--gray); }
.apex-rel-ensesion b { color: var(--text); font-family: var(--font-mono); }

/* ═══════════════════════════════════════════════════════════════════════
   Volatilidad (V2, 2026-08-28) — presupuesto de movimiento del día
   ═══════════════════════════════════════════════════════════════════════
   Reusa .apex-lab-card / .apex-lab-card-head / .apex-ctx-frase / .apex-ctx-
   detalle tal cual (mismo criterio que el resto de Mercado). Lo propio de
   acá: el número grande de la banda (mismo vocabulario visual que
   .apex-rel-rho-num) y la nota "no es regla de oro", que necesita destacarse
   — es la pieza más importante de toda la ficha (§3 del plan de diseño),
   así que no puede tener el mismo peso visual que una nota al pie cualquiera. */

.apex-vol-card .apex-lab-card-head { position: relative; }
.apex-vol-badge-derivado {
  margin-left: auto; font-family: var(--font-mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--gray2);
  border: 1px solid var(--border); border-radius: 4px; padding: 2px 6px; cursor: help;
}
.apex-vol-aviso {
  font-size: 12px; color: var(--gray2); margin: 0 0 10px; font-style: italic;
}

.apex-vol-banda {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 10px; margin-bottom: 4px;
}
.apex-vol-banda-label {
  font-family: var(--font-mono); font-size: 10px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--gray2); flex-basis: 100%;
}
.apex-vol-banda-valor {
  font-family: var(--font-display); font-size: 26px; font-weight: 800; color: var(--text); line-height: 1;
}
.apex-vol-banda-rango {
  font-family: var(--font-mono); font-size: 12px; color: var(--gray);
}
.apex-vol-secundario { font-size: 12.5px; color: var(--gray); margin: 0 0 10px; }
.apex-vol-frase-secundaria { margin-top: 8px; }

.apex-vol-detalle-lista {
  font-family: var(--font-mono); font-size: 11px; color: var(--gray);
  line-height: 1.7; margin: 6px 0 0; padding-left: 18px;
}

/* La pieza que impide que la banda se lea como promesa (§3 del plan) —
   destacada con borde propio, no un <p> más al final de la tarjeta. */
.apex-vol-no-regla {
  display: flex; align-items: flex-start; gap: 8px;
  margin: 14px 0 0; padding: 10px 12px;
  background: var(--bg1, var(--bg2)); border: 1px solid var(--border); border-radius: 8px;
  font-size: 11.5px; line-height: 1.5; color: var(--gray);
}
.apex-vol-no-regla svg { flex: none; margin-top: 1px; color: var(--gray2); }

/* ══ L7 (2026-08-30) · RELACIONES QUE CONVIENE CONOCER ══════════════════════
   Bloque de pares curados arriba del explorador por categorías. Tokens del
   sistema, sin colores literales (regla del portal: la UI lee la ZONA). */
.apex-rel-destacadas{margin:0 0 16px}

/* DESPLEGABLE (2026-09-02) — en el celular las 6 tarjetas empujaban abajo del
   pliegue los botones de categoría y la ficha entera. Cabecera tocable de una
   línea, cerrada por default; el panel usa grid-template-rows 0fr→1fr, la
   misma técnica que .apex-ctx-cat-panel (no hay que adivinar una altura). */
.apex-rel-dest-toggle{
  display:flex;align-items:center;gap:10px;width:100%;margin:0 0 10px;
  padding:11px 13px;border-radius:12px;cursor:pointer;text-align:left;
  border:1px solid var(--border,rgba(200,255,0,.14));background:rgba(255,255,255,.02);
  transition:border-color .15s,background .15s;
}
.apex-rel-dest-toggle:hover{border-color:rgba(200,255,0,.42)}
.apex-rel-dest-titulo{flex:1;font-size:15px;color:#e8f4f8;font-weight:600;margin:0}
/* Cuántos pares hay adentro — sin esto, una cabecera cerrada no dice si vale
   la pena abrirla. */
.apex-rel-dest-cuenta{
  flex:none;min-width:20px;padding:1px 7px;border-radius:999px;
  font-size:11.5px;font-weight:700;font-variant-numeric:tabular-nums;text-align:center;
  color:var(--accent,#C8FF00);background:rgba(200,255,0,.10);
}
.apex-rel-dest-flecha{
  flex:none;width:8px;height:8px;margin-right:2px;
  border-right:2px solid #7fa5b4;border-bottom:2px solid #7fa5b4;
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .25s ease;
}
.apex-rel-dest-toggle[aria-expanded="true"] .apex-rel-dest-flecha{
  transform:rotate(-135deg) translate(-2px,-2px);
}
.apex-rel-dest-panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .25s ease}
.apex-rel-dest-panel--abierto{grid-template-rows:1fr;margin-bottom:6px}
.apex-rel-dest-panel-inner{overflow:hidden;min-height:0}

.apex-rel-dest-grid{display:grid;grid-template-columns:1fr;gap:10px}
.apex-rel-dest-card{display:block;padding:13px 14px;border-radius:12px;text-decoration:none;
  border:1px solid var(--border,rgba(200,255,0,.14));background:rgba(255,255,255,.02);transition:border-color .15s}
.apex-rel-dest-card:hover{border-color:rgba(200,255,0,.42)}
.apex-rel-dest-head{display:flex;align-items:baseline;gap:10px;margin-bottom:3px}
.apex-rel-dest-h3{flex:1;font-size:14.5px;font-weight:600;color:#e8f4f8;line-height:1.25}
.apex-rel-dest-rho{flex:none;font-size:16px;font-weight:700;font-variant-numeric:tabular-nums}
.apex-rel-dest-rho--pos{color:var(--apex-pos,#4ade80)}
.apex-rel-dest-rho--neg{color:var(--apex-neg,#f87171)}
.apex-rel-dest-frase{margin:0 0 7px;font-size:13px;color:var(--accent,#C8FF00);font-weight:600}
.apex-rel-dest-txt{margin:0 0 5px;font-size:13px;color:#9ec3d1;line-height:1.5}
.apex-rel-dest-txt b{color:#cfe6ee;font-weight:600}
/* El pie era una sola línea gris con "· ver el detalle →" pegado al conteo de
   días: se leía como una nota al pie, no como algo que se toca (2026-09-02,
   Sergio: "veo una flecha que dice ver el detalle, no muestra nada"). El
   número de días se queda gris —es contexto— y la acción se separa en lima. */
.apex-rel-dest-pie{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-top:9px}
.apex-rel-dest-n{font-size:11.5px;color:#7fa5b4}
.apex-rel-dest-cta{flex:none;font-size:12px;font-weight:600;color:var(--accent,#C8FF00)}
.apex-rel-dest-nota{margin:10px 0 0;font-size:12.5px;color:#7fa5b4;line-height:1.5}
.apex-rel-dest-nota b{color:#9ec3d1}
/* En escritorio entran de a dos: la tarjeta tiene 4 líneas de texto, tres
   columnas la volverían ilegible. */
@media (min-width:1024px){
  .apex-rel-dest-grid{grid-template-columns:1fr 1fr;gap:12px}
}

/* Las tarjetas de arriba linkean a #apex-rel-cuerpo (2026-09-02): sin esto el
   navegador deja el detalle debajo de la topbar sticky, que mide
   56px + safe-area. Mismo criterio que .apex-glo-item[id] en el glosario. */
#apex-rel-cuerpo{scroll-margin-top:calc(72px + env(safe-area-inset-top, 0px))}

/* Consistencia de tamaño · fila sin muestra suficiente (2026-08-31, L13).
   No lleva barra: con menos de 5 operaciones la dispersión da 0 por
   matemática y una barra verde afirmaría una consistencia que no se midió. */
.apex-an-corte-row.es-sinmuestra { opacity: .55; }
.apex-an-corte-row.es-sinmuestra .apex-an-corte-barwrap {
  background: repeating-linear-gradient(90deg, var(--bg3) 0 4px, transparent 4px 8px);
}

/* ══ iOS: el auto-zoom al enfocar un campo ═══════════════════════════════════
   Lo encontró Sergio el 2026-09-01 probando la app en su iPhone: tocó la
   campanita para crear una alarma y "la pantalla creció gigante y se
   desconfiguró" — los precios cortados a la derecha, la barra inferior partida.

   NO era un bug de la alarma (la alarma se creó bien): es comportamiento de
   iOS. Safari y WKWebView hacen zoom automático al enfocar cualquier campo con
   font-size MENOR a 16px, y NO lo deshacen al salir. La página queda ampliada
   hasta que el usuario pellizca para volver, o cierra la app. Con la barra de
   navegación cortada, parece que la app se rompió.

   Se sube el campo a 16px SOLO en pantallas táctiles (`pointer: coarse` = el
   dedo, no el mouse), así los tamaños de diseño de escritorio quedan intactos.

   ⚠️ La alternativa que suele verse (`maximum-scale=1` o `user-scalable=no` en
   el viewport) NO se usa a propósito: apaga el zoom con pinza para todo el
   mundo — es un problema de accesibilidad real y algo que Apple mira en la
   revisión. Se arregla la causa, no se tapa el síntoma.

   Afectaba al menos a `.apex-alm-form input` (alarmas) y `.apex-rg-input`
   (reglas), más los formularios de login, perfil y soporte. */
@media (pointer: coarse) {
  input[type="text"], input[type="number"], input[type="email"],
  input[type="password"], input[type="search"], input[type="tel"],
  input[type="url"], input[type="date"], input[type="time"],
  input:not([type]), select, textarea {
    font-size: 16px;
  }
}

/* ── OJO PARA TAPAR IMPORTES (2026-09-01) ────────────────────────────────────
   Helper en apex-lab-datos.php: apex_lab_ojo() / apex_lab_ojo_attr().
   Para grabar o compartir pantalla sin mostrar cuánta plata hay en la cuenta.

   El ojo REUSA .apex-cc-ojo (mismo botón que el del número de cuenta) pero el
   estado se invierte: allá la clase marca "visible", acá marca "tapado",
   porque acá el default es ver. Por eso los iconos se resuelven con reglas
   propias en vez de heredar las de .apex-cc-num-wrap.

   El dato tapado NO se borra del DOM: se cubre. Está en su propia página y
   nadie más la ve — el ojo protege de una cámara, no de un curioso con las
   herramientas de desarrollador, y prometer lo segundo sería mentir. */
.apex-ojo-btn .apex-cc-ojo-on{display:inline}
.apex-ojo-btn .apex-cc-ojo-off{display:none}
.apex-ojo--tapado .apex-ojo-btn .apex-cc-ojo-on{display:none}
.apex-ojo--tapado .apex-ojo-btn .apex-cc-ojo-off{display:inline}

/* 2026-09-01 · Área de toque real — Sergio: "el ojo está un poco escondido en
   el iPhone". Medido en el original: 21×21px de botón (15px de ícono + 3px de
   relleno), contra el mínimo de 44×44 que pide la guía de Apple. Sube acá, en
   `.apex-ojo-btn`, y NO en `.apex-cc-ojo` (la base, que también es el ojo del
   número de cuenta en la fila de la cuenta conectada): ese vive en una fila ya
   resuelta y angosta, y agrandarlo ahí tocaría algo que nadie pidió cambiar. */
.apex-ojo-btn{padding:9px;min-width:34px;min-height:34px}

/* Variante con texto visible — SOLO donde el ojo flota solo, sin nada
   alrededor que diga "acá hay algo para tocar" (la tarjeta "Salud de la
   cuenta" de Resumen). En la cabecera de "Movimientos de caja" NO se usa:
   esa fila ya es angosta y agregar texto ahí partiría el título en dos
   líneas — ver el comentario de $con_texto en apex_lab_ojo(). */
.apex-ojo-btn--full{
  gap:6px;padding:9px 14px;min-height:36px;
  background:var(--bg3);border:1px solid var(--border2);border-radius:var(--radius-md);
  color:var(--gray);
}
.apex-ojo-btn--full:hover{border-color:var(--accent-bd);color:var(--text)}
.apex-ojo-txt{font-family:var(--font-mono);font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase}
/* Mismo criterio -on/-off que los <svg>: "on" es el texto del estado por
   defecto (visible), "off" el del estado tapado. */
.apex-ojo-btn--full .apex-ojo-txt-off{display:none}
.apex-ojo--tapado .apex-ojo-btn--full .apex-ojo-txt-on{display:none}
.apex-ojo--tapado .apex-ojo-btn--full .apex-ojo-txt-off{display:inline}

/* `color:transparent` + bolitas encima: mantiene el ancho de la fila, así que
   tapar y destapar no salta la maquetación (importante en la tabla, donde el
   salto se vería en 20 filas a la vez). */
.apex-ojo--tapado .apex-ojo-dato{position:relative;color:transparent!important;user-select:none}
.apex-ojo--tapado .apex-ojo-dato::after{
  content:"••••";position:absolute;inset:0;display:flex;align-items:center;
  justify-content:inherit;color:var(--text-dim,#8a9fa8);letter-spacing:.12em;
  font-weight:600;pointer-events:none;
}
/* En las tarjetas de stat el número va centrado; en la tabla, alineado como
   la celda. `inherit` de arriba resuelve la tabla; acá el centro de la tarjeta. */
.apex-lab-stat .apex-ojo-dato::after{justify-content:center}

/* El botón, alineado con el título de la tarjeta que tapa. */
.apex-ojo-cabecera{display:inline-flex;align-items:center;gap:6px;margin-left:auto}
/* Barra del ojo: alineada a la derecha, arriba del bloque que tapa. */
.apex-ojo-barra{display:flex;justify-content:flex-end;margin:0 0 -6px}

/* ═══ MI CUENTA — FOTO DE PERFIL (2026-09-02) ═══════════════════════════════
   Pedido de Sergio: "hay un redondo lima con iniciales, ahí quería su foto, un
   poco más grande". Era 56px con las iniciales sobre lima pleno; ahora es la
   foto real y ocupa el lugar que le corresponde como ancla de la pantalla.

   El fondo lima se mantiene SOLO cuando no hay foto: con imagen, un aro lima
   fino la enmarca sin competirle. Un círculo lima pleno detrás de una foto la
   ensucia por los bordes. */
.apex-cta-foto-wrap{position:relative;flex-shrink:0;width:84px;height:84px}
.apex-cta-id .apex-cta-avatar{
  width:84px;height:84px;padding:0;border:0;cursor:pointer;overflow:hidden;
  font-size:28px;transition:filter .18s,box-shadow .18s;
}
.apex-cta-id .apex-cta-avatar:hover{filter:brightness(1.06)}
.apex-cta-id .apex-cta-avatar:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.apex-cta-avatar img{width:100%;height:100%;object-fit:cover;display:block;border-radius:50%}
/* Con foto, el lima pasa a ser un aro, no un relleno. */
.apex-cta-avatar:has(img){background:transparent;box-shadow:0 0 0 2px var(--accent)}
.apex-cta-foto-badge{
  position:absolute;right:-2px;bottom:-2px;width:28px;height:28px;border-radius:50%;
  background:var(--accent);color:var(--accent-t);display:flex;align-items:center;
  justify-content:center;border:2px solid var(--bg2);pointer-events:none;
}
.apex-cta-foto-wrap.subiendo{opacity:.55;pointer-events:none}
.apex-cta-foto-msg{margin-top:8px}

@media(max-width:700px){
  .apex-cta-id{gap:14px}
  .apex-cta-foto-wrap,.apex-cta-id .apex-cta-avatar{width:76px;height:76px}
  .apex-cta-id .apex-cta-avatar{font-size:26px}
  .apex-cta-foto-badge{width:26px;height:26px}
}

/* ═══ MI CUENTA — JERARQUÍA (2026-09-02) ═══════════════════════════════════
   Pedido de Sergio: "hay mil cuadrados, sin claridad... quiero que diagrames,
   marques espacio, diferencies el tema del que se habla".

   Eran ONCE tarjetas apiladas, todas con el mismo fondo, borde y radio: plan,
   cuentas, nombre, seguridad, la app, borrar historial, ayuda, dar de baja…
   Sin un nivel por encima de la tarjeta, el ojo no tiene dónde apoyarse. Todo
   pesa igual, así que nada pesa.

   La solución no es decorar las cajas: es SACAR cajas. Un encabezado de grupo
   dice de qué se habla, y adentro las tarjetas se vuelven un listado separado
   por líneas. Menos bordes, más lectura. */
.apex-grupo-h{
  display:flex;align-items:flex-start;gap:12px;
  margin:30px 0 2px;padding-bottom:11px;
  border-bottom:1px solid var(--accent-bd);
}
.apex-grupo-h:first-of-type{margin-top:24px}
.apex-grupo-n{
  font-family:var(--font-mono,'JetBrains Mono',monospace);font-size:10px;font-weight:700;
  letter-spacing:.1em;color:var(--accent);background:var(--accent-bg);
  border:1px solid var(--accent-bd);border-radius:3px;padding:4px 7px;flex-shrink:0;line-height:1;
}
.apex-grupo-h h2{
  font-family:'Barlow Condensed',sans-serif;font-size:19px;font-weight:800;
  color:var(--text);margin:0;line-height:1.1;letter-spacing:.01em;
}
.apex-grupo-h p{font-size:12px;color:var(--gray);margin:2px 0 0;line-height:1.4}

/* Las tarjetas de ESTA pantalla (no las del resto del Lab) pasan a listado. */
.apex-cta-sec{
  border-radius:0;border-left:0;border-right:0;border-top:0;
  background:transparent;padding-left:2px;padding-right:2px;
}
.apex-cta-sec + .apex-grupo-h{margin-top:34px}
.apex-cta-sec .apex-lab-card-head{padding-left:0;padding-right:0}

/* La identidad SÍ sigue siendo una tarjeta: es la foto de quién sos, y merece
   el peso. Es la única de la pantalla con caja completa. */
.apex-cta-id{
  background:var(--bg2);border:1px solid var(--border);border-radius:12px;
  padding:20px;border-left:1px solid var(--border);
}

/* Las dos acciones destructivas se distinguen del resto: no por color de
   alarma —no son un error— sino por quedar visiblemente aparte. */
.apex-cta-sec.apex-salir-card,.apex-cta-sec.apex-bh-card{
  background:rgba(255,255,255,.02);border-radius:10px;
  border:1px solid rgba(255,255,255,.08);padding:16px;margin-top:12px;
}

@media(max-width:700px){
  .apex-grupo-h{margin:24px 0 2px;gap:10px;padding-bottom:9px}
  .apex-grupo-h h2{font-size:18px}
  .apex-grupo-h p{font-size:11.5px}
  .apex-cta-id{padding:16px;border-radius:10px}
  .apex-cta-sec{padding-left:0;padding-right:0}
  .apex-cta-sec.apex-salir-card,.apex-cta-sec.apex-bh-card{padding:14px}
}
/* "Pro activo" es un estado positivo y estable: va en el acento de la marca.
   Antes reusaba la clase del regalo (violeta), un color prestado de otro
   significado. */
.apex-cta-badge--pro{background:var(--accent-bg);color:var(--accent);border:1px solid var(--accent-bd)}

/* ── BOTONES DE MI CUENTA (2026-09-02) ──────────────────────────────────────
   `.flow-btn` a secas no pinta NADA: fondo y borde viven en los modificadores
   .primary/.outline (apex-flow.css). Tres botones de esta pantalla estaban sin
   modificador y se veían como texto suelto — "no se sabe si son botones o qué",
   textual de Sergio. Corregido en el HTML; acá va lo que necesitan además. */
.apex-cta-acciones{gap:12px}
.apex-cta-acciones .flow-btn{min-height:48px}
/* "Cerrar sesión" no es un destino más: se separa de "cambiar contraseña" para
   que no se toque por error. Sin rojo — cerrar sesión no es un peligro. */
.apex-cta-salir{color:var(--gray)!important;border-color:rgba(255,255,255,.14)!important}
.apex-cta-salir:hover{color:var(--text)!important;border-color:rgba(255,255,255,.34)!important}

/* Guardar apagado: sigue siendo legible, pero no invita. Un botón deshabilitado
   que no se distingue del habilitado es peor que no tenerlo. */
.apex-cta-guardar{min-height:48px;transition:background .18s,color .18s,border-color .18s,opacity .18s}
.apex-cta-guardar[disabled]{opacity:.5;cursor:default;pointer-events:none}

@media(max-width:700px){
  /* Dos botones en mayúsculas uno al lado del otro no entran en 375px sin
     partirse. Apilados y a ancho completo se leen y se tocan bien. */
  .apex-cta-acciones{flex-direction:column}
  .apex-cta-acciones .flow-btn{width:100%}
  .apex-cta-guardar{width:100%}
}

/* Avatar del topbar con foto (2026-09-02). Un poco más grande que el de
   iniciales: una foto necesita más superficie que dos letras para leerse, y
   este botón es la puerta a Mi cuenta en TODAS las pantallas. */
.apex-cta-topbar-ini--foto{
  width:36px;height:36px;padding:0;overflow:hidden;
  background:transparent;border:0;box-shadow:0 0 0 2px var(--accent);
}
.apex-cta-topbar-ini--foto img{width:100%;height:100%;object-fit:cover;display:block;border-radius:50%}
/* Con foto, el relleno lima del estado Pro sobra: el aro ya lo dice. */
.apex-cta-topbar.is-pro .apex-cta-topbar-ini--foto{background:transparent;border:0}

/* ── EL INPUT DE ARCHIVO ES EL BOTÓN (2026-09-02) ───────────────────────────
   Antes: `<input type="file" hidden>` + `input.click()` desde JS. En el
   escritorio andaba; en iPhone NO — WebKit se niega a abrir el selector de un
   input que está en display:none. Tocar el círculo no hacía nada, y encima en
   silencio.
   Ahora el input, transparente, CUBRE el avatar: tocar el círculo es tocar el
   input, y el selector lo abre el sistema sin que ningún script lo pida. */
.apex-cta-foto-input{
  position:absolute;inset:0;width:100%;height:100%;
  opacity:0;cursor:pointer;z-index:3;border-radius:50%;
  font-size:0;   /* Safari le dibuja el botón "Choose file" si no */
}
.apex-cta-foto-input:focus-visible + .apex-cta-avatar,
.apex-cta-foto-wrap:focus-within .apex-cta-avatar{outline:2px solid var(--accent);outline-offset:3px}
.apex-cta-avatar{pointer-events:none}   /* el input de arriba recibe el toque */

/* Galería nativa (app de iOS, 2026-09-02): ahí no hay <input> —lo abre el
   plugin de Capacitor— así que el círculo entero ES el botón. El avatar sigue
   con pointer-events:none y el toque lo recibe el wrap, que es quien escucha. */
.apex-cta-foto-wrap.usa-galeria-nativa{cursor:pointer}
.apex-cta-foto-wrap.usa-galeria-nativa:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:50%}

/* El aviso de la foto: visible de verdad, y rojo cuando algo falla. */
.apex-cta-foto-msg{
  flex-basis:100%;margin:10px 0 0;font-size:12.5px;color:var(--gray);line-height:1.4;
}
.apex-cta-foto-msg.is-error{color:#ff8080}
