/* ============================================================
   Cripto Bot — sistema visual
   Paleta "instrumento": fondo verde-azulado profundo, acento
   turquesa para acciones, ámbar reservado SOLO al modo real,
   verde/rojo reservados SOLO a dinero (P&L). Nada más usa esos
   colores.

   El diseño es "móvil primero de verdad": en pantalla pequeña la
   navegación baja a una barra inferior al alcance del pulgar y la
   configuración larga se esconde tras un botón de engranaje, que
   era lo que dejaba kilómetros de formulario debajo de cada bot.
   ============================================================ */

/* El fondo es negro de fábrica: es lo que menos cansa mirando gráficos a
   oscuras y lo que menos gasta en pantallas OLED, que son casi todas las de
   móvil. El azulado de siempre sigue disponible en Mi perfil -> Fondo.
   Solo cambian los grises: el turquesa de las acciones, el ámbar del modo
   real y el verde/rojo del dinero son los mismos en los dos, porque su
   significado no depende del fondo. */
:root {
  --base: #000000;
  --base-2: #08090b;
  --surface: #121316;
  --surface-2: #1a1b1f;
  --line: #2b2d33;
  --line-soft: #1f2126;

  --text: #e7e9ea;
  --text-dim: #99a0a6;
  --text-faint: #676e75;

  --accent: #3ac7b4;
  --accent-dim: #1f7f74;
  --live: #f2a93b;
  --up: #4ed07e;
  --down: #f2635f;

  --r: 10px;
  --r-sm: 6px;
  --sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --display: "Space Grotesk", var(--sans);
  --mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;
  --shadow: 0 8px 24px rgba(0, 0, 0, 0.35);

  /* Muescas y barras del sistema en móvil. Sin esto el contenido se mete
     debajo del notch y de la barra de gestos. */
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  /* En horizontal la muesca se va a un lado, así que también hay laterales.
     Es la postura natural para mirar un gráfico, y sin esto el precio se
     metía debajo del notch al girar el teléfono. */
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --tabbar-h: 58px;
}

/* El fondo de siempre, para quien lo prefiera. */
:root[data-tema="azulado"] {
  --base: #0e1a1e;
  --base-2: #122329;
  --surface: #16292f;
  --surface-2: #1c333a;
  --line: #24424b;
  --line-soft: #1b343b;

  --text: #dfeaec;
  --text-dim: #8ba5ac;
  --text-faint: #5d777f;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--base);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  /* Instalada como app, el rebote elástico deja ver el fondo del navegador
     y parece que la pantalla se rompe. */
  overscroll-behavior-y: none;
}

/* Nadie hace zoom con dos dedos para leer una tabla: la deja doble-tocando
   sin querer. Se desactiva solo el doble toque, el pellizco sigue. */
button, .btn, .nav a, .tab, .chip { touch-action: manipulation; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { font-family: var(--display); font-weight: 600; letter-spacing: -0.01em; margin: 0; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: 0.98rem; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------------------------------------------------- estructura */
.shell { display: flex; min-height: 100vh; min-height: 100dvh; }

.side {
  width: 224px;
  flex: 0 0 224px;
  background: var(--base-2);
  border-right: 1px solid var(--line-soft);
  padding: 20px 14px;
  display: flex;
  flex-direction: column;
  gap: 26px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.brand { display: flex; align-items: center; gap: 10px; padding: 0 6px; }
.brand-mark {
  width: 26px; height: 26px; border-radius: 7px; flex: 0 0 26px;
  background: linear-gradient(150deg, var(--accent), var(--accent-dim));
  display: grid; place-items: center;
  font-family: var(--mono); font-size: 13px; font-weight: 700; color: #06181a;
}
.brand-name { font-family: var(--display); font-weight: 600; font-size: 0.95rem; }
.brand-sub { font-family: var(--mono); font-size: 0.62rem; color: var(--text-faint);
  letter-spacing: 0.14em; text-transform: uppercase; }

.nav { display: flex; flex-direction: column; gap: 2px; }
.nav a {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px; border-radius: var(--r-sm);
  color: var(--text-dim); font-size: 0.9rem; text-decoration: none;
}
.nav a:hover { background: var(--surface); color: var(--text); text-decoration: none; }
.nav a.on { background: var(--surface-2); color: var(--text); box-shadow: inset 2px 0 0 var(--accent); }
.nav svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 1.7;
  flex: 0 0 17px; }

/* Grupo del panel: un título y debajo sus dos destinos, simulación y real.
   Que estén separados no es estética: es lo que impide arrancar con dinero
   de verdad creyendo que estás en la demo. */
.nav-group { margin-bottom: 4px; }
.nav-group > .nav-title {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px 5px; color: var(--text-faint);
  font-family: var(--mono); font-size: 0.62rem;
  letter-spacing: 0.14em; text-transform: uppercase;
}
.nav-group .sub a { padding-left: 38px; font-size: 0.86rem; }
.nav-group .sub a .punto {
  width: 7px; height: 7px; border-radius: 50%; flex: 0 0 7px;
  background: var(--accent-dim); margin-left: -18px;
}
.nav-group .sub a.real .punto { background: var(--live); }
.nav-group .sub a.on.real { box-shadow: inset 2px 0 0 var(--live); }

.side-foot { margin-top: auto; font-size: 0.78rem; color: var(--text-faint); }
.side-foot a { color: var(--text-dim); }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* Barra de modo: el elemento de seguridad del panel.
   Se pone ámbar y anuncia el estado cuando hay dinero real en juego. */
.modebar {
  display: flex; align-items: center; gap: 14px;
  padding: 9px 24px;
  background: var(--base-2);
  border-bottom: 1px solid var(--line-soft);
  font-family: var(--mono); font-size: 0.74rem;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-faint);
}
.modebar.real { background: #2a1f0c; border-bottom-color: #6b4d15; color: var(--live); }
.modebar .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text-faint);
  flex: 0 0 7px; }
.modebar.real .dot { background: var(--live); animation: pulso 2s infinite; }
.modebar .live-on { background: var(--up); }
.modebar .sep { margin-left: auto; display: flex; gap: 16px; align-items: center; }

@keyframes pulso { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { .modebar.real .dot { animation: none; } }

.content { padding: 24px; max-width: 1400px; width: 100%; }
.page-head { display: flex; align-items: flex-end; gap: 16px; margin-bottom: 20px; flex-wrap: wrap; }
.page-head p { margin: 4px 0 0; color: var(--text-dim); font-size: 0.9rem; }
.page-head .right { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }

/* Barra superior, barra inferior y hoja del menú: solo existen en móvil.
   La hoja llevaba su `display:none` DENTRO del bloque de móvil, así que en
   pantalla grande se pintaba como un bloque más y el menú entero aparecía
   repetido al final de la página. Ocultarla aquí es lo correcto: el bloque de
   móvil la vuelve a mostrar cuando lleva la clase `.on`. */
.topbar, .tabbar, .btn-menu, .hoja { display: none; }

/* ---------------------------------------------------- tarjetas */
.card {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r);
  padding: 18px;
}
.card + .card { margin-top: 16px; }
.card-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
.card-head .right { margin-left: auto; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

.grid { display: grid; gap: 16px; }
.g-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.split { display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: 16px; align-items: start; }

/* ---------------------------------------------------- métricas */
.stat { background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--r); padding: 14px 16px; }
.stat .k { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-faint); }
.stat .v { font-family: var(--mono); font-size: 1.45rem; font-weight: 600;
  font-variant-numeric: tabular-nums; margin-top: 3px; }
.stat .s { font-size: 0.78rem; color: var(--text-dim); }

.pos { color: var(--up); }
.neg { color: var(--down); }
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
/* Referencia en dólares bajo una cifra en otra moneda. Pequeña y apagada a
   propósito: la cifra que manda es la de la moneda real del par. */
.usd { font-family: var(--mono); font-size: 0.72rem; color: var(--text-faint);
  display: block; margin-top: 2px; min-height: 1em; }

/* ---------------------------------------------------- pestañas */
.tabs { display: flex; gap: 6px; margin-bottom: 18px; flex-wrap: wrap; }
.tab {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 16px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface);
  color: var(--text-dim); font-size: 0.87rem; font-weight: 500;
  cursor: pointer; text-decoration: none;
}
.tab:hover { color: var(--text); text-decoration: none; }
.tab .punto { width: 7px; height: 7px; border-radius: 50%; background: var(--accent-dim); }
.tab.real .punto { background: var(--live); }
.tab.on { background: var(--surface-2); color: var(--text); border-color: var(--accent); }
.tab.on.real { border-color: var(--live); color: var(--live); }
.tab .cuenta { font-family: var(--mono); font-size: 0.7rem; color: var(--text-faint); }

/* ---------------------------------------------------- bots */
.bot-list { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); }

/* El "riel de estado": franja vertical que codifica el estado real del bot. */
.bot {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r);
  padding: 16px 16px 14px 20px;
  overflow: hidden;
}
.bot::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--line);
}
.bot.run::before { background: var(--accent); }
.bot.run.live::before { background: var(--live); }
.bot.err::before { background: var(--down); }

/* Las fichas se recogen. Con cinco o seis bots abiertos el panel no cabía en
   pantalla y encontrar el que buscas era bajar y bajar. Plegada, cada ficha
   es una línea con lo único que se mira de reojo: cuánto lleva ganado y si
   está operando. */
.bot > summary { cursor: pointer; list-style: none; }
.bot > summary::-webkit-details-marker { display: none; }
.bot > summary::before {
  content: "▸"; color: var(--text-faint); font-size: 0.8rem;
  display: inline-block; transition: transform 0.15s; margin-right: 2px;
}
.bot[open] > summary::before { transform: rotate(90deg); }
.bot > summary:hover .bot-name { color: var(--accent); }
.bot-resumen {
  margin-left: auto; display: flex; align-items: baseline; gap: 10px;
  font-family: var(--mono); font-size: 0.8rem; font-variant-numeric: tabular-nums;
}
.bot-resumen .hint { font-size: 0.7rem; }
/* Abierta, esas dos cifras ya salen enteras más abajo: repetirlas en la
   cabecera solo hace ruido. */
.bot[open] .bot-resumen { display: none; }
.bot > summary .btn-icono { margin-left: auto; }

.bot-top { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.bot-name { font-family: var(--display); font-weight: 600; font-size: 1rem; }
.bot-pair { font-family: var(--mono); font-size: 0.78rem; color: var(--text-dim); }
.bot-meta { font-size: 0.8rem; color: var(--text-dim); margin: 6px 0 12px; }
.bot-figs { display: flex; gap: 18px; margin-bottom: 12px; flex-wrap: wrap; }
.bot-figs div { min-width: 0; }
.bot-figs .k { font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-faint); }
.bot-figs .v { font-family: var(--mono); font-size: 1rem; font-variant-numeric: tabular-nums; }
.bot-actions { display: flex; gap: 6px; flex-wrap: wrap; }

/* ---------------------------------------------------- etiquetas */
.tag {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.09em;
  text-transform: uppercase; padding: 2px 7px; border-radius: 4px;
  border: 1px solid var(--line); color: var(--text-dim);
}
.tag.paper { border-color: var(--accent-dim); color: var(--accent); }
.tag.live { border-color: var(--live); color: var(--live); background: rgba(242, 169, 59, 0.1); }
.tag.run { border-color: var(--up); color: var(--up); }
.tag.err { border-color: var(--down); color: var(--down); }
.tag.acum { border-color: #7a6ad0; color: #a99bf0; }

/* ---------------------------------------------------- formularios */
label { display: block; font-size: 0.78rem; color: var(--text-dim); margin-bottom: 5px; }
input, select, textarea {
  width: 100%; min-width: 0; padding: 8px 10px;
  background: var(--base); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  font-family: var(--mono); font-size: 0.85rem;
}
input:focus, select:focus, textarea:focus { border-color: var(--accent); outline: none; }
input[type="checkbox"] { width: auto; accent-color: var(--accent); }
.field { margin-bottom: 12px; }
.row { display: grid; gap: 10px; grid-template-columns: 1fr 1fr; }
.row-3 { display: grid; gap: 10px; grid-template-columns: repeat(3, 1fr); }
.hint { font-size: 0.75rem; color: var(--text-faint); margin-top: 4px; }

/* Mando de reparto de las ganancias: el número tiene que verse mientras se
   arrastra, o no se sabe dónde se ha soltado. */
input[type="range"] { width: 100%; accent-color: var(--accent); padding: 0; }
.reparto { font-size: 0.85rem; color: var(--text); margin-top: 6px;
  font-family: var(--mono); }
.reparto strong { color: var(--accent); }

/* ------------------------------------------------------------------
   Avisos dentro de un icono de información

   La explicación de cada campo ya no se imprime debajo: vive detrás
   de una ⓘ pegada a la etiqueta y aparece al tocarla. Con doce
   parámetros en pantalla, la diferencia entre un formulario que se
   lee y una pared de texto que nadie mira.
   ------------------------------------------------------------------ */
.ico-info {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; margin-left: 6px; padding: 0;
  border-radius: 50%; border: 1px solid var(--line);
  background: var(--surface-2); color: var(--text-dim);
  font-family: var(--sans); font-size: 10px; font-weight: 700; line-height: 1;
  cursor: pointer; vertical-align: middle; flex: 0 0 auto;
}
.ico-info:hover { border-color: var(--accent); color: var(--accent); }
.ico-info[aria-expanded="true"] {
  background: var(--accent); border-color: var(--accent); color: #06181a;
}
.hint.hint-info { display: none; }
.hint.hint-info.abierto {
  display: block;
  border-left: 2px solid var(--accent-dim);
  background: rgba(58, 199, 180, 0.06);
  padding: 8px 10px; border-radius: 0 var(--r-sm) var(--r-sm) 0;
  color: var(--text-dim); line-height: 1.5;
}
/* En un interruptor la etiqueta de arriba solo existe para colgar la ⓘ:
   el texto que se lee es el del propio interruptor. */
.field-switch > label:first-child { margin-bottom: 6px; }

/* Interruptor de sí/no. Más claro que una casilla suelta para cosas que
   cambian lo que el bot hace con el dinero. */
.switch { display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--base); margin-bottom: 10px; }
.switch input { flex: 0 0 auto; }
.switch .txt { font-size: 0.85rem; color: var(--text); }
.switch .txt small { display: block; color: var(--text-faint); font-size: 0.75rem; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 14px; border-radius: var(--r-sm); border: 1px solid var(--line);
  background: var(--surface-2); color: var(--text);
  font-family: var(--sans); font-size: 0.85rem; font-weight: 500;
  cursor: pointer; transition: background 0.12s ease, border-color 0.12s ease;
  text-decoration: none;
}
.btn:hover { background: var(--line-soft); border-color: var(--line); text-decoration: none; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #06181a; font-weight: 600; }
.btn-primary:hover { background: #4ad8c4; border-color: #4ad8c4; }
.btn-live { background: var(--live); border-color: var(--live); color: #241703; font-weight: 600; }
.btn-live:hover { background: #ffbc55; }
.btn-danger { border-color: #6b2b2b; color: var(--down); background: transparent; }
.btn-danger:hover { background: rgba(242, 99, 95, 0.12); }
.btn-sm { padding: 5px 10px; font-size: 0.78rem; }
/* Botón apagado a propósito: existe, se ve, y al pulsarlo explica dónde se
   enciende. Es lo que hace "Vender ahora" mientras el perfil no lo desbloquea.
   Se deja visible en gris en vez de esconderlo: un botón que no está no se
   puede buscar. */
.btn-bloqueado {
  background: var(--base); border-color: var(--line-soft);
  color: var(--text-faint); cursor: pointer;
}
.btn-bloqueado:hover { background: var(--surface-2); color: var(--text-dim); }
.btn-bloqueado .candado { font-size: 0.7em; opacity: 0.8; }

/* Fichas de "Administrar sistema": cada zona de la administración con una
   línea que dice qué hay dentro, en vez de siete enlaces sueltos en el menú. */
.admin-tile {
  display: flex; flex-direction: column; gap: 5px;
  padding: 14px 15px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--base); text-decoration: none; color: var(--text);
  transition: border-color 0.12s ease, background 0.12s ease;
}
.admin-tile:hover { border-color: var(--accent); background: var(--surface-2);
  text-decoration: none; }
.admin-tile strong { font-size: 0.92rem; }

/* ------------------------------------------------------------------
   Aviso de las claves API.

   Es la pieza de seguridad más importante del sistema y antes era una
   línea pequeña que nadie leía. Ocupa espacio a propósito: una clave
   con permiso de retiro robada vacía la cuenta, y eso no se arregla.
   ------------------------------------------------------------------ */
.aviso-claves {
  border: 1px solid #6b4d15; background: #241a08; border-radius: var(--r);
  padding: 18px 20px; margin-bottom: 18px;
}
.aviso-claves h2 { font-size: 1rem; color: var(--live); margin-bottom: 12px; }
.aviso-claves ol { margin: 0; padding-left: 20px; }
.aviso-claves li { margin-bottom: 12px; font-size: 0.88rem; line-height: 1.6; }
.aviso-claves li strong { color: var(--text); }
.aviso-claves code {
  background: var(--base); border: 1px solid var(--line); border-radius: 4px;
  padding: 2px 8px; font-family: var(--mono); font-size: 0.85rem;
  color: var(--live);
}
.aviso-claves details { margin-top: 6px; }
.aviso-claves summary {
  cursor: pointer; font-size: 0.85rem; color: var(--accent);
  padding: 6px 0; list-style: revert;
}
.aviso-claves details ul { margin: 8px 0 0; padding-left: 20px; }
.aviso-claves details li { font-size: 0.82rem; color: var(--text-dim);
  margin-bottom: 8px; }
.aviso-claves .cierre {
  margin: 14px 0 0; padding-top: 12px; border-top: 1px solid #4a3a18;
  font-size: 0.82rem; color: var(--text-dim); line-height: 1.6;
}
.admin-tile span { font-size: 0.76rem; color: var(--text-faint); line-height: 1.5; }
.btn svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.8; }
/* Botón de engranaje: cuadrado y sin texto, para las esquinas. */
.btn-icono { padding: 6px; width: 32px; height: 32px; }
.btn-icono svg { width: 17px; height: 17px; }

/* ---------------------------------------------------- tablas */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
th {
  text-align: left; padding: 8px 10px;
  font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-faint);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
td { padding: 8px 10px; border-bottom: 1px solid var(--line-soft); white-space: nowrap; }
tbody tr:hover { background: var(--surface-2); }
td.n { font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right; }
th.n { text-align: right; }

/* ---------------------------------------------------- gráficos */
/* position:relative para que la marca de agua se pueda anclar dentro: la
   librería de gráficos mete su lienzo aquí y no toca a los demás hijos. */
.chart { width: 100%; height: 380px; position: relative; }
.chart-sm { width: 100%; height: 200px; position: relative; }

/* ---------- Barra de progreso ----------
   Un backtest de seis años tarda un rato y antes la pantalla se quedaba con
   un botón gris sin decir nada, que es cuando la gente vuelve a pulsar. Esta
   barra va de verdad: la mueve el servidor según descarga. */
.progreso { margin-top: 12px; }
.progreso .pista {
  height: 8px; border-radius: 999px; background: var(--surface-2);
  overflow: hidden; border: 1px solid var(--line-soft);
}
.progreso .relleno {
  height: 100%; width: 0; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-dim), var(--accent));
  transition: width .35s ease;
}
/* Cuando todavía no se sabe el porcentaje, la barra se mueve sola para que
   se vea que no está colgado. */
.progreso.indeterminado .relleno {
  width: 35% !important; animation: vaiven 1.1s ease-in-out infinite;
}
@keyframes vaiven {
  0% { margin-left: -35%; } 100% { margin-left: 100%; }
}
.progreso .texto {
  display: flex; justify-content: space-between; gap: 12px; margin-top: 7px;
  font-family: var(--mono); font-size: 0.7rem; color: var(--text-dim);
}
@media (prefers-reduced-motion: reduce) {
  .progreso .relleno { transition: none; }
  .progreso.indeterminado .relleno { animation: none; width: 100% !important; opacity: .5; }
}

/* ---------- Marca de agua ----------
   El mismo distintivo de la cabecera, encima del gráfico. Está para que una
   captura o una grabación se sigan sabiendo de dónde salen cuando circulan
   sueltas por ahí, que es como circulan siempre.
   z-index 5: la librería de gráficos mete su canvas después de este nodo, así
   que sin esto lo pintaría por encima. */
.marca-agua {
  position: absolute; right: 12px; bottom: 12px; z-index: 5;
  display: flex; align-items: center; gap: 7px;
  pointer-events: none; user-select: none; opacity: 0.55;
}
.marca-agua .mm {
  width: 20px; height: 20px; border-radius: 6px; flex: 0 0 20px;
  background: linear-gradient(150deg, var(--accent), var(--accent-dim));
  display: grid; place-items: center;
  font-family: var(--mono); font-size: 11px; font-weight: 700; color: #06181a;
}
.marca-agua .mt { font-family: var(--display); font-weight: 600; font-size: 0.78rem;
  color: var(--text-dim); letter-spacing: -0.01em; white-space: nowrap; }
/* En el modo presentación va al CENTRO, como la marca de agua de un vídeo:
   abajo a la derecha las velas le pasaban por encima y en las capturas se
   perdía. Grande y muy tenue: se lee, se reconoce en una grabación, y no
   estorba para seguir las velas. */
.escenario .marca-agua {
  right: auto; bottom: auto; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  opacity: 0.16; gap: 12px;
}
.escenario .marca-agua .mm {
  width: 44px; height: 44px; flex: 0 0 44px; font-size: 24px; border-radius: 12px;
}
.escenario .marca-agua .mt { color: #e9f2f3; font-size: 1.9rem; letter-spacing: -0.02em; }
@media (max-width: 900px) {
  .escenario .marca-agua { gap: 8px; opacity: 0.18; }
  .escenario .marca-agua .mm {
    width: 30px; height: 30px; flex: 0 0 30px; font-size: 17px; border-radius: 9px;
  }
  .escenario .marca-agua .mt { font-size: 1.25rem; }
}
@media (max-width: 900px) {
  .marca-agua { right: 8px; bottom: 8px; gap: 5px; }
  .marca-agua .mm { width: 16px; height: 16px; flex: 0 0 16px; font-size: 9px; }
  .marca-agua .mt { font-size: 0.68rem; }
}
.chart-legend { display: flex; gap: 14px; font-family: var(--mono); font-size: 0.7rem;
  color: var(--text-dim); margin-bottom: 8px; flex-wrap: wrap; }
.swatch { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 5px; }

/* ---------------------------------------------------- avisos */
.note {
  border-left: 3px solid var(--accent); background: var(--surface-2);
  padding: 11px 14px; border-radius: 0 var(--r-sm) var(--r-sm) 0;
  font-size: 0.85rem; color: var(--text-dim);
}
.note.warn { border-left-color: var(--live); }
.note.danger { border-left-color: var(--down); }
.note strong { color: var(--text); }

.empty { text-align: center; padding: 34px 18px; color: var(--text-faint); }
.empty h3 { color: var(--text-dim); margin-bottom: 6px; }

#toast {
  position: fixed; right: 20px; z-index: 9500;
  bottom: calc(20px + var(--safe-b));
  display: flex; flex-direction: column; gap: 8px;
}
.toast {
  background: var(--surface-2); border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  padding: 10px 14px; border-radius: var(--r-sm); box-shadow: var(--shadow);
  font-size: 0.85rem; max-width: 340px;
}
.toast.bad { border-left-color: var(--down); }

dialog {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--r);
  padding: 20px; width: min(560px, 92vw); max-height: 88vh; overflow-y: auto;
  box-shadow: var(--shadow);
}
dialog::backdrop { background: rgba(4, 12, 14, 0.72); }
/* El asistente lleva una tabla comparativa de tres monedas: con 560px se
   sale por los lados. */
dialog.dlg-ancho { width: min(780px, 94vw); }

/* Encabezado de paso dentro de un diálogo largo. Sin esto el asistente era
   un muro de campos y no se veía dónde acababa una decisión y empezaba otra. */
.paso {
  font-family: var(--display); font-size: 0.86rem; font-weight: 600;
  color: var(--accent); letter-spacing: 0.01em;
  margin: 22px 0 10px; padding-bottom: 7px;
  border-bottom: 1px solid var(--line-soft);
}
.paso:first-of-type { margin-top: 6px; }

/* Dos tarjetas para elegir entre opciones que no son un número, sino dos
   formas distintas de hacer las cosas. Un desplegable las escondería. */
.opciones { display: grid; gap: 8px; grid-template-columns: 1fr 1fr; }
.opcion {
  text-align: left; background: var(--base-2); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--r);
  padding: 12px 13px; cursor: pointer; display: grid; gap: 5px;
  font: inherit; transition: border-color .15s ease, background .15s ease;
}
.opcion:hover { border-color: var(--accent-dim); }
.opcion strong { font-family: var(--display); font-size: 0.92rem; }
.opcion span { font-size: 0.78rem; color: var(--text-dim); line-height: 1.5; }
.opcion.on { border-color: var(--accent); background: var(--surface-2); }
.opcion.on strong { color: var(--accent); }
@media (max-width: 620px) { .opciones { grid-template-columns: 1fr; } }

/* La cifra de un deslizador, al lado de su etiqueta. Un deslizador sin
   número obliga a adivinar dónde lo has dejado. */
.valor {
  font-family: var(--mono); font-size: 0.78rem; font-weight: 600;
  color: var(--accent); background: var(--surface-2);
  border: 1px solid var(--line-soft); border-radius: var(--r-sm);
  padding: 1px 7px; margin-left: 6px; white-space: nowrap;
}

/* Deslizador con su casilla al lado: la barra para tantear, la casilla para
   cuando ya sabes la cifra exacta que quieres. */
.con-numero { display: flex; gap: 10px; align-items: center; }
.con-numero input[type=range] { flex: 1; min-width: 0; }
.con-numero input[type=number] { width: 108px; flex: 0 0 108px; }

/* Distintivo de la opción aconsejada. */
.recomendado {
  font-family: var(--mono); font-size: 0.6rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: #06181a; background: var(--accent);
  border-radius: 999px; padding: 2px 7px; margin-left: 7px;
  vertical-align: middle;
}

/* La fila de la moneda elegida en la comparativa del asistente. */
tr.elegida { background: rgba(58, 199, 180, 0.10); }
tr.elegida td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
.dlg-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px;
  position: sticky; top: -20px; background: var(--surface); padding: 4px 0 8px; z-index: 2; }
.dlg-head .right { margin-left: auto; }
.dlg-pie { display: flex; gap: 8px; justify-content: flex-end; margin-top: 16px;
  position: sticky; bottom: -20px; background: var(--surface); padding: 10px 0 2px; }

/* ---------------------------------------------------- login */
.login-wrap { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: 20px; }
.login-card {
  width: min(380px, 100%); background: var(--surface);
  border: 1px solid var(--line-soft); border-radius: 14px; padding: 30px;
}
.login-card h1 { font-size: 1.3rem; margin-bottom: 3px; }
.login-card .sub { color: var(--text-dim); font-size: 0.85rem; margin-bottom: 22px; }
.login-err {
  border-left: 3px solid var(--down); background: rgba(242, 99, 95, 0.1);
  padding: 9px 12px; border-radius: 0 var(--r-sm) var(--r-sm) 0;
  font-size: 0.85rem; margin-bottom: 16px; color: #ffb9b7;
}

/* ============================================================
   Escalera DCA — cada peldaño es una compra; la línea de precio
   medio es la referencia que decide si se puede vender o esperar.
   ============================================================ */
/* De arriba abajo y en orden: 1, 2, 3… Se pintaba al revés para imitar un
   gráfico —el peldaño más hondo abajo del todo—, pero se lee como una lista,
   no como un gráfico: arriba la posición abierta y debajo las compras en el
   orden en que ocurren. */
.ladder { display: flex; flex-direction: column; gap: 3px; margin: 10px 0; }
.rung {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 10px; border-radius: var(--r-sm);
  background: var(--base); border: 1px solid var(--line-soft);
  font-family: var(--mono); font-size: 0.78rem;
}
.rung.done { border-color: var(--accent-dim); background: rgba(58, 199, 180, 0.07); }
.rung.pending { opacity: 0.45; border-style: dashed; }
.rung .n {
  width: 20px; height: 20px; flex: 0 0 20px; border-radius: 4px;
  display: grid; place-items: center; font-size: 0.66rem; font-weight: 600;
  background: var(--surface-2); color: var(--text-dim);
}
.rung.done .n { background: var(--accent); color: #06181a; }
.rung .px { flex: 1; min-width: 0; }
.rung .amt { color: var(--text-dim); white-space: nowrap; }
/* Lo que cada compra aporta: lo que vale ahora y lo que dejará al cerrar la
   ronda. Va al final del peldaño y en móvil salta a su propia línea, porque
   son cuatro cifras y apretadas no se leen. */
.rung .proy {
  margin-left: auto; white-space: nowrap; font-size: 0.72rem;
  color: var(--text-dim);
}
.rung .proy b { font-weight: 600; }
.dca-resumen { font-size: 0.82rem; }
.dca-resumen b { font-family: var(--mono); }
@media (max-width: 560px) {
  .rung { flex-wrap: wrap; }
  .rung .proy { margin-left: 30px; width: 100%; }
}
/* Peldaños de la red de protección: solo se usan si hay depósitos o
   ganancias que los paguen, así que se distinguen del DCA normal. */
.rung.prot { border-color: #4a3f7a; }
.rung.prot .n { background: #2b2547; color: #a99bf0; }
.rung.prot.done { border-color: #6c5cc0; background: rgba(169, 155, 240, 0.09); }
.rung.prot.done .n { background: #a99bf0; color: #16112c; }

.avgline {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 10px; margin: 8px 0;
  border-radius: var(--r-sm); border: 1px dashed var(--live);
  background: rgba(242, 169, 59, 0.08);
  font-family: var(--mono); font-size: 0.8rem; color: var(--live);
}

.riskbox {
  border: 1px solid #6b4d15; background: #221a09;
  border-radius: var(--r); padding: 16px; margin-bottom: 16px;
}
.riskbox h3 { color: var(--live); margin-bottom: 10px; font-size: 0.95rem; }
.riskgrid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.riskgrid .k { font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: #a8894d; }
.riskgrid .v { font-family: var(--mono); font-size: 1.15rem; font-variant-numeric: tabular-nums;
  color: var(--text); }

.stepbar { display: flex; gap: 3px; margin-top: 6px; }
.stepbar i { height: 5px; flex: 1; border-radius: 2px; background: var(--line); }
.stepbar i.on { background: var(--accent); }
.stepbar i.warn { background: var(--live); }
/* Peldaños de la red de protección: el DCA normal ya se agotó y estas
   compras solo existen si hay depósitos o ganancias que las paguen. */
.stepbar i.prot { background: #2b2547; }
.stepbar i.prot.on { background: #a99bf0; }

/* ---------- Modo presentación / directo ----------
   Pensado para enseñar y para grabar: pantalla completa, negro,
   números enormes y un destello en cada venta. */
.escenario {
  position: fixed; inset: 0; z-index: 9000; display: none;
  background: #05080b; color: #e9f2f3;
  /* Márgenes al mínimo: aquí el gráfico es lo que se mira, y cada píxel de
     borde es un píxel que no se ve de la vela. Solo se respeta la zona
     segura del móvil, que es donde está la muesca. */
  padding: calc(8px + var(--safe-t)) 10px calc(8px + var(--safe-b));
  font-variant-numeric: tabular-nums;
  /* Alto de lo que SE VE, no del papel. `inset: 0` mide el viewport de
     maquetación, que en el móvil incluye lo que tapan las barras del
     navegador. En pantalla completa de verdad manda el 100%. */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}
.escenario:fullscreen { height: 100%; }

/* Rejilla, no columna flexible.
   Con flex, el gráfico se llevaba más alto del que había: la librería le
   pone un alto en píxeles a su lienzo y ese lienzo se desbordaba por abajo,
   tapando la fila de botones. Los botones seguían ahí, debajo del gráfico,
   pero no había forma de pulsarlos ni de saber que existían.
   Con `minmax(0, 1fr)` el gráfico solo puede ocupar lo que sobre: las tres
   filas `auto` cogen su sitio SIEMPRE, y la barra por la que se sale de aquí
   no puede desaparecer pase lo que pase. */
.escenario.on {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto auto;
}
/* Y por si la librería vuelve a pasarse con el tamaño: aquí se corta. */
.escenario .lienzo { overflow: hidden; }
.escenario .cabeza { display: flex; align-items: flex-start; gap: 20px; flex-wrap: wrap; }
.escenario .par { font-size: 24px; font-weight: 700; letter-spacing: -0.02em; }
.escenario .par small { display: block; font-size: 11px; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; color: #6a8086; margin-top: 4px; }
/* El precio en vivo sube a la cabecera: en una emisión es el número que
   todo el mundo mira, y abajo entre los botones no se veía. */
.escenario .vivo { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.escenario .vivo .punto { width: 8px; height: 8px; border-radius: 50%;
  background: #ff4d4d; animation: pulso 1.6s infinite; }
.escenario .cifras { margin-left: auto; display: flex; gap: 32px; text-align: right;
  flex-wrap: wrap; }
.escenario .cifra .k { font-size: 10px; letter-spacing: 0.16em;
  text-transform: uppercase; color: #6a8086; }
.escenario .cifra .v { font-size: 42px; font-weight: 700; line-height: 1.05;
  letter-spacing: -0.03em; }
.escenario .cifra .v.pos { color: #2fe08a; }
.escenario .cifra .v.neg { color: #ff5a54; }
/* Moneda base acumulada. Solo aparece cuando el bot está guardando algo;
   en morado, para que no se confunda con el dinero de las operaciones. */
.escenario .cifra.acum .v { color: #a99bf0; font-size: 30px; }
.escenario .cifra.acum .k { color: #8a7fc4; }
/* La referencia en USDT va debajo y pequeña: la cifra que manda es la de
   la moneda real del par. */
.escenario .cifra .u { font-size: 12px; color: #6a8086; margin-top: 3px;
  min-height: 16px; }
.escenario .precio { font-size: 20px; font-weight: 700; color: #cfe0e2;
  transition: color .25s ease; font-variant-numeric: tabular-nums; }
.escenario .precio.sube { color: #2fe08a; }
.escenario .precio.baja { color: #ff5a54; }
.escenario .precio small { color: #6a8086; font-weight: 500; font-size: 13px; }
.escenario .lienzo { flex: 1; margin: 8px 0 0; position: relative; min-height: 0; }
.escenario .pie { display: flex; align-items: center; gap: 10px; margin-top: 8px;
  flex-wrap: wrap; }
.escenario .pie button { background: #101820; color: #cfe0e2; border: 1px solid #22303a;
  border-radius: 8px; padding: 10px 16px; font-size: 14px; font-weight: 600;
  cursor: pointer; min-height: 42px; }
.escenario .pie button:hover { background: #182430; }
.escenario .pie button.principal { background: #2fe08a; border-color: #2fe08a; color: #05100b; }
.escenario .pie input[type=range] { flex: 1; min-width: 140px; accent-color: #2fe08a; }
.escenario .pie .reloj { font-size: 13px; color: #8ba0a5; min-width: 140px; }
.escenario .marcador { display: flex; gap: 22px; font-size: 13px; color: #8ba0a5;
  flex-wrap: wrap; margin-top: 6px; }
.escenario .marcador b { color: #e9f2f3; font-weight: 600; }

/* Destello y cartel de resultado en cada venta.
   z-index: la librería de gráficos mete su canvas después de estos dos
   nodos, así que sin esto los pintaría por encima y no se verían. */
.escenario .destello { position: absolute; inset: 0; pointer-events: none;
  z-index: 5; opacity: 0; transition: opacity .18s ease; }
.escenario .destello.gana { background: radial-gradient(ellipse at center,
  rgba(47,224,138,0.30), transparent 68%); }
.escenario .destello.pierde { background: radial-gradient(ellipse at center,
  rgba(255,90,84,0.30), transparent 68%); }
.escenario .destello.on { opacity: 1; }
.escenario .cartel { position: absolute; left: 50%; top: 40%; transform: translate(-50%,-50%) scale(0.7);
  font-size: clamp(48px, 9vw, 96px); font-weight: 800; letter-spacing: -0.04em; opacity: 0;
  z-index: 6; pointer-events: none; text-shadow: 0 6px 40px rgba(0,0,0,0.6); }
.escenario .cartel.on { animation: cartelazo 1.15s ease-out; }
@keyframes cartelazo {
  0%   { opacity: 0; transform: translate(-50%,-50%) scale(0.7); }
  18%  { opacity: 1; transform: translate(-50%,-50%) scale(1.08); }
  70%  { opacity: 1; transform: translate(-50%,-58%) scale(1); }
  100% { opacity: 0; transform: translate(-50%,-78%) scale(1); }
}

/* Cuenta atrás antes de arrancar la repetición. Es puro espectáculo: da
   tiempo a mirar antes de que empiecen a salir velas. */
.cuenta {
  position: absolute; inset: 0; z-index: 20; display: none;
  place-items: center; background: rgba(5, 8, 11, 0.86); text-align: center;
}
.cuenta.on { display: grid; }
.cuenta .rotulo { font-size: clamp(13px, 2.2vw, 18px); letter-spacing: 0.42em;
  text-transform: uppercase; color: #6a8086; margin-bottom: 10px; }
.cuenta .numero { font-size: clamp(96px, 26vw, 240px); font-weight: 800;
  line-height: 1; letter-spacing: -0.05em; color: #2fe08a;
  animation: latido 1s ease-out; }
.cuenta .numero.texto { font-size: clamp(40px, 11vw, 120px); letter-spacing: -0.02em; }
@keyframes latido {
  0%   { opacity: 0; transform: scale(1.7); }
  25%  { opacity: 1; transform: scale(1); }
  80%  { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(0.9); }
}
@media (prefers-reduced-motion: reduce) {
  .cuenta .numero, .escenario .cartel.on { animation: none; opacity: 1; }
}

/* En directo no hay nada que reproducir: fuera los mandos de la película. */
.escenario.directo #escPlay,
.escenario.directo #escBarra,
.escenario.directo #escVideo,
.escenario.directo .solo-repeticion { display: none; }
.escenario.directo .pie .reloj { flex: 1; }
/* Y al revés: en la repetición no hay precio en vivo que enseñar. */
.escenario:not(.directo) .vivo { display: none; }

/* ---------- Generador de vídeo ----------
   El lienzo va fuera de la pantalla: se dibuja en él fotograma a fotograma
   y se graba, sin que el usuario vea nada raro. */
.taller-video { position: fixed; left: -10000px; top: 0; }
.video-caja { display: grid; gap: 12px; }
.video-formatos { display: flex; gap: 8px; flex-wrap: wrap; }
.formato {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 10px 14px; background: var(--base); flex: 1 1 160px;
}
.formato.on { border-color: var(--accent); background: var(--surface-2); }
.formato .muestra { border: 2px solid currentColor; border-radius: 3px;
  color: var(--text-faint); flex: 0 0 auto; }
.formato.on .muestra { color: var(--accent); }
.formato .muestra.v { width: 18px; height: 32px; }
.formato .muestra.h { width: 34px; height: 20px; }
.formato .txt { font-size: 0.85rem; }
.formato .txt small { display: block; color: var(--text-faint); font-size: 0.72rem; }
.barra-progreso { height: 6px; border-radius: 3px; background: var(--base);
  overflow: hidden; border: 1px solid var(--line-soft); }
.barra-progreso i { display: block; height: 100%; width: 0; background: var(--accent);
  transition: width .2s ease; }

/* ============================================================
   Móvil: la navegación baja al pulgar y todo se apila.
   ============================================================ */
@media (max-width: 900px) {
  .shell { flex-direction: column; }
  .side { display: none; }

  .topbar {
    display: flex; align-items: center; gap: 10px;
    position: sticky; top: 0; z-index: 60;
    padding: calc(8px + var(--safe-t)) 14px 8px;
    background: var(--base-2); border-bottom: 1px solid var(--line-soft);
  }
  .topbar .brand-sub { display: none; }
  .topbar .right { margin-left: auto; display: flex; gap: 6px; align-items: center; }

  .btn-menu {
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; border-radius: var(--r-sm);
    border: 1px solid var(--line); background: var(--surface-2); color: var(--text);
    cursor: pointer;
  }
  .btn-menu svg { width: 19px; height: 19px; stroke: currentColor; fill: none; stroke-width: 1.8; }

  .tabbar {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
    background: var(--base-2); border-top: 1px solid var(--line-soft);
    padding-bottom: var(--safe-b);
  }
  .tabbar a, .tabbar button {
    flex: 1; display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 3px; min-height: var(--tabbar-h);
    background: none; border: 0; cursor: pointer;
    color: var(--text-faint); font-size: 0.63rem; font-family: var(--sans);
    text-decoration: none; padding: 6px 2px;
  }
  .tabbar a.on { color: var(--accent); }
  .tabbar a.on.real { color: var(--live); }
  .tabbar svg { width: 21px; height: 21px; stroke: currentColor; fill: none; stroke-width: 1.7; }

  /* Hoja del menú: el resto de secciones, idioma y salir. */
  .hoja { position: fixed; inset: 0; z-index: 80; display: none; }
  .hoja.on { display: block; }
  .hoja .velo { position: absolute; inset: 0; background: rgba(4, 12, 14, 0.7); }
  .hoja .panel {
    position: absolute; left: 0; right: 0; bottom: 0;
    background: var(--surface); border-radius: 16px 16px 0 0;
    border-top: 1px solid var(--line);
    padding: 8px 14px calc(18px + var(--safe-b));
    max-height: 82vh; overflow-y: auto;
    animation: sube .18s ease-out;
  }
  .hoja .asa { width: 40px; height: 4px; border-radius: 2px; background: var(--line);
    margin: 6px auto 12px; }
  @keyframes sube { from { transform: translateY(100%); } to { transform: translateY(0); } }

  .split, .g-2, .g-3, .g-4 { grid-template-columns: minmax(0, 1fr); }
  .bot-list { grid-template-columns: minmax(0, 1fr); }
  .content { padding: 14px 14px calc(var(--tabbar-h) + 24px + var(--safe-b)); }
  .modebar { padding: 7px 14px; font-size: 0.62rem; gap: 8px; }
  .modebar .sep { gap: 10px; }
  .page-head { margin-bottom: 14px; }
  .page-head .right { width: 100%; margin-left: 0; }
  .page-head .right .btn { flex: 1; }

  h1 { font-size: 1.28rem; }
  .card { padding: 14px; }
  .stat { padding: 12px 14px; }
  .stat .v { font-size: 1.3rem; }

  /* Dos métricas por fila: cuatro tarjetas de ancho completo obligan a un
     scroll larguísimo antes de llegar a los bots. */
  .grid.g-4, .grid.g-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }

  .row, .row-3 { grid-template-columns: 1fr; }

  /* Los diálogos ocupan la pantalla: en móvil una ventanita flotante con
     scroll interno es imposible de usar. */
  dialog { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh;
    border-radius: 0; border: 0; margin: 0; padding: 14px 14px calc(14px + var(--safe-b)); }
  .dlg-head { top: -14px; }
  .dlg-pie { bottom: 0; padding-bottom: 6px; }
  .dlg-pie .btn { flex: 1; }

  #toast { left: 12px; right: 12px; bottom: calc(var(--tabbar-h) + 14px + var(--safe-b)); }
  .toast { max-width: none; }

  .chart { height: 260px; }
  .chart-sm { height: 170px; }

  /* Margen al mínimo absoluto: en un teléfono el gráfico ya va justo de
     alto, y aquí no hay nada más que mirar. Lo único que se respeta es la
     muesca y la barra de gestos; donde no las hay, quedan 2px para que el
     texto no vaya pegado al canto de la pantalla. */
  .escenario {
    /* Arriba y a los lados, al mínimo. Abajo NO: ahí está la barra de gestos
       del móvil, que se queda con los toques de los últimos milímetros. Sin
       este hueco, el botón de abajo a la izquierda es casi imposible de
       pulsar aunque se vea perfectamente. */
    padding: max(2px, var(--safe-t)) max(2px, var(--safe-r))
             max(14px, calc(var(--safe-b) + 10px)) max(2px, var(--safe-l));
  }
  .escenario .lienzo { margin-top: 10px; margin-bottom: 4px; }
  .escenario .cabeza { gap: 10px; }
  .escenario .vivo { margin-top: 4px; }
  /* El gráfico ocupa lo que sobra, así que la forma de hacerlo más pequeño
     es dejar respirar a lo que tiene encima y debajo. Las cifras se leen sin
     forzar la vista y la barra de botones queda a una distancia cómoda del
     canto: eso es lo que le quita alto a las velas, que estaban estiradas
     ocupando casi toda la pantalla. */
  .escenario .par { font-size: 16px; }
  .escenario .par small { font-size: 9px; margin-top: 2px; letter-spacing: 0.12em; }
  .escenario .vivo { margin-top: 5px; }
  .escenario .precio { font-size: 17px; }
  .escenario .precio small { font-size: 11px; }
  .escenario .cifra .k { font-size: 9px; }
  .escenario .cifra .u { font-size: 10px; }
  /* La moneda acumulada es un dato secundario, pero con su sitio. */
  .escenario .cifra.acum .v { font-size: clamp(14px, 3.8vw, 19px); }
  .escenario .cifras { gap: 16px; width: 100%; margin-left: 0;
    justify-content: space-between; text-align: left; }
  .escenario .cifras { gap: 12px; }
  .escenario .cifra { min-width: 0; }
  .escenario .cifra .v { font-size: clamp(17px, 5vw, 24px); line-height: 1.05; }
  .escenario .cifra .k { font-size: 9px; letter-spacing: 0.1em; }
  .escenario .cifra .u { font-size: 10px; }

  /* Los botones del escenario en el móvil.
     Ojo con el alto: 34px parecía buena idea para dejarle sitio al gráfico,
     pero un dedo no acierta en 34px, y menos pegados al canto de abajo, que
     es donde el sistema se queda con el toque para sus propios gestos.
     44px es el mínimo con el que un pulgar acierta a la primera. El sitio
     sale del gráfico, que para eso ocupa lo que sobra. */
  .escenario .pie { gap: 8px; margin-top: 10px; }
  .escenario .pie button {
    flex: 0 1 auto; padding: 11px 16px; font-size: 13px; font-weight: 600;
    border-radius: 10px; background: #16222c; border-color: #3a5561;
    color: #e9f2f3; min-height: 44px;
  }
  /* En directo solo queda «Salir»: que sea grande y fácil de acertar. */
  .escenario.directo .pie button { padding: 12px 22px; min-height: 46px; }
  .escenario .pie button.principal { color: #05100b; }
  .escenario .pie input[type=range] { flex: 1 1 100%; order: 8; min-width: 0; }
  .escenario .pie .reloj { min-width: 0; flex: 1 1 100%; order: 9;
    text-align: center; font-size: 11px; }
  .escenario .marcador { gap: 14px; font-size: 11px; flex-wrap: wrap; margin-top: 10px; }
}

/* Pantallas muy estrechas: una métrica por fila antes que texto cortado.
   El corte va en 340 y no en 380 porque un iPhone mini mide 375 y ahí dos
   columnas todavía se leen bien; forzar una sola dejaba la pantalla vacía. */
@media (max-width: 340px) {
  .grid.g-4, .grid.g-3 { grid-template-columns: minmax(0, 1fr); }
  .tabbar a, .tabbar button { font-size: 0.58rem; }
}

/* Instalada en el móvil no hay barra de navegador, así que se gana alto:
   se aprovecha para que el gráfico respire. */
@media (display-mode: standalone) {
  .chart { height: 300px; }
}

/* ---------- Selector de estrategia ---------- */
/* Dos tarjetas grandes en vez de un desplegable: la elección de estrategia
   cambia todo lo demás del formulario, así que merece verse de un vistazo y
   con su explicación al lado, no esconderse en una lista. */
.estrategias {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 10px;
  margin-bottom: 16px;
}
.estrategias .estrategia {
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: left;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface-2);
  color: var(--text);
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.estrategias .estrategia:hover { border-color: var(--accent); }
.estrategias .estrategia .et {
  font-size: .72rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.estrategias .estrategia strong { font-size: 1rem; }
.estrategias .estrategia .hint { margin: 0; }
.estrategias .estrategia.activa {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, var(--surface-2));
}
.estrategias .estrategia.activa .et { color: var(--accent); }

/* ---------- Presets validados ---------- */
/* Botones anchos y con su resumen: lo que hacen es rellenar quince mandos de
   golpe, así que tienen que leerse como una decisión, no como un atajo. */
.presets {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}
.presets .preset {
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-align: left;
  padding: 11px 13px;
  border: 1px dashed var(--line);
  border-radius: var(--r);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.presets .preset:hover { border-color: var(--accent); }
.presets .preset strong { font-size: .95rem; }
.presets .preset .hint { margin: 0; font-size: .78rem; }
.presets .preset.activa {
  border-style: solid;
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

/* Atajos de capital: probar con 100 no debería obligar a escribirlo. */
.atajos { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 6px; }
.atajos .btn { padding: 3px 9px; font-size: .74rem; }

/* ---------- Pestañas de la pantalla de backtesting ---------- */
/* La pantalla tenía todo abierto a la vez —presets, veintitantos mandos,
   dinero, costes— y no se encontraba nada. Dos caminos claros: el que ya
   funciona y el de afinar a mano. */
.pestanas {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 12px;
}
.pestanas .pestana {
  padding: 8px 14px;
  border: none;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  font-size: .88rem;
  transition: color .15s, border-color .15s;
}
.pestanas .pestana:hover { color: var(--text); }
.pestanas .pestana.activa {
  color: var(--accent);
  border-bottom-color: var(--accent);
  font-weight: 600;
}

/* Fichas por par dentro de las estrategias IA. */
.fichas { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px; }
.ficha {
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 9px 11px;
  background: var(--surface-2);
}
.ficha .par { font-size: .74rem; color: var(--text-dim); letter-spacing: .05em; }
.ficha .ret { font-size: 1.15rem; font-weight: 600; font-family: var(--mono); }
.ficha .pie { font-size: .68rem; color: var(--text-faint); margin-top: 2px; }

/* ---------- Secciones plegables ----------
   La pantalla de backtesting medía dos pantallas de alto en un ordenador:
   todo abierto a la vez y sin jerarquía. Lo que se toca en cada prueba queda
   a la vista; lo que se ajusta una vez, plegado. */
.plegable {
  border-top: 1px solid var(--line-soft);
  padding-top: 10px;
  margin-top: 12px;
}
.plegable > summary,
.plegable-card > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  font-size: .95rem;
  color: var(--text);
  user-select: none;
}
.plegable > summary::-webkit-details-marker,
.plegable-card > summary::-webkit-details-marker { display: none; }
.plegable > summary::before,
.plegable-card > summary::before {
  content: "›";
  display: inline-block;
  font-size: 1.1rem;
  color: var(--text-dim);
  transition: transform .15s;
}
.plegable[open] > summary::before,
.plegable-card[open] > summary::before { transform: rotate(90deg); }
.plegable > summary:hover, .plegable-card > summary:hover { color: var(--accent); }
.plegable-card > summary h2 { margin: 0; font-size: 1rem; }
.plegable-card > summary .hint { margin-left: auto; }

/* ---------- Ficha de presentación del backtesting ----------
   Antes de soltar las velas se dice qué se está mirando: sin esto, un gráfico
   con flechas no explica si es spot, si reinvierte o de cuánto tiempo va.

   La primera versión partía las frases en dos líneas («Trading spot ·» /
   «BNB/USDT») porque la columna de la etiqueta se comía el ancho. Ahora la
   etiqueta va ARRIBA y pequeña, y el valor debajo en una sola línea, que es
   como se lee una ficha. */
.cuenta .ficha-intro {
  display: grid;
  gap: 10px;
  margin: 16px auto 20px;
  width: min(420px, 88vw);
  text-align: left;
}
.cuenta .ficha-intro .linea {
  display: grid;
  gap: 1px;
  padding: 7px 12px;
  border-left: 2px solid rgba(255, 255, 255, .12);
  background: rgba(255, 255, 255, .03);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
}
.cuenta .ficha-intro .linea .k {
  color: var(--text-faint);
  font-size: .66rem;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.cuenta .ficha-intro .linea .v {
  font-size: 1.06rem;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cuenta .ficha-intro .linea .v.si { color: var(--up); }
.cuenta .ficha-intro .linea .v.no { color: var(--text-faint); }
@media (max-width: 480px) {
  .cuenta .ficha-intro { gap: 7px; margin: 12px auto 14px; }
  .cuenta .ficha-intro .linea { padding: 5px 10px; }
  .cuenta .ficha-intro .linea .v { font-size: .95rem; }
}

/* El editor de esos textos, en el diálogo del vídeo. */
.fila-intro { display: flex; gap: 6px; margin-bottom: 6px; }
.fila-intro input { flex: 1 1 auto; min-width: 0; }
.fila-intro input:first-child { flex: 0 0 40%; font-size: .8rem; }

/* Ritmo del vídeo: lento para mirarlo, rápido para publicarlo. */
.video-ritmos { display: flex; gap: 6px; flex-wrap: wrap; }
.video-ritmos .ritmo {
  flex: 1 1 90px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--text);
  cursor: pointer;
  font-size: .88rem;
}
.video-ritmos .ritmo small { color: var(--text-faint); font-size: .68rem; }
.video-ritmos .ritmo:hover { border-color: var(--accent); }
.video-ritmos .ritmo.on {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, var(--surface-2));
}

/* ---------- Tarjetas de estrategia ---------- */
.est-card.principal { border-color: var(--accent); }
.est-card .etiq {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: .62rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  vertical-align: middle;
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  color: var(--accent);
}
.est-card .etiq.gris {
  background: rgba(255, 255, 255, .07);
  color: var(--text-dim);
}
/* Título de cada bloque de mandos. Sin esto los 32 números van seguidos en
   una sola columna y encontrar uno concreto es cuestión de suerte. */
.grupo-params {
  font-size: 0.74rem; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--accent);
  margin: 16px 0 2px; padding-bottom: 5px;
  border-bottom: 1px solid var(--line-soft);
}
.grupo-params:first-child { margin-top: 4px; }
/* Cartel de la escalera automática. Ocupa el hueco que dejan los dos mandos
   de protección al desaparecer, para que se entienda que no se han perdido
   sino que ya no hay que tocarlos. */
.aviso-auto-escalera {
  grid-column: 1 / -1;
  margin: 6px 0 2px; padding: 9px 12px;
  border: 1px solid var(--accent-dim); border-left-width: 3px;
  border-radius: var(--r-sm);
  background: rgba(58, 199, 180, 0.08);
  font-size: 0.78rem; line-height: 1.45; color: var(--text);
}
.aviso-auto-escalera b { color: var(--accent); }
/* Diario del bot. Cada línea es lo que vio o lo que hizo, con un color que
   distingue de un vistazo las operaciones de las simples lecturas: entre
   compra y venta pueden pasar semanas de solo mirar. */
.avisos { max-height: 55vh; overflow-y: auto; display: flex;
          flex-direction: column; gap: 4px; }
.aviso {
  display: flex; gap: 10px; align-items: baseline;
  padding: 7px 10px; border-radius: var(--r-sm);
  background: var(--base); border-left: 3px solid var(--line-soft);
  font-size: 0.78rem; line-height: 1.45;
}
.aviso .cuando { color: var(--text-dim); font-family: var(--mono);
                 font-size: 0.7rem; white-space: nowrap; }
.aviso.op  { border-left-color: var(--accent); background: rgba(58,199,180,0.07); }
.aviso.avi { border-left-color: #d9a441; background: rgba(217,164,65,0.07); }
.aviso.lec { opacity: 0.82; }

/* El resto de la escalera, recogido. La lista de dentro no lleva el margen de
   arriba: ya lo pone el desplegable, y con los dos se abría un hueco que
   parecía que faltaba un peldaño. */
.escalera-resto { margin-top: 6px; }
.escalera-resto .ladder { margin-top: 6px; }

/* --------------------------------------------------- perfil de estrategia */
/* El perfil va pegado al nombre y con color propio: es lo primero que hay que
   ver de una estrategia y lo único que se entiende sin saber de trading. */
.perfil {
  display: inline-block; vertical-align: middle; margin-left: 8px;
  padding: 2px 9px; border-radius: 999px;
  font-family: var(--mono); font-size: 0.6rem; font-weight: 600;
  letter-spacing: 0.07em; text-transform: uppercase; white-space: nowrap;
}
.perfil.conservador { background: rgba(58, 199, 180, 0.14); color: #3ac7b4;
  border: 1px solid rgba(58, 199, 180, 0.35); }
.perfil.moderado { background: rgba(242, 169, 59, 0.13); color: #f2a93b;
  border: 1px solid rgba(242, 169, 59, 0.33); }
.perfil.agresivo { background: rgba(242, 99, 95, 0.13); color: #f2635f;
  border: 1px solid rgba(242, 99, 95, 0.33); }
.perfil-linea { display: flex; align-items: center; gap: 10px;
  color: var(--text-dim); font-size: 0.9rem; }
.perfil-linea .perfil { margin-left: 0; }

/* La «i»: redonda, discreta y del tamaño del dedo. */
.btn-info {
  display: inline-grid; place-items: center; vertical-align: middle;
  width: 20px; height: 20px; margin-left: 6px; padding: 0;
  border-radius: 50%; border: 1px solid var(--line);
  background: transparent; color: var(--text-dim); cursor: pointer;
  font-family: var(--display); font-size: 0.72rem; font-weight: 700;
  font-style: italic; line-height: 1;
}
.btn-info:hover { border-color: var(--accent); color: var(--accent); }

/* Publicar: un interruptor, no un botón. Es un estado que se mira de reojo
   —«¿la ven los demás?»— y un botón no dice en cuál de los dos estás. */
.pub-sw {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 5px 10px; border-radius: var(--r-sm);
  border: 1px solid var(--line-soft);
  font-size: 0.78rem; color: var(--text-dim);
}
.pub-sw input { accent-color: var(--accent); width: 15px; height: 15px; }
.pub-sw:hover { border-color: var(--line); color: var(--text); }
.etiq.pub { background: rgba(58, 199, 180, 0.16); color: #3ac7b4; }
