/* ===== Mobile + responsive polish (10/10 sweep) ===== */

/* Phone */
@media (max-width: 760px) {
  .topbar {
    /* ── AQUI HABIA TRES COLUMNAS, Y ROMPIAN EL MENU (2-sep-2026) ──────────
       Esta regla forzaba `grid-template-columns: auto minmax(0,1fr) auto` con
       !important. El motivo era bueno —que el nav se vea en el telefono, para
       que un cliente de pago no quede ATRAPADO en el Panel— pero styles.css ya
       lo resuelve, y mejor: baja el nav a una SEGUNDA FILA a ancho completo
       (@media max-width:768px, `.topbar { grid-template-columns: auto 1fr;
       grid-template-rows: auto auto }`).

       Las dos reglas se solapan por debajo de 760 px. El !important ganaba en
       las COLUMNAS pero no en las colocaciones de los hijos, que siguen siendo
       las de styles.css: `.top-right { grid-column: 2 }` y el nav en
       `grid-column: 1 / -1; grid-row: 2`. Medio layout de cada fichero.

       Resultado medido en produccion a 375 px:

           .top-right   left −126   right 42     ← empieza FUERA de pantalla
           boton Entrar left −126   right −77    ← INVISIBLE E INPULSABLE

       Un cliente no podia iniciar sesion desde el movil. Y no lo cazaba ninguna
       auditoria previa porque `document.scrollWidth === clientWidth`: el
       desbordamiento va hacia la IZQUIERDA, y el desbordamiento izquierdo NO
       cuenta en scrollWidth. Todas las mediciones anteriores decian
       «0 desplazamiento horizontal» y eran ciertas — miraban el lado que no era.

       Comprobado en vivo neutralizando SOLO esta linea antes de tocar nada:
       Entrar pasa de left −126 a left 195, y el nav cabe entero (12 → 355) sin
       necesitar scroll. La solucion es dejar que aplique styles.css.

       REGLA: dos ficheros arreglando lo mismo con !important no se suman, se
       parten. Antes de añadir un !important sobre un layout, mirar si el otro
       fichero ya lo resolvio. */
    padding: 0 12px !important;
    gap: 8px;
  }
  .topbar .search-bar { display: none !important; }
  .topbar .live-pill { display: none !important; }
  .brand span:nth-of-type(2) { display: none; }
  .weekly-pick-grid { grid-template-columns: 1fr !important; gap: 16px !important; }

  .landing { padding: 32px 18px 60px !important; }
  .hero h1 { font-size: clamp(40px, 11vw, 64px) !important; }
  .hero-row { grid-template-columns: 1fr !important; gap: 24px; }
  .orb-stage { max-width: 360px; margin: 0 auto !important; }
  .metrics-strip { grid-template-columns: 1fr 1fr !important; }
  .feature-grid { grid-template-columns: 1fr !important; }
  .grid-2, .grid-3 { grid-template-columns: 1fr !important; }
  .press-strip .row { grid-template-columns: repeat(2, 1fr) !important; gap: 12px 18px !important; }
  .quotes { grid-template-columns: 1fr !important; }
  .footer { grid-template-columns: 1fr 1fr !important; gap: 24px !important; }
  .footer-base { flex-direction: column; gap: 8px; align-items: flex-start; }
  .cta-cinematic .row { grid-template-columns: 1fr !important; }
  .cta-cinematic { padding: 36px 24px !important; }
  .cta-cinematic h2 { font-size: clamp(28px, 8vw, 40px) !important; }

  /* Dashboard sidebar/right rail collapses to single column */
  .dashboard { grid-template-columns: 1fr !important; }
  .side, .right { border: 0 !important; border-bottom: 1px solid var(--line-soft) !important; }
  .kpi-row { grid-template-columns: 1fr 1fr !important; }

  /* Analysis screen */
  .analysis { padding: 14px 14px 40px !important; }
  .tk-head { grid-template-columns: 1fr !important; gap: 16px !important; }
  .tk-head .symbol .s { font-size: 38px !important; }
  /* 15-oct-2026 · Dos columnas de 166 px en la ficha: el Veredicto (la pick,
     la señal, los tres KPI) medía 869 px de alto en una columna estrecha y la
     celda de al lado, «Fundamental — sin datos», se estiraba otros 654-808 px
     casi vacíos (HURN, AAPL y VWCE.DE, medidos a 375 px). Una columna de
     331 px: cada bloque mide lo que mide su contenido. */
  .verdict { grid-template-columns: minmax(0, 1fr) !important; }
  .meta-strip { font-size: 11px !important; gap: 8px !important; } /* 15-oct-2026: 11, el suelo del móvil (era 10: «Rango 52s», «Vol. medio», ISIN) */

  /* Markets */
  .stage-strip { grid-template-columns: 1fr 1fr !important; }
  .case-grid { grid-template-columns: 1fr !important; }

  /* Pulse widget */
  .pulse { width: calc(100vw - 24px) !important; right: 12px !important; bottom: 12px !important; }
  .pulse.collapsed { width: auto !important; }

  /* AI Quant Agent panel — full width on mobile */
  /* Targeted by the inline style; rule below ensures it stays usable */

  /* Paywall checkout */
  .pw-card { width: calc(100vw - 24px) !important; }
  .ck { grid-template-columns: 1fr !important; }
  .ck-summary { border-right: 0 !important; border-bottom: 1px solid var(--line-soft) !important; }
  .ck-form { padding: 24px 18px !important; }

  /* Auth */
  .auth-card { width: calc(100vw - 24px) !important; padding: 28px 22px !important; }

  /* Settings */
  .settings-body { grid-template-columns: 1fr !important; }
  .settings-page { padding: 18px 14px 40px !important; }
}

/* Tablet */
/* 761 y no 760 (14-sep-2026). Era `min-width: 760px` y este es el UNICO
   `min-width: 760` del proyecto, frente a TREINTA Y CUATRO bloques
   `max-width: 760px` repartidos por seis hojas. A 760 px exactos se aplicaban
   los dos a la vez: el telefono y la tableta, con las reglas de tableta
   ganando por orden de carga — incluida `.right { display: none }` de tres
   lineas mas abajo, que esconde la lista de seguimiento.

   O sea un carril de un pixel de ancho con una maqueta hibrida que no es
   ninguna de las dos. `max-width: 760` y `min-width: 761` no se solapan. */
@media (min-width: 761px) and (max-width: 1080px) {
  .feature-grid { grid-template-columns: 1fr 1fr !important; }
  .grid-3 { grid-template-columns: 1fr 1fr !important; }
  .dashboard { grid-template-columns: 200px 1fr !important; }
  .right { display: none; }
  .kpi-row { grid-template-columns: 1fr 1fr !important; }
}

/* === Skeleton loading state === */
@keyframes skel-shimmer {
  from { background-position: -400px 0; }
  to   { background-position: 400px 0; }
}
.skel {
  background: linear-gradient(90deg, var(--bg-2) 0%, var(--bg-3) 50%, var(--bg-2) 100%);
  background-size: 800px 100%;
  animation: skel-shimmer 1.4s linear infinite;
  border-radius: 8px;
}

/* === Empty-state cards === */
.empty {
  padding: 28px 22px;
  text-align: center;
  color: var(--ink-3);
  font-size: 13px;
  border: 1px dashed var(--line);
  border-radius: 12px;
  background: var(--bg-1);
}

/* === Tighten heavy padding for compact density === */
[data-density="compact"] .card { padding: 12px !important; }
[data-density="compact"] .card-title { margin-bottom: 8px !important; }
[data-density="compact"] .kpi { padding: 11px !important; }
[data-density="compact"] .metric-table td { padding: 6px 0 !important; }

/* === Topbar shrink on narrow viewports === */
@media (max-width: 1180px) {
  .topbar .search-bar { width: 280px !important; }
}

/* === Print stylesheet for PDF capture === */
@media print {
  body { background: white !important; color: black !important; }
  .topbar, .pulse, [data-tweaks-panel], .cookie-banner, .gen-toast,
  .constellation, [class*="aurora"] { display: none !important; }
  .card { break-inside: avoid; page-break-inside: avoid; }
}

/* === Focus visible for accessibility === */
:focus-visible {
  outline: 2px solid var(--focus-ring, var(--accent));
  outline-offset: 2px;
}
button:focus-visible, a:focus-visible, input:focus-visible {
  outline: 2px solid var(--focus-ring, var(--accent));
  outline-offset: 1px;
}

/* === Avatar menu mobile === */
@media (max-width: 760px) {
  .avatar-menu { right: 0 !important; width: calc(100vw - 24px); max-width: 320px; }
}

/* === Pulsing accent border (used by "activate live prices" CTA) === */
@keyframes pulse-border {
  0%, 100% { box-shadow: 0 0 0 0 oklch(0.82 0.13 78 / 0.0); }
  50%      { box-shadow: 0 0 0 4px oklch(0.82 0.13 78 / 0.18); }
}

/* === Resilient TradingView mount (tvkit) === */
.tv-wrap { width: 100%; }
.tv-wrap .tv-fallback { animation: tv-fade-in .3s ease; }
@keyframes tv-fade-in { from { opacity: 0; } to { opacity: 1; } }
.tv-retry:hover { border-color: var(--ink-3) !important; color: var(--ink) !important; }
.tv-open:hover  { background: var(--accent-soft) !important; }

/* === Nano Banana generated visuals === */
@keyframes nano-in { from { opacity: 0; transform: scale(1.04); } to { opacity: 1; transform: scale(1); } }
@keyframes nano-drift {
  0%   { transform: scale(1.06) translate(0, 0); }
  50%  { transform: scale(1.12) translate(-1.5%, -1%); }
  100% { transform: scale(1.06) translate(0, 0); }
}
.nano-drift { animation: nano-in 1s ease both, nano-drift 26s ease-in-out 1s infinite !important; }
@media (prefers-reduced-motion: reduce) { .nano-drift { animation: nano-in 1s ease both !important; } }

/* === MarketBar fallback marquee (when TradingView tape is unavailable) === */
@keyframes mb-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.mb-marquee { animation: mb-scroll 38s linear infinite; }
.mb-fallback:hover .mb-marquee { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .mb-marquee { animation: none; } }

/* ============================================================= */
/* === Entrance polish — cinematic hero atmosphere ============= */
/* ============================================================= */

/* Warm, on-brand gradient mesh for the entry hero (overrides the cooler
   launch.css mesh so the first impression matches the gold/obsidian brand). */
.landing .hero {
  background:
    radial-gradient(ellipse 90% 70% at 50% -25%, oklch(0.82 0.13 78 / 0.13) 0%, transparent 58%),
    radial-gradient(ellipse 70% 55% at 88% 8%,  oklch(0.74 0.15 52 / 0.10) 0%, transparent 55%),
    radial-gradient(ellipse 60% 50% at 8% 92%,  oklch(0.55 0.12 250 / 0.06) 0%, transparent 55%) !important;
}

/* Film grain + soft top-light vignette layered over the hero for depth.
   Decorative only — sits below the headline (z-index:1) and ignores pointer. */
.landing .hero::after {
  content: "";
  position: absolute; inset: -60px -80px;
  pointer-events: none; z-index: 0;
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxNjAnIGhlaWdodD0nMTYwJz48ZmlsdGVyIGlkPSduJz48ZmVUdXJidWxlbmNlIHR5cGU9J2ZyYWN0YWxOb2lzZScgYmFzZUZyZXF1ZW5jeT0nMC45JyBudW1PY3RhdmVzPScyJyBzdGl0Y2hUaWxlcz0nc3RpdGNoJy8+PC9maWx0ZXI+PHJlY3Qgd2lkdGg9JzEwMCUnIGhlaWdodD0nMTAwJScgZmlsdGVyPSd1cmwoI24pJyBvcGFjaXR5PScwLjUnLz48L3N2Zz4=");
  opacity: 0.035;
  mix-blend-mode: overlay;
}
@media (prefers-reduced-motion: no-preference) {
  /* gentle breathing of the orb glow for life on the entry screen */
  .orb-stage .glow { animation: hero-glow-breathe 7s ease-in-out infinite; }
}
@keyframes hero-glow-breathe {
  0%, 100% { opacity: 0.85; transform: scale(1); }
  50%      { opacity: 1; transform: scale(1.06); }
}

/* Nano Banana ambient backdrop behind the entry orb */
.orb-nano {
  position: absolute; inset: 4%;
  border-radius: 50%; overflow: hidden;
  z-index: 0; opacity: 0.5; pointer-events: none;
  mask-image: radial-gradient(circle at 50% 50%, #000 45%, transparent 72%);
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 45%, transparent 72%);
}

/* Eyebrow: a touch more premium on the entry screen */
.landing .hero .eyebrow {
  background: linear-gradient(180deg, oklch(0.16 0.012 80 / 0.9), oklch(0.12 0.01 80 / 0.7));
  box-shadow: 0 1px 0 oklch(0.5 0.05 80 / 0.12) inset, 0 6px 20px oklch(0 0 0 / 0.3);
  backdrop-filter: blur(8px);
}

/* ============================================================= */
/* === Global AI Assistant (floating, Gemini-powered) ========== */
/* ============================================================= */
.ai-fab {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 54px; height: 54px; padding: 0 16px;
  border-radius: 27px; cursor: pointer;
  background: linear-gradient(135deg, oklch(0.82 0.13 78), oklch(0.74 0.15 52));
  color: #161205; border: none;
  box-shadow: 0 8px 28px oklch(0.74 0.15 52 / 0.4), 0 0 0 1px oklch(0.82 0.13 78 / 0.5) inset;
  transition: transform .2s cubic-bezier(.2,.8,.2,1), box-shadow .2s ease;
}
.ai-fab:hover { transform: translateY(-2px) scale(1.04); box-shadow: 0 12px 36px oklch(0.74 0.15 52 / 0.55); }
.ai-fab:active { transform: scale(0.97); }
.ai-fab-dot { width: 8px; height: 8px; border-radius: 50%; background: #161205;
  animation: ai-fab-pulse 1.8s ease-in-out infinite; }
@keyframes ai-fab-pulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .5; transform: scale(1.4); } }

.ai-assistant-panel {
  width: 380px; max-width: calc(100vw - 32px); height: 540px; max-height: calc(100vh - 120px);
  display: flex; flex-direction: column;
  background: oklch(0.13 0.008 260 / 0.97); backdrop-filter: blur(20px) saturate(1.2);
  border: 1px solid var(--accent-line); border-radius: 18px; overflow: hidden;
  box-shadow: 0 24px 70px oklch(0 0 0 / 0.6), 0 0 0 1px oklch(0.82 0.13 78 / 0.1);
  animation: ai-panel-in .26s cubic-bezier(.2,.8,.2,1);
}
@keyframes ai-panel-in { from { opacity: 0; transform: translateY(14px) scale(.97); } to { opacity: 1; transform: none; } }

.ai-as-head { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 13px 15px; border-bottom: 1px solid var(--line-soft);
  background: linear-gradient(135deg, oklch(0.18 0.02 78 / 0.5), transparent); }
.ai-as-avatar { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  background: var(--accent-soft); border: 1px solid var(--accent-line); color: var(--accent); }
.ai-as-keybtn { background: transparent; border: 1px solid var(--line-soft); border-radius: 8px;
  width: 32px; height: 32px; cursor: pointer; font-size: 14px; transition: border-color .2s, background .2s; }
.ai-as-keybtn:hover { border-color: var(--accent-line); background: var(--accent-soft); }

.ai-as-keysetup { padding: 12px 15px; border-bottom: 1px solid var(--line-soft); background: var(--bg-1); }

.ai-as-msgs { flex: 1; overflow-y: auto; padding: 15px; display: flex; flex-direction: column; gap: 12px; }
.ai-as-bubble-avatar { width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0; display: grid; place-items: center;
  font-size: 8.5px; font-weight: 700; font-family: var(--font-mono); }
.ai-as-bubble-avatar[data-role="ai"] { background: var(--accent-soft); border: 1px solid var(--accent-line); color: var(--accent); }
.ai-as-bubble-avatar[data-role="user"] { background: var(--bg-3); border: 1px solid var(--line-soft); color: var(--ink-3); }
.ai-as-bubble { max-width: 82%; padding: 9px 13px; border-radius: 12px; font-size: 12.5px; line-height: 1.6; color: var(--ink-2); }
.ai-as-bubble[data-role="ai"] { background: var(--bg-2); border: 1px solid var(--line-soft); border-top-left-radius: 4px; }
.ai-as-bubble[data-role="user"] { background: oklch(0.82 0.13 78 / 0.12); border: 1px solid var(--accent-line); border-top-right-radius: 4px; color: var(--ink); }
.ai-as-bubble strong { color: var(--accent); font-weight: 700; }

.ai-as-typing { display: inline-flex; gap: 4px; padding: 2px 0; }
.ai-as-typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); opacity: .5; animation: ai-typing 1.2s ease-in-out infinite; }
.ai-as-typing i:nth-child(2) { animation-delay: .2s; } .ai-as-typing i:nth-child(3) { animation-delay: .4s; }
@keyframes ai-typing { 0%,60%,100% { opacity: .3; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-3px); } }

.ai-as-suggest { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 15px 12px; }
.ai-as-suggest button { padding: 6px 11px; border-radius: 14px; border: 1px solid var(--accent-line);
  background: var(--accent-soft); color: var(--accent); font-size: 11px; cursor: pointer; transition: background .2s; font-family: var(--font-sans); }
.ai-as-suggest button:hover { background: oklch(0.82 0.13 78 / 0.18); }

.ai-as-input { display: flex; gap: 8px; padding: 12px 15px; border-top: 1px solid var(--line-soft); background: var(--bg-1); }
.ai-as-input input { flex: 1; padding: 10px 13px; background: var(--bg); border: 1px solid var(--line-soft); border-radius: 10px;
  color: var(--ink); font-size: 13px; outline: none; transition: border-color .2s; }
.ai-as-input input:focus { border-color: var(--accent-line); }
.ai-as-input button { width: 40px; flex-shrink: 0; border-radius: 10px; border: none; cursor: pointer; font-size: 17px; font-weight: 700;
  background: linear-gradient(135deg, oklch(0.82 0.13 78), oklch(0.74 0.15 52)); color: #161205; transition: opacity .2s, transform .1s; }
.ai-as-input button:disabled { opacity: .4; cursor: not-allowed; }
.ai-as-input button:not(:disabled):active { transform: scale(0.92); }

@media (max-width: 760px) {
  .ai-fab { left: 14px; bottom: 14px; }
  .ai-assistant-panel { left: 14px; right: 14px; bottom: 74px; width: auto; height: min(540px, calc(100vh - 110px)); }
}

/* ─── TARJETAS FANTASMA ─────────────────────────────────────────────
   Al apagar los datos inventados de la ficha de análisis, varias
   secciones quedaron con la caja pero sin nada dentro: cuatro
   rectángulos oscuros de 200-320 px de alto, vacíos, en mitad del
   informe. Se veían como un fallo de carga.

   La causa es que el guardián `SIMULADOS &&` envuelve el CONTENIDO,
   no el contenedor, así que React sigue pintando <div class="card">
   sin hijos. Arreglarlo sección por sección obliga a tocar la anidación
   de paréntesis de un fichero compilado — que ya rompí una vez.

   Esto lo resuelve de raíz y de una sola vez: una tarjeta sin un solo
   hijo ni texto no se dibuja. Y protege de las que vengan. */
/* (sustituido: ocultarlas dejaba la columna de la rejilla vacia — ahora se rellenan) */

/* ─── LOS HUECOS NEGROS DE LA FICHA DE ANÁLISIS ─────────────────────
   Medido en producción (AAPL): la tarjeta «QUALITATIVE» tiene 567 px de
   contenido y se dibujaba con 2.567 px de alto. Dos mil píxeles de negro
   en una sola tarjeta. Sus dos hermanas de fila, igual.

   La causa no es contenido que falte: es que las rejillas de tarjetas son
   `display:grid` con `align-items: normal`, que en grid significa
   *stretch*. Cada tarjeta se alarga hasta igualar a la más alta de su
   fila. Con una fila donde una tiene un gráfico de 2.500 px y las otras
   dos tienen cuatro líneas de texto, salen dos columnas casi vacías —
   justo lo que se ve como fondo de constelación.

   `align-self: start` en la tarjeta la deja con su altura natural sin
   tocar la rejilla. En un padre que no sea grid o flex no hace nada, así
   que es seguro aplicarlo a todas.

   Las filas quedan desiguales de abajo. Es lo correcto: una tarjeta mide
   lo que mide su contenido.

   ACOTADO (20-ago): esta regla estaba SIN acotar y afectaba a TODAS las
   pantallas — panel, mercados, señales. Drew reporto que "se ha movido la
   web". El problema de estiramiento que arregla solo se midio en la ficha
   de analisis, asi que no hay motivo para tocar el resto. */
.analysis .card { align-self: start; }

/* ─── LOS CUATRO HUECOS DE LA FICHA ─────────────────────────────────
   Medidos a 1900 px de ancho, que es la pantalla real del dueño. No eran
   el mismo problema repetido: son cuatro causas distintas. */

/* 1 · LA FICHA NO PASABA DE 1480 px
   `.analysis { max-width: 1480px }` en styles.css. En un monitor de 1900
   sobran 420 px de negro en TODO el lateral derecho, de arriba abajo. Ese
   ancho estaba pensado para leer texto, pero esto es una estación de
   trabajo: tablas, mapas de correlación y comparativas agradecen el sitio.
   Se sube el techo y se deja que respire, sin quitarlo del todo — a 2560
   px una línea de 2500 px sería ilegible. */
@media (min-width: 1560px) {
  .analysis { max-width: 1860px !important; }
}

/* 2 · REJILLAS CON UNA SOLA TARJETA
   El mapa de correlación vive en una rejilla de 2 columnas y es el ÚNICO
   hijo: ocupaba una columna y dejaba 602 px negros al lado. Cuando una
   tarjeta está sola en su rejilla, que ocupe todo el ancho. */
.analysis [style*="grid"] > .card:only-child,
.analysis .grid-2 > .card:only-child,
.analysis .grid-3 > .card:only-child { grid-column: 1 / -1; }

/* ── UNA REJILLA DE 3 CON SOLO 2 TARJETAS NO DEJA UNA CELDA MUERTA ───────

   La regla de arriba cubre 1 tarjeta de 3 (`:only-child`). No cubre DOS de
   tres, que es el caso real: en `analysis.js:8506` el hijo del medio (ESG &
   governance) está apagado con `SIMULADOS &&`, así que React no lo pinta y
   quedan 2 tarjetas en 3 columnas.

   La celda vacía medida en producción: 458 × 320 px de fondo negro, en la
   mitad de la ficha. Era el hueco más grande de la pantalla.

   Ni `rellenafichas.js` lo tapaba —sus dos rutas exigen MÁS hijos que
   columnas, y aquí hay menos— ni el `:only-child` de arriba.

   `:nth-child(2):last-child` significa «el segundo hijo es también el
   último», o sea exactamente dos. Sin !important a propósito: las reglas
   de móvil de las líneas 22 y 71 tienen que seguir mandando.

   Cubre también la rejilla gemela de `analysis.js:8246`, que hoy se salva
   solo porque rellenafichas le inserta un panel — si /api/recommendation
   falla, vuelve el hueco.                                                */
.analysis .grid-3:has(> :nth-child(2):last-child) { grid-template-columns: 1fr 1fr; }

/* 3 · TABLAS Y MAPAS QUE NO SE ESTIRAN
   El mapa de correlación usaba 823 px de los 1424 disponibles. La tabla
   tiene ancho natural y no crece. */
.analysis .card > table,
.analysis .card > div > table { width: 100%; }

/* 4 · EL PERFIL DE VOLUMEN INTRADÍA
   Rejilla de 13 columnas con 7 barras: 255 px sin usar a la derecha.
   Repartiendo el ancho entre las que hay, las barras se ensanchan en vez
   de amontonarse a la izquierda. */
.analysis .card > div[style*="grid-template-columns"][style*="repeat"] { width: 100%; }

/* FASE WYCKOFF · el diagrama no se estiraba
   Un flex con el dibujo (96 px) y el texto (395 px) dentro de 857: 348 px
   sin usar. El texto no crecía porque no tenía flex-grow. */
.analysis .card > div[style*="display: flex"] > div:last-child:not(:only-child) { flex: 1 1 auto; min-width: 0; }

/* ── GLOSARIO · los términos que nadie explicaba (2-sep-2026) ───────────────
   Una clienta potencial leyó «Etapa Weinstein 3» y dijo: «suena a que me lo
   tengo que creer sin entenderlo». El subrayado punteado es la señal mínima de
   «esto se puede tocar» sin convertir el párrafo en un campo de enlaces.

   La zona táctil se amplía con padding vertical negativo compensado: en el
   móvil un subrayado de 1 px no se acierta con el dedo. */
.gen-term {
  border-bottom: 1px dotted color-mix(in oklab, var(--accent) 65%, transparent);
  cursor: help;
  padding: 2px 0;
}
.gen-term:hover,
.gen-term:focus-visible {
  border-bottom-color: var(--accent);
  color: var(--accent);
  outline: none;
}
.gen-term:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

.gen-glosario-pop {
  position: fixed;
  z-index: 10000;
  max-width: min(320px, calc(100vw - 24px));
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 14px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .45);
  pointer-events: none;   /* no se interpone: el ratón sigue sobre el término */
}
.gen-glosario-pop .gt-t {
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 5px;
}
.gen-glosario-pop .gt-d {
  font-size: 13px;
  line-height: 1.6;
  color: var(--ink-2);
}

/* ── EL MENU DEL MOVIL: CABIA, PERO SIN AIRE (2-sep-2026) ───────────────────
   Arreglado el desplazamiento, la clienta volvio a mirarlo y dijo: «funciona,
   pero van muy apretados, con la letra pequeña y casi sin aire entre palabras».
   Tenia razon y ademas es medible: la fila del nav media 27 px de alto, por
   debajo del minimo de 44 px para un objetivo tactil.

   NO se puede ensanchar: los seis enlaces ocupan 343 px de los 375 y cualquier
   separacion extra los echa fuera o los manda a un scroll donde se esconden.
   Asi que el aire se da en VERTICAL —que no compite por el ancho— y la zona
   tactil se amplia con un ::after invisible, la misma tecnica que ya rescato al
   boton PULSE en agosto. El texto no se mueve; el dedo tiene donde caer. */
/* ── EL MENÚ DE LA PORTADA, EN MÓVIL, ES UN PANEL (6-sep-2026) ─────────────
   Los seis enlaces —Producto · Motor · Precios · Método · FAQ · Legal— salían
   con la mitad inferior de las letras CORTADA, en todas las pantallas y encima
   del pliegue. Comprobado con zoom sobre cuatro capturas a 375 px.

   La causa no era el ancho: `.app` da al header 56 px FIJOS
   (grid-template-rows: 56px …) y el bloque móvil de styles.css metía el nav en
   una SEGUNDA fila dentro de esa caja. La fila sobraba y se recortaba.

   Los dos intentos anteriores —bajar el nav a su fila con scroll horizontal, y
   darle 44 px de zona táctil con un ::after invisible— eran correctos para el
   problema equivocado: ninguno podía caber en 56 px.

   Con panel, el header vuelve a UNA fila. Cada enlace ocupa una línea entera,
   así que la zona táctil sale sola y el ::after sobra. */

/* Solo en móvil: en escritorio manda el menú horizontal de siempre y la
   hamburguesa no debe verse. Va fuera de la consulta para que el defecto sea
   «oculta» en cualquier ancho que no esté cubierto abajo. */
.nav-burger { display: none; }

@media (max-width: 760px) {
  .nav-burger {
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 40px;
    height: 40px;
    padding: 0 9px;
    border: 1px solid var(--line-soft);
    border-radius: 9px;
    background: transparent;
    cursor: pointer;
    flex-shrink: 0;
  }
  .nav-burger span {
    display: block;
    height: 1.5px;
    border-radius: 2px;
    background: var(--ink-2);
  }
  .nav-burger[aria-expanded="true"] { border-color: var(--accent); }
  .nav-burger[aria-expanded="true"] span { background: var(--accent); }

  /* El panel cuelga del header, que es `position: relative`. Fuera del flujo:
     no puede volver a empujar una segunda fila dentro de los 56 px. */
  .topbar nav.nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 6px;
    background: var(--bg);
    border-bottom: 1px solid var(--line-soft);
    box-shadow: 0 18px 40px rgba(0, 0, 0, .45);
    max-height: calc(100vh - 56px);
    overflow-y: auto;
  }
  .topbar nav.nav[data-abierto="true"] { display: flex; }
  .topbar nav.nav > * {
    width: 100%;
    text-align: left;
    min-height: 44px;
    padding: 11px 12px;
    font-size: 14px;
    border-radius: 8px;
  }
}

/* ── LOS BOTONES FLOTANTES SE APARTAN AL BAJAR (2-sep-2026) ─────────────────
   Medidos cinco solapamientos con texto real en la portada movil. A 375 px no
   hay margen lateral: cualquier sitio fijo esta encima de la columna de texto.

   Se apartan al bajar —cuando lees hacia delante— y vuelven al subir, arriba
   del todo y al fondo. Lo mismo que hace el navegador con su propia barra.
   `flotantes.js` pone y quita la clase; aqui solo esta el movimiento. */
.ai-fab, .pulse, .gen-soporte-fab {
  transition: transform .22s ease, opacity .22s ease;
}
.gen-flotantes-fuera .ai-fab {
  transform: translateY(140%);
  opacity: 0;
  pointer-events: none;
}
.gen-flotantes-fuera .pulse.collapsed {
  transform: translateY(140%);
  opacity: 0;
  pointer-events: none;
}
/* El de soporte se aparta con los otros dos. Dejarlo fijo mientras sus
   vecinos se apartan haria justo lo que este bloque existe para evitar
   —tapar el texto— y ademas pareceria roto. Vuelve en cuanto paras de
   bajar, que es cuando se lee y cuando se busca ayuda. */
.gen-flotantes-fuera .gen-soporte-fab {
  transform: translateY(260%);
  opacity: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .ai-fab, .pulse, .gen-soporte-fab { transition: none; }
}

/* Y en el telefono ocupan menos: 64x54 sobre 375 px de ancho es mucho boton
   para un adorno que no es el producto. 48x48 mantiene el minimo tactil. */
@media (max-width: 760px) {
  .ai-fab {
    width: 48px !important;
    height: 48px !important;
    min-width: 48px !important;
    border-radius: 50% !important;
    font-size: 11px !important;
  }
}

/* ── EL HISTORIAL, EN MÓVIL, DEJA DE SER UNA TABLA (3-sep-2026) ──────────

   Medido a 375 px: la tabla ocupa 760 px dentro de una ventana de 329, así
   que de sus siete columnas solo se ven «Semana» y «Valor». Las cinco que
   quedan fuera son la prueba entera: estado, resultado, días y peor momento.

   Se podía desplazar —el envoltorio es `overflow-x: auto`— pero no había
   ninguna pista de ello: ni sombra, ni flecha, ni texto. Y en un teléfono
   real no hay barra de desplazamiento permanente que lo insinúe. Un dato al
   que solo se llega con un gesto que nadie sugiere es, en la práctica, un
   dato que no está.

   Cada operación pasa a ser una ficha con sus siete campos. No se oculta
   nada: se reordena.

   La etiqueta va en un `::before` ABSOLUTO, no en grid ni flex, porque la
   celda de «Estado» lleva dos `span` y la de «Valor» mezcla texto suelto con
   un `span`. En grid, cada hijo —incluidos los nodos de texto anónimos—
   ocuparía su propia celda y el resultado cambiaría según la fila.

   Los `!important` son obligados: los estilos de la tabla van EN LÍNEA desde
   `React.createElement` (padding, textAlign, whiteSpace, borderBottom y un
   `minWidth: 640`), y un estilo en línea gana a cualquier regla sin él. */

@media (max-width: 640px) {
  /* El envoltorio ya no necesita desplazarse ni pintar su propio marco:
     el marco pasa a cada ficha. */
  .historial-tabla { overflow-x: visible !important; border: 0 !important; border-radius: 0 !important; }
  /* 15-oct-2026: la tabla del historial son tarjetas apiladas, no es ancha: sin
     overflow, para que Safari en iPhone no la pinte como una capa de 3.000 px
     (se quedaba en blanco; ver mobile.css, «.metric-table, table»). */
  .historial-tabla table { min-width: 0 !important; display: block !important; overflow: visible !important; }
  .historial-tabla thead { display: none !important; }
  .historial-tabla tbody { display: block !important; }

  .historial-tabla tbody tr {
    display: block;
    border: 1px solid var(--line-soft);
    border-radius: 12px;
    padding: 4px 12px;
    margin-bottom: 10px;
  }

  .historial-tabla tbody td {
    display: block !important;
    position: relative;
    padding: 8px 0 8px 116px !important;
    min-height: 18px;
    text-align: left !important;
    white-space: normal !important;
    border-bottom: 1px solid var(--line-soft) !important;
  }
  .historial-tabla tbody tr td:last-child { border-bottom: 0 !important; }

  .historial-tabla tbody td::before {
    position: absolute;
    left: 0;
    top: 9px;
    width: 104px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 10px;
    font-weight: 400;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--ink-4);
  }

  /* Las etiquetas salen de la cabecera real de `landing.js`, en su orden.
     `verificar-build.mjs` §12 vuelve a compararlas en cada compilación: si
     alguien añade o mueve una columna y estas no se tocan, cada valor
     quedaría bajo el nombre de otro — que es peor que no poner nombre. */
  .historial-tabla td:nth-child(1)::before { content: "Semana"; }
  .historial-tabla td:nth-child(2)::before { content: "Valor"; }
  .historial-tabla td:nth-child(3)::before { content: "Emitida"; }
  .historial-tabla td:nth-child(4)::before { content: "Estado"; }
  .historial-tabla td:nth-child(5)::before { content: "Resultado"; }
  .historial-tabla td:nth-child(6)::before { content: "Días"; }
  .historial-tabla td:nth-child(7)::before { content: "Peor momento"; }
}

/* ── «VER UN INFORME DE EJEMPLO» NO PARECIA UN BOTON (3-sep-2026) ────────

   Medido a 1280 px sobre los estilos ya calculados:

     Empieza gratis              fondo oklch(0.22 0.008 260)  borde visible
     Ver un informe de ejemplo   fondo rgba(0,0,0,0)          borde 1px SOLID
                                                              rgba(0,0,0,0)

   Un borde de 1 px declarado y completamente transparente, sin fondo y sin
   subrayado, en una caja de 276x47. Se veia texto suelto al lado de un boton.

   Viene de `.btn-ghost`, que es transparente A PROPOSITO: aparece al pasar el
   raton. El patron esta bien; el sitio no. Es el CTA secundario del hero —el
   camino de baja friccion, «mira el producto sin registrarte»— y EN TACTIL NO
   EXISTE EL HOVER: en un telefono no hay ningun estado en el que se dibuje.

   `.btn-ghost` se usa 64 veces en 15 ficheros, asi que no se toca la clase:
   se acotan los dos del hero. polish.css va despues de styles.css en el HTML,
   asi que a igual especificidad gana esta regla. */
.btn-ejemplo {
  border-color: var(--line) !important;
  color: var(--ink-2);
}
.btn-ejemplo:hover { border-color: var(--ink-4) !important; }


/* ── LA TARJETA DE LA PICK EN LA FRANJA DE TABLETA (4-sep-2026) ──────────

   Drew: «se ve pésimo en móvil», con una captura de la tarjeta de la pick
   partida en dos columnas y la derecha cortada.

   A 375 px NO pasa: `.weekly-pick-grid` ya colapsaba a una columna en
   `mobile.css` (720 px) y aquí arriba (760 px). Y el viewport está bien
   declarado —`width=device-width, initial-scale=1`— así que un teléfono
   real entra por debajo del corte. Que en su pantalla salgan DOS columnas
   significa que la está viendo por encima de 760: tableta, móvil apaisado o
   una ventana estrecha de escritorio. Esa franja no la cubría nadie.

   Y el corte de 760 no estaba elegido: estaba heredado. Medido el ancho que
   la columna derecha necesita de verdad, fila a fila, con la fuente real:

     Precio actual .................  141 px
     Stop (emitido) ................  145 px
     Riesgo/Recompensa .............  179 px
     Objetivo (2,0R · emitido) .....  207 px
     Mejor compra · emitida ........  261 px
     Tamaño para arriesgar el 1% ...  293 px   ← la que manda

   Con el reparto 1,3fr / 1fr y 22 px de hueco, 293 de columna derecha exigen
   293 × 2,3 + 22 = 696 px de CONTENIDO, y con el relleno de la tarjeta y del
   panel eso son ~770 px de pantalla — para caber JUSTO, con holgura cero.

   O sea que entre 761 y ~870 px la rejilla mantenía dos columnas que no
   caben. Se sube el corte a 900: por debajo, una sola columna. El número
   sale de la medición, no del gusto — 340 px de holgura razonable por
   columna dan 340 × 2,3 + 22 + 72 ≈ 875, redondeado.

   Va al final del fichero a propósito: la regla de los 760 vive dentro de un
   bloque con muchas otras y moverla arrastraría cosas que no tocan. Al ir
   después y con la misma especificidad, esta gana. */
@media (max-width: 900px) {
  .weekly-pick-grid {
    grid-template-columns: 1fr !important;
    gap: 16px !important;
  }
}

/* ── LOS FLOTANTES Y EL BANNER DE COOKIES YA NO SE PISAN (11-sep-2026) ──────

   Medido en el recorrido anónimo a 390 px (Edge sin cookies ni sesión):

     · el banner de cookies medía 350×220 y tapaba el final del párrafo del
       hero —54.971 px² de texto— en la primera pantalla de un visitante;
     · el botón IA lleva z-index 9000 EN LÍNEA y el banner 80, así que el
       botón quedaba ENCIMA del banner, sobre su propio «Personalizar»;
     · dentro del muro de precios, que es un diálogo modal, el botón IA
       tapaba el título del plan Pro.

   Mientras haya un banner o un diálogo modal delante, los tres flotantes se
   apartan con el mismo movimiento que al bajar (.gen-flotantes-fuera). Con un
   modal abierto el banner también espera: vuelve en cuanto se cierra.

   Va con :has() para no tocar tres ficheros compilados. Un navegador sin :has()
   (anteriores a 2023) ignora la regla y todo queda como estaba. */
body:has(.cookie-banner) .ai-fab,
body:has(.cookie-banner) .pulse,
body:has(.cookie-banner) .gen-soporte-fab,
body:has([aria-modal="true"]) .ai-fab,
body:has([aria-modal="true"]) .pulse,
body:has([aria-modal="true"]) .gen-soporte-fab {
  transform: translateY(140%) !important;
  opacity: 0 !important;
  pointer-events: none !important;
}
body:has([aria-modal="true"]) .cookie-banner {
  display: none !important;
}
/* Y en el teléfono el banner ocupa menos: el mismo texto y los mismos tres
   botones, con menos relleno. */
@media (max-width: 760px) {
  .cookie-banner {
    left: 10px; right: 10px; bottom: 10px;
    padding: 12px 14px; gap: 10px; border-radius: 12px;
  }
  .cookie-text { font-size: 12px; line-height: 1.45; }
  .cookie-actions { gap: 6px; }
  .cookie-actions .btn { padding: 8px 10px; font-size: 12px; min-height: 40px; }
}

/* ── INFORME EN MÓVIL: LA FILA DE BOTONES YA NO SE MONTA (11-sep-2026) ──────

   La cabecera de la ficha es una fila flex con tres grupos —«← Volver» y el
   rótulo; «Imprimir / PDF» y «Compartir»; «Crear alerta», «Imprimir / Guardar
   como PDF» y «Añadir a seguimiento»— y ninguno podía saltar de línea. A
   390 px los textos se montaban unos encima de otros: «Imprimir / PDF» sobre
   el rótulo y «Crear alerta» sobre «Compartir». Es el informe de ejemplo, lo
   primero que ve quien todavía no tiene cuenta.

   Los estilos van en línea en analysis.js y ninguno fija flex-wrap ni gap en
   esas filas, así que basta con permitir el salto aquí. El selector apunta al
   primer hijo de .analysis, que es esa cabecera. */
@media (max-width: 760px) {
  .analysis > div:first-child {
    flex-wrap: wrap;
    gap: 10px;
  }
  .analysis > div:first-child > div {
    flex-wrap: wrap;
  }

  /* 15-oct-2026 · EN DOS COLUMNAS. Con el salto de línea, a 375 px la fila
     ocupaba 289 px en cinco filas (cada botón en la suya) y el veredicto
     empezaba en y=794 de 812: fuera de la primera pantalla. «← Volver» y el
     rótulo van en una fila; los cuatro botones, en una rejilla de dos por
     dos con su zona de toque de 44 px. */
  .analysis > .ficha-acciones {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    align-items: stretch;
    padding-bottom: 14px !important;
  }
  .ficha-acciones > .ficha-acciones-ir {
    grid-column: 1 / -1;
    flex-wrap: nowrap !important;
    min-width: 0;
  }
  .ficha-acciones-ir > .mono { white-space: normal; line-height: 1.35; min-width: 0; }
  .ficha-acciones-ir > button { flex-shrink: 0; white-space: nowrap; min-height: 44px; }
  .ficha-acciones > .ficha-acciones-compartir,
  .ficha-acciones > .ficha-acciones-botones { display: contents !important; }
  .ficha-acciones-compartir > button,
  .ficha-acciones-botones > button {
    width: 100%;
    min-height: 44px;
    align-self: stretch;
    /* En táctil no hay hover: un botón fantasma sin borde se lee como texto. */
    border: 1px solid var(--line-soft) !important;
    font-size: 12.5px !important;
    padding: 8px 10px !important;
    white-space: normal;
    line-height: 1.25;
    text-align: center;
  }
}

/* ── LA CINTA DENTRO DE <main> NO CRECE (11-sep-2026) ───────────────────────
   La cinta pasa a ser el primer hijo de <main> (ver appmain.js). Pero
   «.app > main > *» reparte el alto con flex: 1 1 auto, y la cinta tiene que
   quedarse en sus 46 px: si creciera, se comería la pantalla de debajo. */
.app > main > .gen-marketbar {
  flex: 0 0 46px !important;
}

/* ── EL REGISTRO NO LLEVA BANNER DE COOKIES (11-sep-2026) ───────────────────
   Medido a 390 px: el banner tapaba «Inicia sesión», el sello de sesión
   cifrada y el enlace a la Política de Privacidad, y esa pantalla no hace
   scroll, así que no había forma de llegar a ellos. En el registro no se carga
   nada de terceros —ningún gráfico de TradingView— y el banner vuelve al
   salir de él. */
body:has(.auth-screen) .cookie-banner {
  display: none !important;
}

/* ── EL BANNER SE VA EN CUANTO HAY DECISIÓN (11-sep-2026) ───────────────────
   Los gráficos de TradingView esperan al consentimiento (consentimiento-tv.js)
   y cada hueco tiene su botón «Activar». Si se acepta desde ahí, el banner no
   se entera —su estado vive en React—, así que se oculta por la marca que el
   guardián pone en <html>. */
html[data-cookies="accept"] .cookie-banner,
html[data-cookies="reject"] .cookie-banner {
  display: none !important;
}

/* ── LA LUPA DEL MÓVIL (27-sep-2026) ─────────────────────────────────────
   La barra de búsqueda (.search-bar) se oculta por debajo de 1040 px y la
   paleta solo se abría con el teclado: en un teléfono no había forma de
   buscar un valor. Esta lupa aparece justo en ese tramo y abre la misma
   paleta (appmain.js). 40 px: por encima del mínimo táctil de 44 contando
   el hueco que la rodea, y sin empujar a «Entrar» fuera de la barra. */
.lupa-movil { display: none; }
@media (max-width: 1040px) {
  .topbar .lupa-movil {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; min-width: 40px; flex-shrink: 0;
    margin-left: auto; padding: 0; border-radius: 10px; cursor: pointer;
    background: var(--bg-1); border: 1px solid var(--line-soft); color: var(--ink-2);
  }
  .topbar .lupa-movil:active { border-color: var(--accent); color: var(--accent); }
}

/* ── AUDITORÍA DE DISEÑO DEL 8-OCT-2026 ─────────────────────────────────── */

/* El historial en el teléfono: las operaciones en curso eran una ficha de
   siete campos con cinco guiones («EMITIDA —», «RESULTADO –», «PEOR MOMENTO
   —»). Cuatro así antes de la primera con resultado. Se quedan en semana,
   valor, estado y días: lo que sí se sabe. */
@media (max-width: 640px) {
  .historial-tabla tbody tr.fila-abierta td:nth-child(3),
  .historial-tabla tbody tr.fila-abierta td:nth-child(5),
  .historial-tabla tbody tr.fila-abierta td:nth-child(7) { display: none !important; }
  .historial-tabla tbody tr.fila-abierta td:nth-child(6) { border-bottom: 0 !important; }
}

/* ── LA CARTERA DEL CLIENTE, EN EL TELÉFONO, DEJA DE SER UNA TABLA (15-oct-2026)
   dashboard.js:5581 pinta las posiciones con `minWidth: 680` dentro de un div
   con `overflow-x: auto`. Medido con sesión a 375 px: 680 px de tabla en 345
   de caja, así que de sus diez columnas se ven Símbolo, Empresa y Acciones; el
   precio, el valor, el P&L y el peso —el dinero— quedan fuera, y en un teléfono
   no hay barra que insinúe el arrastre. Misma receta que el historial (arriba):
   cada posición pasa a ser una ficha con sus campos rotulados.

   Y el envoltorio deja de ser desplazable: con cinco posiciones la tabla mide
   1.645 px, y una caja de ese alto con overflow es justo lo que Safari deja en
   blanco en el iPhone (regla del 15-oct en mobile.css). Sin :has() (navegadores
   anteriores a 2023) la tabla sigue en tarjetas y el envoltorio no tiene nada
   que desplazar, así que no pasa nada.

   Los rótulos salen de la cabecera real de dashboard.js, en su orden. Si alguien
   añade o mueve una columna hay que tocar esto a la vez (el historial tiene la
   comprobación en verificar-build.mjs §12; esta tabla aún no). Medido con la
   regla puesta: 345 px de tabla en 345 de caja, 321 px por posición. */
@media (max-width: 760px) {
  .dashboard .center div:has(> table[style*="min-width: 680px"]) { overflow: visible !important; }
  .dashboard .center table[style*="min-width: 680px"] { min-width: 0 !important; display: block; overflow: visible; }
  .dashboard .center table[style*="min-width: 680px"] thead { display: none; }
  .dashboard .center table[style*="min-width: 680px"] tbody { display: block; }
  .dashboard .center table[style*="min-width: 680px"] tbody tr { display: block; border: 1px solid var(--line-soft); border-radius: 12px; padding: 4px 12px; margin: 0 12px 10px; }
  .dashboard .center table[style*="min-width: 680px"] tbody td { display: block; position: relative; padding: 7px 0 7px 116px !important; min-height: 18px; text-align: left !important; border-bottom: 1px solid var(--line-soft); }
  .dashboard .center table[style*="min-width: 680px"] tbody td:last-child { border-bottom: 0; padding-left: 0 !important; }
  .dashboard .center table[style*="min-width: 680px"] tbody td > div { justify-content: flex-start !important; }
  .dashboard .center table[style*="min-width: 680px"] tbody td::before { position: absolute; left: 0; top: 8px; width: 104px; font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-4); }
  .dashboard .center table[style*="min-width: 680px"] td:nth-child(1)::before { content: "Símbolo"; }
  .dashboard .center table[style*="min-width: 680px"] td:nth-child(2)::before { content: "Empresa"; }
  .dashboard .center table[style*="min-width: 680px"] td:nth-child(3)::before { content: "Acciones"; }
  .dashboard .center table[style*="min-width: 680px"] td:nth-child(4)::before { content: "Coste medio"; }
  .dashboard .center table[style*="min-width: 680px"] td:nth-child(5)::before { content: "Precio"; }
  .dashboard .center table[style*="min-width: 680px"] td:nth-child(6)::before { content: "Stop"; }
  .dashboard .center table[style*="min-width: 680px"] td:nth-child(7)::before { content: "Valor"; }
  .dashboard .center table[style*="min-width: 680px"] td:nth-child(8)::before { content: "P&L"; }
  .dashboard .center table[style*="min-width: 680px"] td:nth-child(9)::before { content: "Peso"; }
}

/* El foco con teclado, con el color de la casa y en todas partes igual. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
@media (forced-colors: active) { :focus-visible { outline-color: Highlight; } }

/* Titulares sin una palabra suelta en la última línea, párrafos sin viudas, y
   las cifras con el mismo ancho para que no bailen al actualizarse. */
h1, h2, h3 { text-wrap: balance; }
.landing p, .landing li, .screen-pad p { text-wrap: pretty; }
.mono, td, .num { font-variant-numeric: tabular-nums; }

/* Las respuestas largas de las preguntas frecuentes, a un ancho que se lee. */
.landing details p, .landing details div { max-width: 72ch; }

/* El segundo botón flotante de IA («Q»): se aparta al bajar, como los demás
   (flotantes.js solo conocía tres), y deja el violeta que no es de la casa. */
.gen-quant-fab { transition: transform .22s ease, opacity .22s ease; background: var(--bg-2) !important; border: 1px solid var(--accent-line, var(--accent)) !important; color: var(--accent) !important; }
.gen-flotantes-fuera .gen-quant-fab { transform: translateY(260%); opacity: 0; pointer-events: none; }
/* Y espera, como los otros flotantes, mientras el aviso de cookies está en
   pantalla: en la primera visita quedaba debajo de él (9-oct-2026). */
body:has(.cookie-banner) .gen-quant-fab,
body:has([aria-modal="true"]) .gen-quant-fab { transform: translateY(260%) !important; opacity: 0 !important; pointer-events: none !important; }

/* ── EL BUSCADOR DE LA BARRA NO PISA EL RELOJ (8-oct-2026) ───────────────────
   Con seis pestañas en el menú, a 1.280 px al buscador le quedan 104 px y su
   contenido pide 157: la tecla «Ctrl K» se salía 53 px por la derecha y se
   pintaba ENCIMA de «NYSE ABIERTO» (se leía «Ctr|NYSE ABIERTO»; lo vio el
   dueño en su captura). El buscador recorta lo suyo y, por debajo de
   1.500 px, la pista de teclado no se pinta: el atajo sigue funcionando. */
.topbar .search-bar { overflow: hidden; min-width: 0; }
.topbar .search-bar .placeholder { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 1500px) {
  .topbar .search-bar > span:not(.placeholder) { display: none !important; }   /* lleva display en línea */
}
/* Y por debajo de 1.240 px no cabe ni «Buscar…» (se leía «B»): queda la lupa,
   que es un botón igual de claro. */
@media (max-width: 1240px) {
  .topbar .search-bar { width: auto !important; padding: 7px 10px; }
  .topbar .search-bar .placeholder { display: none; }
}

/* ── EL FINAL DE CADA PANTALLA QUEDA POR ENCIMA DE LOS BOTONES FLOTANTES (8-oct-2026)
   Al llegar abajo del todo, las últimas líneas (en Señales, las tres notas
   sobre cómo leer la lista) quedaban debajo de los botones de ayuda y de IA,
   que tapaban el principio de cada una. Un hueco al final las deja libres.
   Va en un ::after y no en un padding porque varias pantallas traen el suyo
   escrito en línea. */
.app > main > .screen::after { content: ""; display: block; height: 84px; }

/* ── EN ESCRITORIO, NADA POR DEBAJO DE 10 PX (8-oct-2026) ────────────────────
   El suelo de 11 px se puso solo en móvil (styles.css) con este argumento:
   «una etiqueta mono de 9 px en versalitas es una decisión de diseño a 60 cm».
   Medido en escritorio el 8-oct: en el Panel hay texto a 7, 7,5, 8 y 8,5 px
   («● 13F REAL», «CONV.», «372 ABREN») y en la ficha los cinco factores del
   veredicto van a 7,5 px y la escala de los analistas a 8. Eso no es una
   decisión de diseño a ninguna distancia. El suelo de escritorio es 10 px:
   lo que ya estaba en 10 no se toca y la jerarquía se queda como estaba. */
@media (min-width: 761px) {
  .app [style*="font-size: 7px"], .app [style*="font-size: 7.5px"],
  .app [style*="font-size: 8px"], .app [style*="font-size: 8.5px"],
  .app [style*="font-size: 9px"], .app [style*="font-size: 9.5px"] { font-size: 10px !important; }
  .dash-orb-label, .ai-as-bubble-avatar { font-size: 10px; }
  /* Lo que se inyecta como HTML (rellenafichas.js, quantkit.js) escribe el
     estilo sin espacio tras los dos puntos, y la regla de arriba no lo veía. */
  .app [style*="font-size:7px"], .app [style*="font-size:7.5px"],
  .app [style*="font-size:8px"], .app [style*="font-size:8.5px"],
  .app [style*="font-size:9px"], .app [style*="font-size:9.5px"] { font-size: 10px !important; }


  /* LOS BOTONES FLOTANTES TAPABAN EL PIE DE LA BARRA LATERAL DEL PANEL: el
     último enlace de las listas y la ficha del propio usuario (su nombre y su
     plan) quedaban debajo de «?» y de «IA», siempre. La barra termina antes y
     deja ese hueco para ellos; sus listas hacen scroll por dentro. */
  .dashboard > aside.side { margin-bottom: 132px; }
}

/* LA PROSA, A 12 PX COMO MÍNIMO (15-oct-2026), en todos los anchos. La
   reauditoría del 9-oct midió el 81 % del texto del Panel a 12 px o menos.
   Las etiquetas en versalitas (.mono) son una decisión de diseño y se quedan
   (en el móvil, con el suelo de 11 px de styles.css); lo que no lo es son las
   frases que explican el plan, el historial o una señal a 10,5-11,5 px.
   Medido en el Panel, la ficha, Señales, Mercados, Macro, Fondos, Alertas y
   Ajustes a 1366x800, y en la portada, el Panel y la ficha a 375x812:
   ningún texto nuevo cortado ni desbordado. Pesa más que el suelo del móvil
   (que deja 10,5 en 11,5) a propósito. */
.app main [style*="font-size: 10.5px"]:not(.mono):not(.mono *),
.app main [style*="font-size: 11px"]:not(.mono):not(.mono *),
.app main [style*="font-size: 11.5px"]:not(.mono):not(.mono *) { font-size: 12px !important; }

/* ── EL AVISO DE COOKIES NO SE PINTA DENTRO DE UNA CINTA (9-oct-2026) ─────
   La cinta de cotizaciones tiene repuesto propio con datos reales
   (.mb-fallback): mientras TradingView espera al permiso, se enseña ese y
   no «TradingView · pendiente de tu permiso de cookies · Activar». El
   permiso se sigue dando en el aviso de cookies y en cada gráfico, que sí
   lo necesita. El elemento se queda en el DOM: la cinta lo usa para saber
   que TradingView está retenido (professional.js, cinematic.js). */
.gen-marketbar .gen-tv-retenido,
.ticker-tape-wrap .gen-tv-retenido { display: none !important; }

/* ── EL AVISO DE COOKIES NO TAPA EL BOTÓN PRINCIPAL EN EL MÓVIL (9-oct-2026) ──
   Medido en la reauditoría de diseño: a 375x812 el aviso medía 184 px y
   tapaba la mitad de «Crear cuenta gratis» (y=595-641) en la primera visita.
   legal.js lleva dos textos; aquí se enseña el corto en el teléfono. */
.cookie-corto { display: none; }
/* 16-oct-2026: el párrafo de presentación de la portada, igual (landing.js). */
.lede-corto { display: none; }
@media (max-width: 760px) {
  .lede-largo { display: none; }
  .lede-corto { display: inline; }
}
@media (max-width: 760px) {
  .cookie-largo { display: none; }
  .cookie-corto { display: inline; }
  .cookie-banner { padding: 10px 12px; gap: 8px; }
}

/* ── EL AVISO, EN TRES LÍNEAS Y UNA FILA DE BOTONES (12-oct-2026) ──────────
   La #91 alargó el texto del aviso y el párrafo de la portada, y el botón
   «Crear cuenta gratis» (y=622-668 a 375x812) volvía a quedar debajo del
   aviso (161 px, desde y=641). En el teléfono: letra de 12 px, el enlace a
   la política dentro de la línea (sin su relleno de 10 px) y los tres
   botones en una fila de 40 px. Queda en ~118 px, por debajo del botón. */
@media (max-width: 760px) {
  .cookie-banner .cookie-text { font-size: 12px; line-height: 1.4; }
  .cookie-banner .cookie-text .auth-link { display: inline !important; padding: 0 !important; min-height: 0 !important; font-size: inherit; }
  .cookie-banner .cookie-actions { gap: 6px; flex-wrap: nowrap; }
  .cookie-banner .cookie-actions .btn { font-size: 11px !important; padding: 6px 6px !important; min-height: 40px; white-space: nowrap; flex: 1 1 auto; }
}

/* ── LA BARRA DE PILARES DE LA CONCLUSIÓN, EN EL MÓVIL (15-oct-2026) ──────
   Cada pilar ocupa un ancho proporcional a su nota: en 291 px «Institucional
   91» quedaba en 70 px y «Flujo 46» en 35, cortados con «…». En el móvil van
   en dos columnas, con la barra de color y el rótulo entero debajo. */
@media (max-width: 760px) {
  .pilares-conclusion { flex-wrap: wrap; row-gap: 10px; column-gap: 12px !important; }
  .pilares-conclusion > div { flex: 0 0 calc(50% - 6px) !important; }
  .pilares-conclusion .mono { white-space: normal !important; overflow: visible !important; }
}
