/* Aumento general de tamaño de letra (16-jul-2026, ronda 39, pedido
   explicito de Diego: "aumenta el tamaño de letra" a toda la pagina +
   "los subtitulos deben ser mas visibles"). Todos los font-size de este
   archivo estaban en px fijo (no rem), asi que se subieron uno por uno
   ~10-15% en vez de un solo valor global -- no hay una unica variable de
   escala que los cubra a todos. Ademas de subir tamaño, los "subtitulos"
   (.subhead, th, .metric .label, .match-meta, .liga-meta) que usaban
   --text-muted (el gris mas apagado) se pasaron a --text-secondary (mas
   claro) para que de verdad se noten mas, no solo que midan mas.
   --text-muted se deja para texto realmente secundario (.note, badges) --
   no se cambio la paleta completa a proposito. */
:root{
  /* Refresh visual (27-jul-2026, ronda 94, pedido explicito de Diego:
     "se ve como pagina chafa, no inspira confianza... interactiva y
     profesional"). Direccion elegida en vivo con 3 rondas de mockups
     comparativos (ver conversacion) -- el fondo casi negro plano (#080b12)
     resultaba en "sin color todavia", no "diseñado a proposito". Grafito
     elevado: mismo espiritu oscuro, pero un tono mas claro y con mas
     separacion entre pagina/superficie/superficie-elevada. Los colores de
     deporte (--tenis/--mlb/etc, mas abajo) NO cambian -- siguen siendo
     categoricos (que deporte es este partido), no de marca. */
  --bg:#14161c;
  --surface-1:#20222c;
  --surface-2:#292c38;
  --surface-3:#323644;
  --border:#3a3e4d;
  --border-strong:#525768;
  --text-primary:#eef1f7;
  --text-secondary:#98a4bf;
  --text-muted:#5c6883;

  /* Acento de marca (ronda 94) -- antes el chrome generico (logo, botones,
     link de login, pestañas activas) usaba --tenis "de rebote" porque era
     el primer color de deporte de la lista, sin ser una decision real de
     marca -- confundia "esto es tenis" con "esto es una accion/marca".
     Ambar dorado elegido explicitamente por Diego sobre grafito elevado,
     comparado en vivo contra violeta/teal/cian. Los usos de --tenis como
     color de deporte (tabs, borde de match-card, etc.) no se tocan. */
  --accent:#d9a536; --accent-hover:#e8b34a; --accent-bg:#2b2210; --accent-text:#f0c05e;
  /* Alias para var(--card-bg, #16181d) que ya vivia suelto en
     AgregarApuestaFAB.jsx/ChatbotWidget.jsx sin nunca definirse de verdad
     -- siempre caian al valor de respaldo hardcodeado. Ahora resuelve a la
     superficie real. */
  --card-bg:var(--surface-2);

  --tenis:#22b8a6; --tenis-bg:#0c2b28; --tenis-text:#6fe3d2;
  --mlb:#e0913c; --mlb-bg:#2e1f0c; --mlb-text:#f2b96a;
  --mundial:#4caf6e; --mundial-bg:#122d1a; --mundial-text:#7fe0a0;
  /* Auditoria 26-jul-2026 (ronda 59): futbol_clubes nunca tuvo su propio
     color desde que se agrego (ronda 13) -- solo el tab combinado "futbol"
     de PartidosDelDia.jsx (que agrupa Mundial+clubes) reusaba el verde de
     Mundial. NHL/NFL tampoco tenian, agregados en las rondas 56/57 sin
     este detalle visual. Colores nuevos, sin repetir tono con los ya
     existentes. */
  --futbol-clubes:#7b61ff; --futbol-clubes-bg:#1c1730; --futbol-clubes-text:#b3a3ff;
  --nhl:#3ba7e0; --nhl-bg:#0c2230; --nhl-text:#7cc9f2;
  --nfl:#c0392b; --nfl-bg:#2e0f0c; --nfl-text:#f2a08a;

  --success:#31b578; --success-bg:#0f2b21; --success-text:#5ee0a0;
  --danger:#e05a56; --danger-bg:#331414; --danger-text:#f18e8b;
  --amber:#e0a83c; --amber-bg:#2c2210; --amber-text:#f2c977;
  --radius:10px;

  /* Sombras de elevacion (ronda 94, subidas de intensidad el mismo dia --
     Diego probo el primer intento y "no veo que se vea mas interactivo":
     una sombra oscura sobre un fondo YA oscuro practicamente no se
     percibe, sin importar que este ahi de verdad -- confirmado con
     getComputedStyle, el problema no era que faltara, era que no se veia.
     Fix real de dos partes: (1) el "inset" de arriba, una linea clara de
     1px casi invisible que simula luz pegandole al borde superior de la
     tarjeta -- el truco estandar de profundidad en interfaces oscuras,
     mucho mas perceptible que una sombra externa sobre fondo oscuro; (2)
     sombras externas bastante mas opacas que antes. Dos niveles: reposo
     (visible pero discreta) y "lift" al pasar el mouse (notoriamente mas
     marcada, para que "esto responde" se sienta sin ambiguedad). */
  --shadow-card:inset 0 1px 0 rgba(255,255,255,.045), 0 2px 5px rgba(0,0,0,.55), 0 10px 26px -8px rgba(0,0,0,.7);
  --shadow-lift:inset 0 1px 0 rgba(255,255,255,.07), 0 4px 10px rgba(0,0,0,.6), 0 22px 46px -12px rgba(0,0,0,.8);
}
*{box-sizing:border-box;}
/* Respeta la preferencia de movimiento reducido (ronda 94) -- las
   transiciones/transforms nuevos de este refresh (hover-lift, chevron,
   pulso "en vivo") son decorativos, no funcionales -- se apagan enteros
   para quien lo pida a nivel sistema operativo. */
@media (prefers-reduced-motion: reduce){
  *{transition-duration:.001ms !important; animation-duration:.001ms !important; animation-iteration-count:1 !important;}
}
body{margin:0; background:var(--bg); color:var(--text-primary); font-family:-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif; line-height:1.5;}
.app{display:grid; grid-template-columns:222px 1fr; min-height:100vh;}
/* Sidebar fija al hacer scroll (17-jul-2026, ronda 56, pedido explicito
   de Diego: "que la sidebar se quede estatica en todo momento aunque el
   usuario scrolee para abajo"). El scroll de la pagina lo genera `.main`
   (mas alto que el viewport en paginas largas como "Partidos del dia"),
   mientras `.app` sigue siendo un grid de una sola fila -- `position:
   sticky; top:0` alcanza porque el contenedor de scroll es la ventana
   misma, no un contenedor interno. `height:100vh` + `overflow-y:auto` es
   por si el propio contenido de la sidebar (nav + footer de usuario)
   llegara a medir mas que la pantalla en algun momento -- se scrollea ella
   sola en vez de empujar/cortar el resto. */
/* Compactado (01-ago-2026, ronda 133, pedido explicito de Diego: "quiero
   que el sidebar se vea bien y no que sea tipo subir y bajar para ver
   todo") -- con "Manual de usuario" (ronda 129) sumado a los 4 items
   admin-only, la sidebar de un admin ya no cabia completa en pantallas de
   laptop tipicas (~800-900px de alto) con el espaciado original, forzando
   el scroll interno (`overflow-y:auto` de arriba, pensado como salvavidas
   para el caso raro, no como el estado normal). Se redujo padding/gap del
   contenedor, del brand, y de cada item -- 11 items + brand + footer ahora
   caben sin scroll en la mayoria de resoluciones reales.*/
.sidebar{background:var(--surface-1); border-right:1px solid var(--border); padding:14px 14px; display:flex; flex-direction:column; gap:2px; position:sticky; top:0; height:100vh; overflow-y:auto;}
.brand{display:flex; align-items:center; gap:10px; padding:4px 10px 14px;}
.brand .dot{width:9px; height:9px; border-radius:50%; background:var(--accent);}
.brand-name{font-size:16px; font-weight:700;}
.brand-sub{font-size:12.5px; color:var(--text-muted);}
.nav-item{position:relative; display:flex; align-items:center; gap:10px; padding:7px 12px; border-radius:8px; font-size:14px; color:var(--text-secondary); cursor:pointer; border:1px solid transparent; transition:background .15s ease,color .15s ease;}
.nav-item svg{flex-shrink:0; opacity:.85; transition:opacity .15s ease;}
.nav-item:hover svg, .nav-item.active svg{opacity:1;}
.nav-item:hover{background:var(--surface-2); color:var(--text-primary);}
/* Indicador activo (ronda 94) -- antes solo un borde plano alrededor del
   item; ahora una barra de acento a la izquierda con leve resplandor,
   mismo lenguaje visual que se aprobo en el mockup. */
.nav-item.active{background:var(--surface-2); color:var(--text-primary); border-color:var(--border-strong);}
.nav-item.active::before{content:""; position:absolute; left:-14px; top:8px; bottom:8px; width:3px; border-radius:0 3px 3px 0; background:var(--accent); box-shadow:0 0 10px 1px rgba(217,165,54,.45);}
.main{padding:22px 28px 60px; max-width:1260px;}
.topbar{display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:18px; gap:16px; flex-wrap:wrap;}
.topbar h1{font-size:22px; font-weight:700; margin:0 0 4px;}
.topbar .sub{font-size:14px; color:var(--text-muted);}
.sport-tabs{display:flex; gap:6px; margin-bottom:18px;}
.sport-tab{font-size:14.5px; padding:8px 16px; border-radius:8px; cursor:pointer; color:var(--text-secondary); border:1px solid var(--border); font-weight:700; background:transparent;}
.sport-tab.active[data-sport="tenis"]{background:var(--tenis-bg); color:var(--tenis-text); border-color:var(--tenis);}
.sport-tab.active[data-sport="mlb"]{background:var(--mlb-bg); color:var(--mlb-text); border-color:var(--mlb);}
.sport-tab.active[data-sport="mundial"]{background:var(--mundial-bg); color:var(--mundial-text); border-color:var(--mundial);}
/* Tab combinada "Futbol" en Partidos del dia (Mundial + futbol_clubes
   juntos, 16-jul-2026 ronda 33) -- reusa el mismo verde de Mundial. */
.sport-tab.active[data-sport="futbol"]{background:var(--mundial-bg); color:var(--mundial-text); border-color:var(--mundial);}
/* Auditoria 26-jul-2026 (ronda 59): tabs "Fútbol clubes"/NHL/NFL (Picks.jsx,
   MisApuestas.jsx, AgregarApuestaFAB.jsx) nunca tuvieron su propio color --
   caian en el estilo default sin marcar cual esta activo. */
.sport-tab.active[data-sport="futbol_clubes"]{background:var(--futbol-clubes-bg); color:var(--futbol-clubes-text); border-color:var(--futbol-clubes);}
.sport-tab.active[data-sport="nhl"]{background:var(--nhl-bg); color:var(--nhl-text); border-color:var(--nhl);}
.sport-tab.active[data-sport="nfl"]{background:var(--nfl-bg); color:var(--nfl-text); border-color:var(--nfl);}
.grid-cards{display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:14px; margin-bottom:22px;}
.metric{background:var(--surface-1); border:1px solid var(--border); border-radius:var(--radius); padding:16px 18px; box-shadow:var(--shadow-card); transition:transform .16s ease,border-color .16s ease,background .16s ease,box-shadow .16s ease;}
.metric:hover{transform:translateY(-3px); border-color:var(--accent); background:var(--surface-2); box-shadow:var(--shadow-lift);}
.metric .label{font-size:13px; color:var(--text-secondary); text-transform:uppercase; letter-spacing:.5px; margin-bottom:6px;}
.metric .value{font-size:25px; font-weight:700; font-variant-numeric:tabular-nums; letter-spacing:-.3px;}
.tourney-header{display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; padding:12px 16px; margin:22px 0 10px; border-radius:var(--radius); background:var(--surface-2); border-left:3px solid var(--tenis);}
.tourney-name{font-size:16.5px; font-weight:700;}
.tourney-meta{font-size:13.5px; color:var(--text-secondary); margin-top:2px;}
.tier-badge{font-size:12px; font-weight:700; padding:4px 10px; border-radius:999px; letter-spacing:.3px; background:var(--surface-3); color:var(--text-secondary);}
.match-card{border:1px solid var(--border); border-radius:var(--radius); background:var(--surface-1); margin-bottom:12px; overflow:hidden; box-shadow:var(--shadow-card); transition:transform .16s cubic-bezier(.2,.8,.2,1),box-shadow .16s ease,border-color .16s ease;}
.match-card:hover{transform:translateY(-4px); box-shadow:var(--shadow-lift); border-color:var(--accent);}
.match-card .match-head{transition:background .15s ease;}
.match-card.sport-tenis{border-top:2px solid var(--tenis);}
.match-card.sport-mlb{border-top:2px solid var(--mlb);}
.match-card.sport-mundial{border-top:2px solid var(--mundial);}
.match-card.sport-futbol_clubes{border-top:2px solid var(--futbol-clubes);}
.match-card.sport-nhl{border-top:2px solid var(--nhl);}
.match-card.sport-nfl{border-top:2px solid var(--nfl);}
.match-head{display:flex; align-items:center; justify-content:space-between; gap:14px; padding:14px 16px; cursor:pointer;}
.match-head:hover{background:var(--surface-2);}
.match-players{font-size:16px; font-weight:700;}
.match-meta{font-size:13px; color:var(--text-secondary); margin-top:2px;}
/* Barras de probabilidad del modelo por jugador/equipo (ronda 94b) --
   antes solo se veia el % dentro de "Pick del modelo", una vez expandida
   la tarjeta; ahora se ve de un vistazo en el encabezado, mismo dato
   (`pick.prob_modelo`), sin llamada extra. */
.match-prob-bars{display:flex; flex-direction:column; gap:4px; margin-top:8px; max-width:260px;}
.match-prob-row{display:flex; align-items:center; gap:8px; font-size:12.5px;}
.match-prob-nombre{color:var(--text-secondary); flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.probbar{width:64px; height:4px; border-radius:99px; background:var(--surface-3); overflow:hidden; flex-shrink:0;}
.probbar > span{display:block; height:100%; border-radius:99px; background:var(--accent);}
.match-prob-pct{font-weight:700; font-variant-numeric:tabular-nums; min-width:32px; text-align:right; flex-shrink:0;}
/* Mejor pick del partido (ronda 105) -- solo se renderiza si el backend
   mando `mejor_pick` (partido no finalizado + al menos un mercado supera
   el umbral de Kelly, ver casa_pdt.py::mejor_pick_partido) -- por eso no
   hace falta un estado "vacio" aqui, simplemente no se dibuja nada. */
.match-best-pick{display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; margin-top:8px; font-size:12.5px;}
.mbp-mercado{color:var(--text-secondary);}
.mbp-mercado b{color:var(--text-primary); font-weight:700;}
.mbp-stat{font-variant-numeric:tabular-nums; color:var(--text-muted); white-space:nowrap;}
.mbp-lbl{margin-right:4px;}
.match-right{display:flex; align-items:center; gap:10px;}
.chevron{font-size:12.5px; color:var(--text-muted); transition:transform .15s,color .15s; display:inline-block;}
.match-card.open .chevron{transform:rotate(90deg);}
.match-card:not(.open):hover .chevron{transform:translateX(2px); color:var(--text-secondary);}
.match-body{border-top:1px solid var(--border); padding:16px; background:var(--surface-1);}
.badge{font-size:12px; font-weight:700; padding:3px 9px; border-radius:999px; letter-spacing:.3px;}
.badge-high{background:var(--success-bg); color:var(--success-text); border:1px solid #1c6b40;}
.badge-medium{background:var(--amber-bg); color:var(--amber-text); border:1px solid #5a4520;}
.badge-low{background:var(--danger-bg); color:var(--danger-text); border:1px solid #4a2222;}
.badge-neutral{background:var(--surface-3); color:var(--text-secondary); border:1px solid var(--border-strong);}
/* Badge "EN VIVO" con punto de pulso (ronda 94) -- antes era un badge
   estatico igual a cualquier otro estado; el pulso comunica "esto esta
   pasando ahora mismo" de un vistazo, sin tener que leer el texto. */
.badge-live{background:var(--danger-bg); color:var(--danger-text); border:1px solid #4a2222; display:inline-flex; align-items:center; gap:6px;}
.badge-live::before{content:""; width:6px; height:6px; border-radius:50%; background:var(--danger); box-shadow:0 0 0 3px rgba(224,90,86,.25); animation:pulso-vivo 1.8s ease-in-out infinite;}
@keyframes pulso-vivo{0%,100%{box-shadow:0 0 0 3px rgba(224,90,86,.25);} 50%{box-shadow:0 0 0 6px rgba(224,90,86,.08);}}
.badge-proj{background:var(--amber-bg); color:var(--amber-text); border:1px solid #5a4520;}
.badge-conf{background:var(--success-bg); color:var(--success-text); border:1px solid #1c6b40;}
.edge-pos{color:var(--success); font-weight:700; font-variant-numeric:tabular-nums;} .edge-neg{color:var(--danger); font-weight:700; font-variant-numeric:tabular-nums;}
/* Envoltorio de scroll horizontal para tablas (26-jul-2026, ronda 69) --
   varias tablas (historial, momios, admin) tienen mas columnas de las que
   caben en un telefono en vertical; en vez de forzar un reflow de tabla
   (rompe la alineacion columna-por-columna), se deja hacer scroll lateral
   solo dentro de la tabla, sin mover el resto de la pagina. */
.table-scroll{overflow-x:auto; -webkit-overflow-scrolling:touch;}
table{width:100%; border-collapse:collapse; font-size:14px;}
th,td{padding:8px 9px; text-align:left; border-bottom:1px solid var(--border);}
th{color:var(--text-secondary); font-weight:700; font-size:13px; text-transform:uppercase; letter-spacing:.4px;}
td.num, th.num{text-align:right;}
td.num{font-variant-numeric:tabular-nums;}

/* Tablas -> tarjetas en telefono (29-jul-2026, ronda 125, pedido explicito
   de Diego: "tengo un iphone 17 pro... hay varias opciones que no puedo
   ver como tal en la pantalla porque se salen del cuadro, entonces tengo
   que scrollear hacia los lados, esto pasa principalmente en la sección
   de picks o similares donde hay tablas largas horizontalmente... no se
   que tengas que hacer pero arreglalo"). La ronda 69 eligio scroll lateral
   DENTRO de la tabla en vez de reacomodar filas -- funciona para tablas
   donde se compara una columna entre varias filas (ROI historico, admin),
   pero en Picks el patron de lectura real es "leer UN pick completo a la
   vez" (partido/mercado/lado/edge/ev/kelly juntos), no comparar una
   columna sola hacia abajo -- ahi SI conviene la tarjeta.
   Opt-in via `.tabla-responsive` (no se aplica a TODAS las `.table-scroll`
   de la app a la fuerza, solo a las que ya tienen sus `<td data-label>`
   puestos) -- cada fila se convierte en una tarjeta vertical: la cabecera
   de la tabla se oculta (ya redundante, la etiqueta va en cada celda via
   `data-label`) y cada celda muestra su propia etiqueta a la izquierda,
   el valor a la derecha. Ancho de telefono real (iPhone 17 Pro no-Max,
   ~390px de viewport) -- 640px de corte cubre eso con margen sin afectar
   tablets/iPad (>=768px, donde la tabla normal ya cabe bien). */
@media (max-width: 640px) {
  .tabla-responsive thead{display:none;}
  .tabla-responsive, .tabla-responsive tbody{display:block; width:100%;}
  .tabla-responsive tr{
    display:block; border:1px solid var(--border-strong); border-radius:var(--radius);
    background:var(--surface-2); padding:10px 12px; margin-bottom:10px;
  }
  .tabla-responsive td{
    display:flex; justify-content:space-between; align-items:center; gap:10px;
    padding:6px 0; border-bottom:1px solid var(--border); text-align:right;
  }
  .tabla-responsive td:last-child{border-bottom:none;}
  .tabla-responsive td[data-label]::before{
    content:attr(data-label); font-weight:700; font-size:12px; color:var(--text-secondary);
    text-transform:uppercase; letter-spacing:.4px; text-align:left; flex-shrink:0;
  }
  /* El numero de fila ("#") no vale la pena como renglon propio de la
     tarjeta -- se oculta explicitamente (por clase, no por "sin
     data-label" a secas, para no esconder por accidente una celda a la
     que se le olvide poner la etiqueta). */
  .tabla-responsive td.tabla-num-fila{display:none;}
}
.cmp-grid{display:grid; grid-template-columns:1fr 1fr; gap:16px;}

/* Navegacion movil (26-jul-2026, ronda 69) -- ver el comentario en
   Sidebar.jsx para el porque. En escritorio (>860px) estas reglas no
   hacen nada (mobile-topbar/backdrop en display:none, .sidebar sigue
   sticky de toda la vida); todo el comportamiento nuevo vive dentro del
   media query de abajo. */
.mobile-topbar{display:none;}
.sidebar-backdrop{display:none;}

@media(max-width:860px){
  .cmp-grid{grid-template-columns:1fr;}
  .app{grid-template-columns:1fr;}

  .mobile-topbar{
    display:flex; align-items:center; justify-content:space-between; gap:10px;
    position:fixed; top:0; left:0; right:0; z-index:110;
    background:var(--surface-1); border-bottom:1px solid var(--border);
    padding:12px 14px;
  }
  .mobile-topbar-brand{font-size:15px; font-weight:700;}
  .mobile-topbar-spacer{width:34px;}
  .hamburger-btn{
    background:transparent; border:1px solid var(--border-strong); color:var(--text-primary);
    border-radius:8px; font-size:18px; line-height:1; padding:6px 10px; cursor:pointer;
  }

  /* La sidebar pasa de columna fija (sticky) a cajon (drawer) que entra
     desde la izquierda -- position:fixed la saca del grid de `.app` (las
     cajas fuera de flujo no cuentan como grid item), asi que `.main` puede
     ocupar el ancho completo sin dejar un hueco de 222px. */
  .sidebar{
    position:fixed; top:0; left:0; height:100vh; width:250px; max-width:82vw;
    transform:translateX(-100%); transition:transform .2s ease; z-index:200;
    box-shadow:2px 0 24px rgba(0,0,0,.5);
  }
  .sidebar.open{transform:translateX(0);}
  .sidebar-backdrop.open{
    display:block; position:fixed; inset:0; background:rgba(0,0,0,.55); z-index:150;
  }

  .main{padding:70px 14px 90px;}
}
.subhead{font-size:14.5px; color:var(--text-secondary); text-transform:uppercase; letter-spacing:.5px; margin:16px 0 8px; font-weight:700;}
.pick-box{background:var(--surface-2); border:1px solid var(--border-strong); border-radius:var(--radius); padding:14px 16px; margin-top:10px; box-shadow:var(--shadow-card);}
.pick-row{display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:10px;}
.pick-name{font-size:16px; font-weight:700;}
.pick-meta{font-size:13px; color:var(--text-secondary); margin-top:3px;}
.note{font-size:13px; color:var(--text-muted); margin-top:8px;}
.hist-row{display:flex; justify-content:space-between; align-items:center; padding:7px 0; border-bottom:1px solid var(--border); font-size:14px;}
.hist-result{font-weight:700; width:20px; text-align:center; border-radius:5px; font-size:12.5px; padding:2px 0;}
.hist-w{background:var(--success-bg); color:var(--success-text);}
.hist-l{background:var(--danger-bg); color:var(--danger-text);}
.hist-e{background:var(--border); color:var(--text-secondary);}
.pbp-row{display:flex; gap:12px; padding:7px 0; border-bottom:1px solid var(--border); font-size:14px;}
.pbp-inning{width:38px; flex-shrink:0; color:var(--mlb); font-weight:700;}
.pbp-text{color:var(--text-secondary);}

/* Pestañas Resumen/Estadísticas/Punto a punto al estilo Flashscore
   (16-jul-2026, ronda 30 -- correccion de Diego: el "box tipo flashscore"
   era por esta navegacion en pestañas, no por las barras de colores). */
.match-tabs{display:flex; gap:4px; margin-bottom:14px; border-bottom:1px solid var(--border);}
.match-tab{background:transparent; border:none; border-bottom:2px solid transparent; color:var(--text-secondary); font-size:14px; font-weight:700; padding:8px 14px; cursor:pointer;}
.match-tab:hover{color:var(--text-primary);}
.match-tab.active{color:var(--text-primary); border-bottom-color:var(--accent);}

/* Box de estadisticas al estilo Flashscore (16-jul-2026, ronda 30) --
   ver StatBox/StatRow en MatchCard.jsx. */
.stat-box{background:var(--surface-2); border:1px solid var(--border-strong); border-radius:var(--radius); padding:14px 16px; margin-top:10px; box-shadow:var(--shadow-card);}
.stat-box-head{display:flex; justify-content:space-between; align-items:center; font-size:14px; font-weight:700; padding-bottom:10px; margin-bottom:8px; border-bottom:1px solid var(--border);}
.stat-row{padding:8px 0; border-bottom:1px solid var(--border);}
.stat-row:last-child{border-bottom:none;}
.stat-row-values{display:flex; justify-content:space-between; align-items:center; font-size:14.5px; gap:10px;}
.stat-row-values .stat-val{font-weight:700; min-width:48px; flex-shrink:0; font-variant-numeric:tabular-nums;}
.stat-row-values .stat-val:last-child{text-align:right;}
.stat-label{color:var(--text-secondary); font-size:13px; text-align:center; flex:1;}
.stat-bar-track{display:flex; height:5px; border-radius:999px; overflow:hidden; margin-top:6px; background:var(--surface-3);}
.stat-bar-fill-a{background:var(--accent); height:100%;}
.stat-bar-fill-b{background:var(--border-strong); height:100%;}
.state-msg{color:var(--text-muted); font-size:14.5px; padding:20px 0;}

/* Results Tracker */
.roi-value.pos{color:var(--success);}
.roi-value.neg{color:var(--danger);}
/* Grafica de profit -- enmarcada + tooltip interactivo (28-jul-2026,
   ronda 112, pedido explicito de Diego: "que la gráfica esté enmarcada o
   algo para que se vea más profesional... interactiva"). Mismo lenguaje
   visual que .metric/.pick-box (surface + border + shadow-card), no un
   estilo nuevo. */
/* Ancho maximo (01-ago-2026, ronda 134, pedido explicito de Diego: "el
   recuadro que la enmarca debería ser poco más ancha que la gráfica") --
   antes esta tarjeta no tenia limite de ancho, asi que estiraba al 100%
   de `.main` (hasta 1260px), mucho mas ancha que el SVG de adentro (tope
   640px via `maxWidth` inline) -- dejaba un area vacia enorme a la
   derecha, y ademas hacia que el tooltip (posicionado en % relativo a
   ESTA tarjeta, ver GraficaProfit) se desalineara del punto real. 640
   (svg) + 2*18 (padding horizontal de esta misma regla) = 676.*/
.grafica-profit-card{background:var(--surface-1); border:1px solid var(--border); border-radius:var(--radius); padding:16px 18px 10px; box-shadow:var(--shadow-card); max-width:676px;}
/* left/top/transform reales se fijan inline por instancia (siguen el
   punto resaltado en X e Y, ver GraficaProfit -- ronda 112b) */
.grafica-tooltip{position:absolute; background:var(--surface-3); border:1px solid var(--border-strong); border-radius:8px; padding:6px 10px; font-size:12.5px; line-height:1.3; pointer-events:none; white-space:nowrap; box-shadow:var(--shadow-lift); z-index:1;}
.grafica-tooltip-fecha{color:var(--text-secondary); font-size:11px; margin-bottom:2px;}
.grafica-tooltip-valor{font-weight:700; font-variant-numeric:tabular-nums;}
.tracker-form{display:flex; gap:8px; align-items:center; flex-wrap:wrap;}
.tracker-input{background:var(--surface-3); border:1px solid var(--border-strong); color:var(--text-primary); border-radius:7px; padding:6px 10px; font-size:14px; min-width:200px;}
.tracker-select{background:var(--surface-3); border:1px solid var(--border-strong); color:var(--text-primary); border-radius:7px; padding:6px 10px; font-size:14px;}
.btn{background:var(--surface-3); border:1px solid var(--border-strong); color:var(--text-primary); border-radius:7px; padding:6px 14px; font-size:14px; font-weight:700; cursor:pointer; transition:border-color .15s ease,color .15s ease,background .15s ease,transform .1s ease,box-shadow .15s ease;}
.btn:hover{border-color:var(--accent); color:var(--accent-text); background:var(--surface-2); box-shadow:0 0 0 1px var(--accent);}
.btn:active{transform:scale(.98);}
.btn:disabled{opacity:.5; cursor:not-allowed;}
.btn-danger-txt{color:var(--danger-text); font-size:13px; margin-top:6px;}
/* Boton "Borrar" con chrome de boton real (29-jul-2026, ronda 116, pedido
   explicito de Diego: "el boton que dice borrar hay que cambiar el como
   se ve, no queda nada acorde con la app") -- antes usaba
   `.btn-danger-txt`, que solo pone color de texto sin quitar el chrome
   nativo del navegador (fondo/borde grises por defecto de un <button> sin
   estilo), por eso se veia fuera de lugar. Se usa junto con `.btn` (mismo
   padding/radius/tipografia que cualquier otro boton de la app), solo
   que este selector puntual sobreescribe el color para dejarlo en tono
   de peligro. */
.btn.btn-danger{border-color:#4a2222; color:var(--danger-text);}
.btn.btn-danger:hover{border-color:var(--danger); color:var(--danger-text); background:var(--danger-bg); box-shadow:0 0 0 1px var(--danger);}
/* Stake de "Mis Apuestas" mas visible (29-jul-2026, ronda 116, pedido
   explicito de Diego: "siento que no se ve practicamente nada el stake
   seleccionado") -- antes usaba `.note` (gris tenue, pensado para texto
   secundario/de contexto), aqui el stake es un dato clave para leer una
   apuesta de un vistazo, asi que se deja en el color de texto normal en
   vez de atenuado. */
.stake-destacado{color:var(--text-primary); font-weight:700;}
.badge-open{background:var(--surface-3); color:var(--text-secondary); border:1px solid var(--border-strong);}
/* Boton "Ver todas las fechas" (29-jul-2026, ronda 119, pedido explicito
   de Diego: "el boton que dice quitar filtro de dia... simplemente se ve
   feo... quiero que sea algo bien hecho") -- antes usaba `.btn-danger-txt`
   (pensada para texto de error, sin chrome de boton real, mismo problema
   ya corregido en "Borrar"/"Cancelar", rondas 116/117) Y ademas el rojo de
   "peligro" no tenia sentido aqui: quitar un filtro no es una accion
   destructiva. Estilo "ghost"/chip discreto -- borde sutil, fondo
   transparente, se resalta en el color de acento (mismo lenguaje de hover
   que el resto de los botones .btn) solo al pasar el mouse, para que no
   compita visualmente con las acciones principales de la pantalla. Ver
   BotonLimpiarFiltroFecha.jsx (componente compartido, un solo lugar para
   las 2 pantallas donde aparece). */
.btn-limpiar-filtro{display:inline-flex; align-items:center; gap:5px; background:transparent; border:1px solid var(--border); color:var(--text-secondary); border-radius:7px; padding:4px 10px; font-size:12.5px; font-weight:600; cursor:pointer; transition:border-color .15s ease,color .15s ease,background .15s ease;}
.btn-limpiar-filtro:hover{border-color:var(--accent); color:var(--accent-text); background:var(--surface-2);}
.btn-limpiar-filtro svg{flex-shrink:0;}

/* Login / Solicitar acceso */
.login-wrap{display:flex; justify-content:center; padding:40px 16px;}
.login-card{width:100%; max-width:380px; background:var(--surface-1); border:1px solid var(--border); border-radius:var(--radius); padding:28px; display:flex; flex-direction:column; gap:4px; box-shadow:var(--shadow-lift);}
.login-brand{display:flex; align-items:center; gap:10px; margin-bottom:18px;}
.login-card h1{font-size:18.5px; margin:0 0 14px;}
.login-label{font-size:13px; color:var(--text-muted); text-transform:uppercase; letter-spacing:.4px; margin:10px 0 4px;}
.login-input{width:100%; min-width:0;}
.login-btn{margin-top:18px; width:100%; padding:9px 0; font-size:14.5px;}
.login-switch{margin-top:16px; font-size:13.5px; color:var(--text-secondary); text-align:center;}
.login-link{color:var(--accent-text); cursor:pointer; font-weight:700;}
.login-link:hover{text-decoration:underline;}

/* Cumplimiento obligatorio de seguridad (27-jul-2026, ronda 87) -- overlay
   bloqueante, sin boton de cerrar, cubre toda la pantalla por encima de la
   sidebar y el contenido mientras falte cambiar contraseña o activar 2FA. */
.cumplimiento-overlay{position:fixed; inset:0; z-index:500; background:rgba(0,0,0,.72); display:flex; align-items:center; justify-content:center; overflow:auto; padding:24px;}
.cumplimiento-texto{font-size:13.5px; color:var(--text-secondary); margin:0 0 10px; line-height:1.4;}

/* Aviso de advertencia reutilizable (27-jul-2026, ronda 94c, pedido
   explicito de Diego sobre la pantalla de desactivar 2FA: "tienes que
   poner una advertencia... para que la gente sepa que va a pasar") -- a
   diferencia de .cumplimiento-texto (texto secundario, facil de pasar por
   alto), esto es un bloque marcado con el color de aviso (ambar) y un
   borde de acento, para una consecuencia que el usuario debe notar antes
   de continuar, no solo informacion de fondo. */
.aviso-box{background:var(--amber-bg); border:1px solid #5a4520; border-left:3px solid var(--amber); border-radius:var(--radius); padding:12px 14px; margin:0 0 14px; font-size:13.5px; color:var(--amber-text); line-height:1.45;}
.aviso-box strong{color:var(--text-primary);}
.cumplimiento-qr{width:200px; height:200px; align-self:center; background:#fff; padding:8px; border-radius:8px; margin:6px 0;}
.cumplimiento-uri{font-size:11px; word-break:break-all; color:var(--text-muted); margin-bottom:8px;}
.cumplimiento-backup-codes{font-family:monospace; font-size:14px; background:var(--surface-2); padding:12px; border-radius:8px; display:grid; gap:4px; margin:8px 0;}

/* Pagina Seguridad (27-jul-2026, ronda 87) */
.seguridad-grid{display:grid; grid-template-columns:repeat(auto-fit, minmax(320px, 1fr)); gap:16px; align-items:start;}
.seguridad-card{padding:20px; display:flex; flex-direction:column; gap:4px;}
.seguridad-card h3{margin:0 0 10px; font-size:16px;}

/* Manual de usuario (29-jul-2026, ronda 129) -- mismo lenguaje visual que
   el resto de la app (.metric/.pick-box: surface + border + shadow-card),
   solo con su propia grilla de botones y el marco del diagrama SVG. */
.manual-grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(230px, 1fr)); gap:12px; margin-bottom:22px;}
.manual-tema-btn{display:flex; gap:12px; align-items:flex-start; background:var(--surface-1); border:1px solid var(--border); border-radius:var(--radius); padding:14px 16px; cursor:pointer; box-shadow:var(--shadow-card); transition:transform .16s ease,border-color .16s ease,background .16s ease,box-shadow .16s ease;}
.manual-tema-btn:hover{transform:translateY(-3px); border-color:var(--accent); background:var(--surface-2); box-shadow:var(--shadow-lift);}
.manual-tema-btn.active{border-color:var(--accent); background:var(--accent-bg);}
.manual-tema-icono{color:var(--text-secondary); flex-shrink:0; margin-top:2px;}
.manual-tema-btn.active .manual-tema-icono{color:var(--accent-text);}
.manual-tema-titulo{font-weight:700; font-size:14.5px; margin-bottom:2px;}
.manual-tema-resumen{font-size:12.5px; color:var(--text-muted); line-height:1.4;}
.manual-panel{background:var(--surface-2); border:1px solid var(--border-strong); border-radius:var(--radius); padding:20px 22px; box-shadow:var(--shadow-card);}
.manual-panel p{font-size:14.5px; line-height:1.55; color:var(--text-secondary); margin:0 0 14px;}
.manual-diagrama{width:100%; height:auto; max-width:640px; display:block; margin:14px 0; background:var(--surface-1); border:1px solid var(--border); border-radius:var(--radius); padding:6px; box-sizing:border-box;}
.manual-lista{font-size:14px; line-height:1.6; color:var(--text-secondary); padding-left:20px; margin:0 0 16px;}
.manual-lista li{margin-bottom:6px;}
.manual-lista strong{color:var(--text-primary);}

/* Sidebar footer (usuario logueado) */
.sidebar-footer{margin-top:auto; padding-top:10px; border-top:1px solid var(--border); display:flex; flex-direction:column; gap:6px;}
.sidebar-user{display:flex; align-items:center; justify-content:space-between; padding:0 12px; font-size:14px;}
.sidebar-user-name{color:var(--text-secondary); font-weight:700;}
.sidebar-logout{width:100%; font-size:13px; padding:7px 0;}

/* Boton flotante "+" para agregar apuesta (AgregarApuestaFAB.jsx). En
   escritorio se recorre a la derecha de la sidebar fija (222px + margen);
   en movil la sidebar es un cajon que no ocupa espacio real, asi que se
   recorre al borde izquierdo como cualquier boton flotante (26-jul-2026,
   ronda 69 -- antes tenia left:246 fijo por inline style sin importar el
   ancho de pantalla). */
.fab-agregar{
  position:fixed; bottom:24px; left:246px; z-index:1000;
  width:52px; height:52px; border-radius:50%; border:none;
  background:var(--success); color:#fff; font-size:28px; font-weight:700;
  line-height:52px; text-align:center; cursor:pointer; padding:0;
  box-shadow:0 4px 14px rgba(0,0,0,.35);
}
@media(max-width:860px){.fab-agregar{left:16px;}}

/* Boleto de apuestas (bet slip) - flotante, fijo abajo a la derecha */
.betslip{
  position:fixed; bottom:16px; right:16px; width:320px; max-width:90vw;
  background:var(--surface-1); border:1px solid var(--border-strong); border-radius:var(--radius);
  box-shadow:0 8px 28px rgba(0,0,0,.45); z-index:50; overflow:hidden;
}
.betslip-header{
  display:flex; align-items:center; justify-content:space-between; padding:12px 14px;
  background:var(--surface-2); cursor:pointer; font-weight:700; font-size:14.5px;
}
.betslip-body{padding:12px 14px; max-height:60vh; overflow-y:auto;}
.betslip-legs{display:flex; flex-direction:column; gap:8px;}
.betslip-leg{
  display:flex; align-items:flex-start; justify-content:space-between; gap:8px;
  background:var(--surface-2); border:1px solid var(--border); border-radius:8px; padding:8px 10px;
}
.betslip-leg-desc{font-size:14px; color:var(--text-primary); line-height:1.35;}

/* Acordeon estilo Flashscore para "Partidos del dia" (14-jul-2026,
   decimoseptima ronda) -- reemplaza el drill-down de 2 pantallas por una
   lista de torneos donde cada uno se expande/colapsa en el mismo lugar. */
.liga-lista{display:flex; flex-direction:column; gap:8px;}
.liga-grupo{border:1px solid var(--border); border-radius:var(--radius); background:var(--surface-1); overflow:hidden; box-shadow:var(--shadow-card); transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease;}
.liga-grupo:hover{transform:translateY(-3px); box-shadow:var(--shadow-lift); border-color:var(--accent);}
.liga-header{display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; padding:10px 14px; cursor:pointer; background:var(--surface-2); transition:background .15s ease;}
.liga-header:hover{background:var(--surface-3);}
.liga-titulo{display:flex; align-items:center; gap:8px; min-width:0; flex-wrap:wrap;}
.liga-nombre{font-size:15px; font-weight:700; color:var(--text-primary);}
.liga-meta{font-size:13px; color:var(--text-secondary);}
.liga-body{padding:8px 10px 10px; display:flex; flex-direction:column; gap:8px; border-top:1px solid var(--border);}
.chevron.abierto{transform:rotate(90deg);}

/* Agrupador de region (Mundo/Europa/pais) para el tab combinado de
   Futbol (Mundial + ligas de clubes), estilo playdoit -- 16-jul-2026,
   ronda 33, pedido explicito de Diego. Un nivel arriba de .liga-grupo,
   fondo un poco mas marcado para diferenciar el nivel. */
.region-grupo{border:1px solid var(--border); border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow-card); transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease;}
.region-grupo:hover{transform:translateY(-3px); box-shadow:var(--shadow-lift); border-color:var(--accent);}
.region-header{display:flex; align-items:center; justify-content:space-between; gap:12px; padding:10px 14px; cursor:pointer; background:var(--surface-3); font-weight:700; font-size:15px; transition:background .15s ease;}
.region-header:hover{filter:brightness(1.05);}
.region-body{padding:8px; display:flex; flex-direction:column; gap:8px;}
