/* ═══ MOBILE RESPONSIVE — capa aditiva, terminal ═══
   Todo dentro de @media(max-width:899px) — ampliado desde 767px para cubrir
   también el rango 768-899px, que css/terminal-mobile.css ocupaba antes de
   su bypass (ver <!-- NUEVO: mobile-render-switch-bypass --> en
   apps/terminal/index.html y al final de css/terminal-mobile.css). Sin este
   ajuste, 768-899px mostraba el #app-shell de escritorio sin ninguna de las
   adaptaciones de este archivo (sidebar fija de 210px sin drawer, barra de
   acciones desbordada ~43px). Cero efecto en desktop (>=900px).
   Ver docs/mobile/terminal-responsive-audit.md para el diagnóstico
   que justifica cada bloque. */

@media (max-width: 899px) {

  /* ─── A/B — Sidebar deja de robar 210px fijos; se convierte en drawer
         off-canvas controlado por js/mobile-nav.js ─── */
  .app-layout { grid-template-columns: 1fr; }

  /* NOTA: terminal.css:1084 define `body:not(.welcome-mode) .sidebar{display:block}`
     con especificidad (0,2,1). Un simple `.sidebar{display:none}` (0,1,0) pierde esa
     pelea sin importar el orden de carga. Igualamos la especificidad reusando el
     mismo patrón de selector para que la cascada la decida el orden de archivo
     (este fichero carga después de terminal.css). */
  .sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: min(78vw, 280px);
    z-index: 600;
    box-shadow: 2px 0 24px rgba(0,0,0,.6);
  }
  body:not(.cbm-mnav-open) .sidebar { display: none; }
  body.cbm-mnav-open .sidebar { display: block; }
  body.cbm-mnav-open .main-content { overflow: hidden; }

  .cbm-mnav-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,.55);
    z-index: 590;
  }
  body.cbm-mnav-open .cbm-mnav-backdrop { display: block; }

  .cbm-mnav-toggle {
    position: fixed;
    top: 8px; left: 8px;
    z-index: 650;
    width: 40px; height: 40px;
    display: flex; align-items: center; justify-content: center;
    background: var(--bg1, #0d1117);
    border: 1px solid var(--border2, #273547);
    border-radius: 6px;
    color: var(--text0, #e8eef5);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
  }

  /* ─── Causa raíz confirmada del desborde de las barras superiores:
         .live-bar-right y .header-stats son flex sin flex-wrap
         (css/terminal.css:33 y :343) ─── */
  .live-bar-right { flex-wrap: wrap; row-gap: 6px; }
  /* !important imprescindible y documentado: apps/terminal/index.html:287
     tiene <div id="headerStats" style="flex:1;justify-content:center;gap:28px">
     — un inline style="" gana siempre a cualquier regla externa (no es un
     problema de orden de carga ni de especificidad de selector, es inline).
     flex-basis:100% fuerza el salto de línea de header-stats a su propia
     fila con los 375px completos; si no, comparte fila con logo+badge
     encogido a ~190px y sus 5 hijos quedan forzados a 1 por fila. */
  .header-stats {
    flex: 1 1 100% !important;
    flex-wrap: wrap;
    row-gap: 4px;
    gap: 12px !important;
    justify-content: flex-start !important;
  }
  .header { padding: 10px 14px; flex-wrap: wrap; row-gap: 6px; }
  .live-bar { padding: 6px 14px; }

  /* ─── C — Tablas anchas: wrapper inyectado por mobile-nav.js.
         Scroll horizontal interno + primera columna fija + shadow-cue ─── */
  .cbm-table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border: 1px solid var(--border, rgba(255,255,255,.08));
    border-radius: 6px;
    box-shadow: inset -14px 0 10px -12px rgba(0,0,0,.55);
  }
  .cbm-table-scroll table { margin: 0; }
  .cbm-table-scroll table th:first-child,
  .cbm-table-scroll table td:first-child {
    position: sticky;
    left: 0;
    background: var(--bg1, #0d1117);
    z-index: 1;
  }

  /* ─── D — Grids de cards genéricos sin cobertura mobile previa.
         Las *-welcome-grid / *-cat-grid / calc-grid-* YA tienen su propio
         breakpoint más abajo en terminal.css — no se tocan aquí para no
         pelear con esa cascada ─── */
  .g4, .g3, .g2, .g21, .g12,
  .fgrid, .fgrid3,
  .vc-metrics, .metrics-grid, .plan-grid,
  .dd-row {
    grid-template-columns: 1fr;
  }

  /* ─── E — Padding reducido pero legible ─── */
  .tab-pane { padding: 12px; }
  .card-body { padding: 12px; }

  /* ─── F — Filas chart+leyenda (p.ej. Asset Allocation) no deben desbordar;
         canvas nunca debe superar el ancho de su contenedor ─── */
  .card-body [style*="display:flex"] { flex-wrap: wrap; }
  canvas { max-width: 100%; }

  /* ─── G — Touch targets ≥44px en controles interactivos ─── */
  .btn { min-height: 44px; padding: 10px 16px; }
  .btn-sm { min-height: 40px; padding: 8px 12px; }
  .nav-item { min-height: 44px; padding: 10px 14px; }
  input[type="checkbox"] { width: 20px; height: 20px; }

  /* ─── H — Modales: ya son responsive (92vw/88vh) — solo safe-area ─── */
  .modal { max-height: calc(88vh - env(safe-area-inset-bottom, 0px)); }

  /* ─── J — 16px evita el auto-zoom de iOS al enfocar inputs.
     !important documentado: varios paneles (p.ej. Settings, generado por
     js/14-preferences.js) escriben sus <select>/<input> con
     style="...font-size:12px" inline vía JS. Un inline style="" gana
     siempre a una regla externa aunque sea más específica o cargue
     después — mismo patrón que .header-stats más arriba. Detectado con
     el test E2E de font-size, no a simple vista. ─── */
  input, select, textarea { font-size: 16px !important; }

  /* ─── K — Safe-area inferior (notch / home indicator) ─── */
  #app-shell { padding-bottom: env(safe-area-inset-bottom, 0px); }

  /* ─── L — .cbm-mnav-toggle (hamburguesa, fixed top:8px left:8px 40x40,
         z-index:650, ver /js/mobile-nav.js) se solapa con el primer símbolo
         del ticker-tape porque este último no reserva espacio a la
         izquierda. Padding-left en el propio ticker (no en ticker-inner,
         que se traslada vía JS para el scroll infinito). ─── */
  .ticker-tape { padding-left: 52px; }

  /* ─── M — Toolbar (.live-bar-right) cabe en 11 controles; con flex-wrap
         ya no desborda pero ocupa demasiadas filas. Se compactan botones y
         se ocultan solo elementos redundantes/no-primarios (accesibles
         igual por teclado: ⌘K y ? abren los mismos paneles via shortcut).
         Refresh/Save/Live Prices/Conectar permanecen visibles y clicables.
         !important necesario: apps/terminal/index.html:254 pone
         style="display:flex" inline en el wrapper de Search/Help — un
         inline style="" gana siempre a una regla externa (mismo patrón que
         .header-stats/input más abajo en este fichero). ─── */
  .live-bar-right .btn, .live-bar-right .btn-sm {
    padding: 6px 9px;
    font-size: 10px;
  }
  #saveStatus,
  .live-bar-right > div[style*="display:flex;align-items:center;gap:4px"] {
    display: none !important;
  }

  /* ─── N — KPIs del header (#headerStats): grid de 2 columnas + font-size
         fluido para que "$6,231.38" no desborde en 375px ─── */
  .header-stats {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px 16px;
  }
  .hstat-value { font-size: clamp(12px, 4vw, 15px); }

  /* ─── P — item #9 del audit: 127 apariciones de font-size 10-13px en
         terminal.css (labels, captions, sub-textos, welcome-screen
         sub/count/desc, drawer tabs, badges...). Lista extraída por
         script (grep de todas las reglas con font-size:10-13px en
         terminal.css) para reusar los selectores EXACTOS con la MISMA
         especificidad que la regla original — así gana por orden de
         carga (este fichero va después de terminal.css) sin necesitar
         !important y sin arriesgar sobre-escalar por herencia (probado
         con max(12px,1em): en las welcome-cat-cards el 1em heredaba
         ~16px del contenedor, muy por encima del 12-13px objetivo del
         audit — de ahí el valor fijo). Excluye explícitamente de la
         extracción: .btn/.btn-sm (bloque G, ya gestionan su propio
         tamaño con min-height:44px), inputs/selects/textareas (bloque
         J, ya en 16px) y .live-bar/.ticker-item/.ticker-suggest-item
         (texto de status-bar y marquee, densidad intencional — no es
         el "cuerpo de texto" al que apunta el hallazgo #9). ─── */
  #tab-advisor-welcome .ra-wc-count, #tab-advisor-welcome .ra-wc-sub, #tab-advisor-welcome .ra-wc-title,
  #tab-ent-welcome .ra-wc .ra-wc-count, #tab-ent-welcome .ra-wc-sub, #tab-ent-welcome .ra-wc-title,
  #tab-legal-welcome .ra-wc .ra-wc-count, #tab-legal-welcome .ra-wc-sub, #tab-legal-welcome .ra-wc-title,
  #tab-pb-welcome .pb-wc-count, #tab-pb-welcome .pb-wc-desc, #tab-pb-welcome .pb-wc-panels,
  #tab-pb-welcome .pb-wc-title, #tab-ra-welcome .ra-wc-count, #tab-ra-welcome .ra-wc-sub,
  #tab-ra-welcome .ra-wc-title, .ai-age, .ai-approvals-badge,
  .ai-disclosure-banner, .ai-insights-header, .ai-resp h3,
  .ai-role, .bulk-bar, .card-title,
  .cert-subtab, .client-sel-dropdown, .contract-upload-clear,
  .contract-upload-filename, .contract-upload-hint, .contract-upload-prompt p,
  .contract-upload-size, .crm-drawer-tab, .cs-label,
  .csv-format-box, .curr-label, .cz-zp-count,
  .cz-zp-empty, .cz-zp-group li label, .cz-zp-group-head,
  .cz-zp-group-toggle, .cz-zp-label, .cz-zp-pill,
  .cz-zp-pill button, .dd-row, .dd-row-header,
  .def-box, .drop-zone .dz-sub, .drop-zone .dz-text,
  .ef-tooltip, .factor-def-abbr, .factor-def-body,
  .factor-def-name, .fi-row .fi-label, .fi-row label,
  .fl, .import-tab, .inv-subtab,
  .ipd-drop-hint, .ipd-drop-text, .ipd-file-chip,
  .ipd-label, .ipd-seg-tab, .ipd-toggle-label,
  .mc-sub, .metrics-section-title, .modal-title,
  .mv-sym, .nav-item .icon, .panel-section > header,
  .pb-wc-count, .pb-wc-desc, .pb-welcome-sub,
  .perf-sub-tab, .plan-features, .plan-features li,
  .plan-header p, .plan-price small, .pm-cat-count,
  .pm-cat-label, .pm-cat-panels, .pm-wc-title,
  .pm-welcome-sub, .price-52w, .ra-wc-title,
  .sig-name, .sig-val, .spill,
  .tier-box-desc, .tier-box-title, .ts-loading,
  .ts-name, .ts-sym, .up-lbl,
  .upgrade-overlay .plan-badge-inline, .upgrade-overlay p, .vm-value,
  .pm-wc-sub, .ra-table th, .ra-wc-count, .ra-wc-sub {
    font-size: 12px;
  }

  /* ─── Q — item #10 del audit: banner legal de IA (#ai-platform-notice)
         cubre ~180/812px (22%) en 375px. Causa: sus 3 hijos (span/a/
         button) son flex-wrap sin flex-basis, compiten por fila y el
         span (texto largo) genera ~4 filas implícitas. padding/gap del
         contenedor están en el style="" inline del propio elemento
         (apps/terminal/index.html:216) → !important obligatorio para
         ganarles (mismo patrón que .header-stats/.live-bar-right más
         arriba). El <span> NO fija font-size inline, solo hereda del
         padre, así que forzarle flex-basis:100% no necesita !important.
         Resultado: de ~4 filas implícitas a 2 (texto arriba, enlace +
         botón "Cerrar" comparten la fila siguiente vía el
         margin-left:auto que el botón ya trae inline). No se toca ni
         se oculta el texto del aviso legal, solo su layout. ─── */
  #ai-platform-notice {
    padding: 7px 14px !important;
    gap: 6px !important;
  }
  #ai-platform-notice > span:first-child {
    flex: 1 1 100%;
    line-height: 1.35;
  }

  /* ─── NUEVO: mobile-header-unstick — ticker+toolbar+header no estaban
         "sticky" de verdad: #app-shell es position:fixed;overflow:hidden con
         .main-content como único contenedor con scroll interno (terminal.css
         :52,51,96), así que el bloque superior nunca se movía. Se pasa a
         scroll de página: #app-shell/.app-layout/.main-content dejan de
         recortar overflow y body (overflow:hidden en terminal.css:17) pasa a
         overflow-y:auto. position:relative (no static) en #app-shell
         preserva el stacking context que ya le da su z-index:1 incondicional
         (terminal.css:52) — imprescindible para que js/mobile-nav.js:22-33
         siga pintando el drawer/backdrop por encima del sidebar (verificado
         con elementFromPoint). Complemento obligatorio en JS: showTab()
         (js/02-core.js) hacía mc.scrollTop=0 asumiendo .main-content como
         único scroll ("window never scrolls" en su propio comentario); con
         scroll de página ese reset se queda corto, así que se añade
         window.scrollTo(0,0) en móvil junto a esa línea. ─── */
  #app-shell { position: relative; inset: auto; overflow: visible; height: auto; min-height: 100vh; }
  .app-layout { overflow: visible; height: auto; }
  .main-content { overflow: visible; height: auto; }
  /* Solo body: html no lleva overflow propio (default visible), así que el
     overflow de body se propaga al viewport (regla legacy CSS2.1) y este
     sigue siendo el único scroll container — si además se fija overflow en
     html, se crean DOS scroll containers anidados y position:sticky dentro
     de .header deja de engancharse al que realmente se mueve (comprobado:
     con html+body ambos en auto, .header calculaba sticky contra el body,
     que no se movía, mientras el scroll real ocurría en html). */
  body { overflow-y: auto; overflow-x: hidden; }

  /* La hamburguesa (.cbm-mnav-toggle, fixed top:8 left:8 40x40) ya recibía
     este mismo tratamiento en .ticker-tape (regla L, arriba) para no tapar
     el primer símbolo del ticker. Con el header ahora sticky (ver bloque
     mobile-sticky-minibar) el mismo solape aparece en .live-bar (texto
     "Live prices disconnected") y en .header (logo) — mismo padding-left. */
  .live-bar { padding-left: 52px; }
  /* /NUEVO: mobile-header-unstick */

  /* ─── NUEVO: mobile-header-compact — reduce el alto de .header (logo +
         badge + rejilla de 5 KPIs) sin ocultar ni reordenar ningún KPI.
         !important en header-stats/hstat-value: mobile-responsive.css ya
         tiene reglas previas con !important sobre .header-stats (arriba,
         bloque de flex-basis) que ganarían por especificidad+!important a un
         gap sin marcar, mismo patrón ya documentado en este fichero. ─── */
  .header { padding: 6px 12px 6px 52px; row-gap: 4px; }
  .logo { font-size: 15px; margin-right: 10px !important; }
  .owner-badge { padding: 2px 8px; }
  .header-stats { gap: 3px 10px !important; }
  .hstat-label { font-size: 7px; }
  .hstat-value { font-size: clamp(10px, 3.2vw, 12px); }
  /* /NUEVO: mobile-header-compact */

  /* ─── NUEVO: mobile-sticky-minibar — .header (ya compactado arriba) se fija
         con position:sticky al hacer scroll: es la única franja del bloque
         superior que permanece visible — ticker-tape y .live-bar, sin
         sticky, se van con el scroll (ver mobile-header-unstick). Reutiliza
         directamente #hTotalValue/#hDayChange y el resto de KPIs — viven ya
         dentro de .header, cero nodos ni estado duplicado. z-index:10 de
         .header ya existe sin condición en terminal.css:30. ─── */
  .header { position: sticky; top: 0; }
  /* /NUEVO: mobile-sticky-minibar */
}
