/* Identidad visual "tablero de casa de cambio": tinta verde-teal oscura +
   acento dorado/latón, IBM Plex Mono (números) + IBM Plex Sans (texto).
   Mismo sistema que demo.html — mantener coherencia si se rediseña. */

:root {
  --ink: #0F211C;
  --surface: #17332C;
  --hairline: rgba(237, 230, 214, 0.14);
  --hairline-strong: rgba(237, 230, 214, 0.28);
  --text-primary: #EDF3EF;
  --text-muted: #8FA69B;
  --brass: #D0A24C;
  --brass-dim: #8A7440;
  /* rust/sage originales (#C1502E / #4F9B72) medían 2.88:1 y 4.05:1 contra
     --surface -- por debajo de las 4.5:1 que pide WCAG AA para texto
     normal (hallazgo real de una auditoría de accesibilidad, no un
     cambio de gusto). Aclarados lo mínimo para pasar 4.5:1 sin perder el
     carácter del color. */
  --rust: #D3846C;
  --sage: #60A580;
  --font-sans: 'IBM Plex Sans', -apple-system, sans-serif;
  --font-mono: 'IBM Plex Mono', 'SFMono-Regular', monospace;
}
/* Modo claro -- mismo sistema (latón + verde-teal), invertido a fondo claro
   tipo "libro de contabilidad" en vez de resolverlo con un filtro genérico.
   Explícito con [data-theme], no con prefers-color-scheme: el toggle manda,
   no el sistema operativo (ver comentario en app.js sobre por qué). */
:root[data-theme="light"] {
  --ink: #F3EFE3;
  --surface: #FFFFFF;
  --hairline: rgba(15, 33, 28, 0.12);
  --hairline-strong: rgba(15, 33, 28, 0.26);
  --text-primary: #17332C;
  --text-muted: #5B6F67;
  /* --brass original (#A97427) medía 3.5:1 contra --ink y 4.03:1 contra
     --surface -- pasa para texto grande (encabezados de 16-18px normal)
     pero no para AA de texto normal, que es el estándar que aplica a los
     16px *bold* que usan .doc-section h2/.panorama-group h2 (14pt bold es
     el piso de "texto grande", 16px bold queda debajo). Oscurecido lo
     mínimo para pasar 4.5:1 en los dos fondos. */
  --brass: #8F6221;
  --brass-dim: #C9A968;
  --rust: #B23D22;
  /* #2E7D4F medía 4.39:1 contra --ink: pasaba como RELLENO de barra, pero no
     como TEXTO de 13px, que es lo que pasó a ser cuando el número del
     panorama tomó el color de su nivel (20 sep 2026). Mismo tono, 4% más
     oscuro: 4.81:1 contra --ink y 5.53:1 contra --surface. Se corrige el
     token en vez de inventar uno aparte para texto, así arrastra a todo lo
     demás que use este verde sobre el fondo de la página. */
  --sage: #2C764B;
}
* { box-sizing: border-box; }
body { margin: 0; background: var(--ink); color: var(--text-primary); font-family: var(--font-sans); line-height: 1.5; transition: background 0.2s ease, color 0.2s ease; }
main { max-width: 760px; margin: 0 auto; padding: 0 20px 48px; }
.topbar { max-width: 760px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; padding: 24px 20px 32px; }
.topbar-mark { display: flex; align-items: center; gap: 8px; }
.mark-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--brass); }
.mark-text { font-size: 13px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.topbar-meta { font-size: 13px; color: var(--text-muted); font-family: var(--font-mono); }
.topbar-right { display: flex; align-items: center; gap: 14px; }
.theme-toggle {
  background: transparent; border: 0.5px solid var(--hairline-strong); color: var(--text-muted);
  width: 30px; height: 30px; border-radius: 50%; cursor: pointer; display: flex;
  align-items: center; justify-content: center; flex-shrink: 0; padding: 0;
}
.theme-toggle:hover { color: var(--text-primary); border-color: var(--brass); }
.theme-toggle:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }
.theme-toggle svg { width: 15px; height: 15px; }
/* Selector ES/EN/PT -- reemplazó al viejo botón único que solo alternaba
   entre 2 idiomas (#lang-toggle) cuando se sumó portugués. Mismo alto que
   .theme-toggle (30px) para que la fila del topbar quede alineada. */
.lang-switch {
  display: flex; gap: 2px; align-items: center; height: 30px;
  border: 0.5px solid var(--hairline-strong); border-radius: 15px; padding: 2px; flex-shrink: 0;
}
.lang-switch-btn {
  background: transparent; border: none; color: var(--text-muted); cursor: pointer;
  font-family: var(--font-mono); font-size: 10px; font-weight: 600; letter-spacing: 0.02em;
  padding: 0 7px; height: 100%; border-radius: 12px; line-height: 1;
}
.lang-switch-btn:hover:not(.active) { color: var(--text-primary); }
.lang-switch-btn.active { color: var(--ink); background: var(--brass); }
.lang-switch-btn:focus-visible { outline: 2px solid var(--brass); outline-offset: 1px; }
/* Un solo botón, dos íconos superpuestos -- se muestra el que corresponde
   según el tema activo en vez de tener que reescribir el SVG por JS. */
.theme-toggle .icon-sun { display: none; }
:root[data-theme="light"] .theme-toggle .icon-moon { display: none; }
:root[data-theme="light"] .theme-toggle .icon-sun { display: block; }
.board { background: var(--surface); border: 0.5px solid var(--hairline); border-radius: 4px; padding: 32px 28px; text-align: center; margin-bottom: 24px; }
.board-label { margin: 0 0 20px; font-size: 13px; color: var(--text-muted); }
.board-filters { display: flex; justify-content: center; align-items: end; gap: 10px; flex-wrap: wrap; margin-bottom: 24px; }
.board-filters .field { text-align: left; min-width: 140px; }
.board-filters .field select,
.board-filters .field input { min-width: 100%; }
.filter-clear { background: transparent; border: 0.5px solid var(--hairline-strong); color: var(--text-muted); font-family: var(--font-sans); font-size: 12px; padding: 8px 12px; border-radius: 3px; cursor: pointer; }
.filter-clear:hover { color: var(--text-primary); border-color: var(--brass); }
.filter-clear:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }
.board-flap { display: flex; justify-content: center; }
.flap-wrap { display: inline-block; }
/* El tablero se llamaba .flap desde el primer día —tablero de casa de
   cambio— pero lo único que hacía al llegar un dato nuevo era bajar la
   opacidad a 0.25 durante 150 ms: la metáfora estaba escrita y nunca se
   construyó. Desde el 20 sep 2026 las aspas giran de verdad, y solo las que
   cambiaron (ver flap.js).
   El contenedor conserva el nombre y la pinta de antes; lo que cambia es que
   adentro hay una fila de aspas en vez de un texto suelto. */
.flap-digits {
  display: inline-flex; gap: 3px; align-items: stretch;
  font-family: var(--font-mono); font-weight: 600;
  font-size: clamp(48px, 12vw, 84px); letter-spacing: 0.02em; color: var(--brass);
  background: var(--ink); border-radius: 6px; padding: 8px 20px;
  border: 0.5px solid var(--hairline-strong);
}
/* Cada aspa: dos mitades fijas (lo que se ve en reposo) y, solo mientras
   gira, dos hojas que se animan con rotateX. Las mitades fijas llevan SIEMPRE
   el carácter puesto, así que si la animación no corre —o el JS no llega— el
   número ya está pintado. Nada arranca en opacidad 0. */
.flap {
  --flap-w: 0.62em; --flap-h: 1.12em;
  position: relative; display: inline-block; width: var(--flap-w); height: var(--flap-h);
  perspective: 5em; border-radius: 3px; flex: 0 0 auto;
}
.flap.flap-sep { --flap-w: 0.3em; }
.flap .flap-half {
  position: absolute; left: 0; right: 0; height: 50%; overflow: hidden;
  background: var(--surface); border: 0.5px solid var(--hairline-strong);
}
.flap.flap-sep .flap-half { background: none; border: 0; }
.flap .flap-half.flap-t { top: 0; border-bottom: 0; border-radius: 3px 3px 0 0; }
.flap .flap-half.flap-b { bottom: 0; border-top: 0; border-radius: 0 0 3px 3px; }
/* La bisagra tiene que leerse también en reposo: sin ella el aspa parece una
   caja con un número, no una pieza que gira. */
.flap .flap-half.flap-b::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px; background: rgba(0, 0, 0, 0.55); }
.flap .flap-half.flap-t::after { content: ''; position: absolute; bottom: 0; left: 0; right: 0; height: 1px; background: rgba(237, 230, 214, 0.10); }
.flap .flap-half > i,
.flap .flap-leaf > i {
  position: absolute; left: 0; right: 0; height: var(--flap-h);
  line-height: var(--flap-h); font-style: normal; text-align: center; color: var(--brass);
}
.flap.flap-sep .flap-half > i { color: var(--brass-dim); }
.flap .flap-half.flap-t > i, .flap .flap-leaf.flap-fall > i { top: 0; }
.flap .flap-half.flap-b > i, .flap .flap-leaf.flap-rise > i { top: calc(var(--flap-h) * -0.5); }
.flap .flap-leaf {
  position: absolute; left: 0; right: 0; height: 50%; overflow: hidden;
  background: var(--surface); border: 0.5px solid var(--hairline-strong);
  backface-visibility: hidden; z-index: 2;
}
.flap .flap-leaf.flap-fall {
  top: 0; border-bottom: 0; border-radius: 3px 3px 0 0;
  transform-origin: bottom center; animation: flap-fall 0.13s linear forwards;
}
.flap .flap-leaf.flap-rise {
  bottom: 0; border-top: 0; border-radius: 0 0 3px 3px;
  transform-origin: top center; animation: flap-rise 0.13s 0.13s linear both;
}
/* La hoja que sube arranca de canto (rotateX(90deg)), nunca en opacidad 0:
   si la animación no corre, no hay nada invisible que esperar. */
@keyframes flap-fall { from { transform: rotateX(0); } to { transform: rotateX(-90deg); } }
@keyframes flap-rise { from { transform: rotateX(90deg); } to { transform: rotateX(0); } }
/* El color de dirección se queda ~2 s y se va solo (lo quita flap.js). */
.flap.flap-up .flap-half, .flap.flap-up .flap-leaf { border-color: var(--rust); }
.flap.flap-down .flap-half, .flap.flap-down .flap-leaf { border-color: var(--sage); }
.flap.flap-up .flap-half > i, .flap.flap-up .flap-leaf > i { color: var(--rust); }
.flap.flap-down .flap-half > i, .flap.flap-down .flap-leaf > i { color: var(--sage); }
.flap .flap-half, .flap .flap-leaf, .flap .flap-half > i { transition: border-color 0.5s ease, color 0.5s ease; }
.board-subrow { display: flex; justify-content: center; gap: 48px; margin-top: 24px; }
.board-sub { display: flex; flex-direction: column; gap: 4px; }
.sub-label { font-size: 12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; }
.sub-value { font-family: var(--font-mono); font-size: 20px; font-weight: 500; }
/* auto-fit en vez de un repeat(4,1fr) fijo -- con Venezuela (4 tarjetas)
   da exactamente el mismo resultado de siempre, pero se adapta solo para
   los países nuevos: Argentina (5 tarjetas) las reparte en una sola fila
   pareja en vez de dejar la 5ta sola casi vacía en una fila aparte, y
   Bolivia/Colombia (2 tarjetas) las estira a ocupar el ancho completo en
   vez de dejar la mitad derecha en blanco. minmax(150px,1fr) es el piso
   de ancho antes de que auto-fit decida bajar la cantidad de columnas. */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 12px; margin-bottom: 40px; }
.card { background: var(--surface); border: 0.5px solid var(--hairline); border-radius: 4px; padding: 18px 16px; position: relative; container-type: inline-size; }
.card-accent { border-color: var(--brass-dim); }
/* flex-wrap, no nowrap -- con 4 o 5 tarjetas en una fila de 760px como
   máximo, cada tarjeta tiene poco ancho real incluso en desktop (no solo
   en mobile). Un label largo como "BCV oficial" o "Dólar BTC" + el ícono
   info no siempre entran junto a los botones de copiar/compartir en la
   misma fila -- es el bloque de botones -- más chico, más fácil de mover
   -- el que baja a su propia línea primero.
   El label en sí SÍ se envuelve (white-space: normal, no nowrap) -- un
   label realmente largo como "Referencia de mercado" (Colombia) no entra
   ni una sola línea en una tarjeta angosta de 5 en una fila, y sin poder
   envolverse quedaba cortado a lo bruto contra el borde de la tarjeta
   (bug real reportado por el usuario 2026-08-25, con captura). Envolverse
   en 2 líneas cortas se ve bien; lo que había que evitar (y se sigue
   evitando) es que compita mal contra los botones en la misma línea. */
.card-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 6px; margin-bottom: 8px; flex-wrap: wrap; row-gap: 6px; }
.card-label-with-info { display: flex; align-items: center; gap: 5px; min-width: 0; flex: 1 1 auto; }
.card-label { margin: 0; font-size: 12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }

/* Botón "i" + burbuja explicativa (ver info-bubbles.js) -- qué significa
   cada tasa (blue, MEP, CCL, TRM...). Ancla la burbuja al botón, no a la
   tarjeta entera, para que la posición no dependa del tamaño de cada
   tarjeta. */
.info-wrap { position: relative; display: inline-flex; flex-shrink: 0; }
.info-btn {
  width: 15px; height: 15px; border-radius: 50%; border: 0.5px solid var(--hairline-strong);
  background: transparent; color: var(--text-muted); font-family: var(--font-mono); font-size: 10px;
  font-style: italic; line-height: 1; display: flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0; flex-shrink: 0;
}
.info-btn:hover, .info-btn[aria-expanded="true"] { color: var(--brass); border-color: var(--brass); }
.info-btn:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }
/* 🔴 `display: none` mientras está cerrada, y no solo `opacity: 0`.
   Una burbuja cerrada seguía ocupando su caja: la de la última tarjeta
   ("Dólar BTC") se anclaba a su botón, medía 230 px y se salía 31 px de la
   ventana, así que `ve.html` tenía scroll horizontal ENTRE 500 Y 1020 px sin
   que nadie hubiera tocado nada. Invisible no es lo mismo que fuera del
   flujo, y el navegador cuenta para el scroll lo que no se ve.
   Encontrado midiendo con el navegador el 20 sep 2026, no mirando la página.

   El fundido se conserva con `allow-discrete` + `@starting-style`, que es lo
   que permite animar algo que entra y sale de `display: none`. Donde no haya
   soporte (Chrome <117, Safari <17.4, Firefox <129) la burbuja simplemente
   aparece y desaparece de golpe: se pierde el fundido, no la información. */
.info-bubble {
  position: absolute; z-index: 30; top: calc(100% + 8px); left: 0; width: max-content; max-width: 230px;
  background: var(--ink); border: 0.5px solid var(--brass-dim); border-radius: 6px; padding: 10px 12px;
  font-size: 12px; line-height: 1.5; color: var(--text-primary); text-transform: none; letter-spacing: normal;
  font-family: var(--font-sans); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  display: none; opacity: 0; pointer-events: none; transform: translateY(-4px);
  transition: opacity 0.15s ease, transform 0.15s ease, display 0.15s allow-discrete;
}
.info-bubble.show { display: block; opacity: 1; pointer-events: auto; transform: translateY(0); }
@starting-style {
  .info-bubble.show { opacity: 0; transform: translateY(-4px); }
}
@media (max-width: 480px) {
  /* En mobile, anclar la burbuja al botón (izquierda o derecha) se
     desborda de la pantalla según en qué columna del grid caiga la
     tarjeta -- verificado, pasaba de verdad con las tarjetas de la
     columna izquierda. Más robusto: en vez de anclarla al botón, se fija
     abajo de la pantalla como una especie de hoja/toast, con margen fijo
     a los dos lados -- así nunca depende de dónde esté el botón. */
  .info-bubble {
    position: fixed; left: 16px; right: 16px; top: auto; bottom: 16px;
    width: auto; max-width: none; transform: translateY(8px);
  }
  .info-bubble.show { transform: translateY(0); }
  @starting-style {
    .info-bubble.show { opacity: 0; transform: translateY(8px); }
  }
}
/* Con 5-7 tarjetas por página (Argentina, Colombia...) el ancho real de
   cada tarjeta puede bajar de 140px, y a 24px fijo un valor como
   "$ 1.591,60" no entra en una sola línea -- se parte justo después del
   símbolo de moneda (el único espacio en blanco del texto), dejando el
   "$" solo arriba y el número abajo, verificado, pasaba de verdad.
   clamp() con cqi (relativo al ancho de la tarjeta, no del viewport) deja
   el tamaño de 24px en tarjetas anchas y lo achica solo lo necesario en
   las angostas -- junto con nowrap, nunca más se parte a la mitad. */
.card-value { margin: 0 0 6px; font-family: var(--font-mono); font-size: clamp(12px, 12.5cqi, 24px); font-weight: 500; white-space: nowrap; }
.card-foot { margin: 0; font-size: 13px; color: var(--text-muted); }
.card-foot.up { color: var(--rust); }
.card-foot.down { color: var(--sage); }
.card-value.up { color: var(--rust); }
.card-value.down { color: var(--sage); }
.card-actions { display: flex; gap: 4px; flex-shrink: 0; }
.card-action-btn {
  background: transparent; border: none; color: var(--text-muted); cursor: pointer;
  padding: 2px; width: 20px; height: 20px; display: flex; align-items: center;
  justify-content: center; border-radius: 3px; flex-shrink: 0;
}
.card-action-btn svg { width: 13px; height: 13px; }
.card-action-btn:hover { color: var(--brass); }
.card-action-btn:focus-visible { outline: 2px solid var(--brass); outline-offset: 1px; }
.card-action-toast {
  position: absolute; top: 8px; right: 12px; font-size: 11px; color: var(--sage);
  background: var(--ink); padding: 2px 6px; border-radius: 3px; opacity: 0;
  pointer-events: none; transition: opacity 0.15s ease;
}
.card-action-toast.show { opacity: 1; }
.card-stats { margin: 8px 0 0; font-size: 11px; color: var(--text-muted); font-family: var(--font-mono); display: flex; gap: 8px; flex-wrap: wrap; }
.history-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 16px; }
.history-head h2 { font-size: 17px; font-weight: 500; margin: 0; }
.dash { width: 14px; height: 0; border-top: 2px dashed var(--text-muted); display: inline-block; }

.bcv-history { margin-bottom: 40px; }
.bcv-history-controls { display: flex; gap: 6px; align-items: center; }
.mini-btn {
  background: transparent; border: 0.5px solid var(--hairline-strong); color: var(--text-muted);
  font-family: var(--font-mono); font-size: 12px; padding: 5px 10px; border-radius: 3px; cursor: pointer;
}
.mini-btn:hover { color: var(--text-primary); border-color: var(--brass); }
.mini-btn:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }
.export-row { display: flex; gap: 8px; margin-top: 10px; }
input.mini-btn[type="date"] { color-scheme: dark; }
input.mini-btn[type="date"]::-webkit-calendar-picker-indicator { filter: invert(0.7); cursor: pointer; }
.bcv-range-label { margin: 0 0 16px; font-size: 13px; color: var(--text-muted); font-family: var(--font-mono); }
.projection-note { margin: 12px 0 0; font-size: 12px; color: var(--text-muted); display: flex; align-items: center; gap: 6px; }

/* Nota de país arriba de las tarjetas -- hoy solo Cuba la usa (avisa que
   falta la comparación con el mercado informal mientras se espera el token
   de El Toque), pero queda genérica por si hace falta en otro país. */
.country-note { margin: 0 0 16px; padding: 10px 14px; font-size: 13px; line-height: 1.5; color: var(--text-muted); background: var(--surface); border: 1px solid var(--hairline); border-radius: 10px; }

.bcv-chart-section { margin-bottom: 40px; }
.bcv-chart-controls { display: flex; align-items: center; gap: 10px; }
.range-toggle { display: flex; gap: 4px; }
.range-toggle button {
  background: transparent; border: 0.5px solid var(--hairline-strong); color: var(--text-muted);
  font-family: var(--font-mono); font-size: 12px; padding: 5px 10px; border-radius: 3px; cursor: pointer;
}
.range-toggle button.active { color: var(--ink); background: var(--brass); border-color: var(--brass); }
.range-toggle button:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }
.chart-wrap { background: var(--surface); border: 0.5px solid var(--hairline); border-radius: 4px; padding: 16px; }
#bcv-full-chart { width: 100%; }

.bcv-table-wrap { background: var(--surface); border: 0.5px solid var(--hairline); border-radius: 4px; overflow-x: auto; }
.bcv-table { width: 100%; border-collapse: collapse; font-family: var(--font-mono); font-size: 12px; font-variant-numeric: tabular-nums; }
.bcv-table th, .bcv-table td { padding: 8px 10px; text-align: right; border-bottom: 0.5px solid var(--hairline); white-space: nowrap; }
.bcv-table th:first-child, .bcv-table td:first-child { text-align: left; }
.bcv-table thead th {
  color: var(--text-muted); font-weight: 500; text-transform: uppercase;
  font-size: 11px; letter-spacing: 0.04em; font-family: var(--font-sans);
}
.bcv-table tbody tr:last-child td { border-bottom: none; }
.bcv-table tbody tr.today td { background: rgba(208, 162, 76, 0.08); }
.bcv-table tbody tr.today td:first-child { color: var(--brass); font-weight: 500; }
.bcv-table tbody tr.projected td { color: var(--text-muted); font-style: italic; }
.bcv-table td.up { color: var(--rust); }
.bcv-table td.down { color: var(--sage); }
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field label { font-size: 12px; color: var(--text-muted); }
.field input, .field select { background: var(--ink); border: 0.5px solid var(--hairline-strong); color: var(--text-primary); border-radius: 3px; padding: 8px 10px; font-family: var(--font-sans); font-size: 14px; }
.field input:focus, .field select:focus { outline: none; border-color: var(--brass); }
/* Histórico USDT/USDC/BTC -- mismo patrón visual que el gráfico completo
   del BCV (chart-wrap, range-toggle ya definidos arriba), con pestañas de
   activo reutilizando la misma pinta de botón. */
.asset-history-section { margin-bottom: 40px; }
.asset-history-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* Tres botones que en realidad son UN control con una posición: en vez de
   que el fondo de latón salte de uno a otro, se desliza una sola pastilla.
   Es un único nodo el que se mueve y los botones no cambian de tamaño, así
   que nada de la página se recoloca al cambiar de pestaña. */
.asset-tabs { position: relative; display: flex; gap: 4px; }
.asset-tabs .asset-tabs-ink {
  position: absolute; top: 0; left: 0; height: 100%; width: 0;
  background: var(--brass); border-radius: 3px; z-index: 0; pointer-events: none;
  transition: transform 0.19s cubic-bezier(0.2, 0.7, 0.3, 1), width 0.19s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.asset-tabs button {
  position: relative; z-index: 1;
  background: transparent; border: 0.5px solid var(--hairline-strong); color: var(--text-muted);
  font-family: var(--font-mono); font-size: 12px; padding: 5px 10px; border-radius: 3px; cursor: pointer;
  transition: color 0.19s ease, border-color 0.19s ease;
}
/* El botón activo pierde su borde y el texto pasa a --ink; el fondo lo pone
   la pastilla, no el botón. .active se conserva porque lo usan el JS y las
   pruebas de siempre; aria-selected es lo que lee un lector de pantalla. */
.asset-tabs button.active { color: var(--ink); background: transparent; border-color: transparent; }
.asset-tabs button:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }
#asset-history-chart { width: 100%; }

/* Comparador secundario -- a propósito más chico/discreto que las tarjetas
   principales, para que quede claro que es información de referencia, no
   la fuente principal del sitio. */
.market-comparison { margin-bottom: 40px; }
.market-comparison h2 { font-size: 15px; font-weight: 500; margin: 0 0 4px; color: var(--text-muted); }
.market-comparison-note { margin: 0 0 14px; font-size: 12px; color: var(--text-muted); }
.market-comparison-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px;
}
.market-comparison-item {
  background: var(--surface); border: 0.5px solid var(--hairline); border-radius: 4px;
  padding: 12px 14px;
}
.market-comparison-item .mc-label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; margin: 0 0 4px; }
.market-comparison-item .mc-value { font-family: var(--font-mono); font-size: 16px; margin: 0; }
.market-comparison-item .mc-source { font-size: 10px; color: var(--text-muted); margin: 4px 0 0; }

.foot { max-width: 760px; margin: 0 auto; padding: 24px 20px 40px; font-size: 12px; color: var(--text-muted); }
.foot-links { display: flex; gap: 16px; margin-top: 8px; flex-wrap: wrap; }
.foot-links a { color: var(--text-muted); }
.foot-links a:hover { color: var(--brass); }

/* Páginas de documentación (como-se-calcula.html, api.html, metrics.html) --
   mismo sistema visual, prosa simple en vez de tarjetas de datos. */
.back-link { display: inline-block; margin-bottom: 20px; font-size: 13px; color: var(--text-muted); text-decoration: none; }
.back-link:hover { color: var(--brass); }
.doc-main { max-width: 640px; margin: 0 auto; padding: 32px 20px 60px; }
.doc-main h1 { font-size: 26px; font-weight: 500; margin: 0 0 8px; }
.doc-intro { color: var(--text-muted); margin: 0 0 32px; font-size: 14px; }
.doc-section { background: var(--surface); border: 0.5px solid var(--hairline); border-radius: 4px; padding: 22px 26px; margin-bottom: 20px; }
.doc-section h2 { font-size: 16px; font-weight: 500; margin: 0 0 10px; color: var(--brass); }
.doc-section p { margin: 0 0 10px; font-size: 14px; line-height: 1.6; }
.doc-section p:last-child { margin-bottom: 0; }
.doc-section code { background: var(--ink); padding: 1px 5px; border-radius: 3px; font-family: var(--font-mono); font-size: 13px; }
.doc-section pre { background: var(--ink); border: 0.5px solid var(--hairline); border-radius: 4px; padding: 14px 16px; overflow-x: auto; font-family: var(--font-mono); font-size: 12.5px; line-height: 1.6; margin: 0 0 14px; }

/* Página "Panorama LATAM" -- barras horizontales comparando la brecha
   oficial/paralelo de los 17 países, agrupadas en tres secciones (control de
   cambio real / flotación libre / economías dolarizadas) para no mezclar
   cosas que no se comparan bien entre sí (ver panorama.js). */
.panorama-intro { color: var(--text-muted); margin: 8px 0 20px; font-size: 14px; max-width: 56ch; }
.panorama-controls { margin: 0 0 28px; }
.panorama-sort-btn { background: transparent; border: 0.5px solid var(--hairline-strong); color: var(--text-muted); font-family: var(--font-sans); font-size: 12px; padding: 8px 12px; border-radius: 3px; cursor: pointer; }
.panorama-sort-btn:hover { color: var(--text-primary); border-color: var(--brass-dim); }
.panorama-group { margin-bottom: 36px; }
.panorama-group h2 { font-size: 15px; font-weight: 500; margin: 0 0 6px; color: var(--brass); }
.panorama-group-note { font-size: 13px; color: var(--text-muted); margin: 0 0 16px; max-width: 60ch; }
.panorama-row {
  display: flex; align-items: center; gap: 12px; padding: 10px 0;
  border-bottom: 0.5px solid var(--hairline); text-decoration: none; color: inherit;
}
.panorama-row:last-child { border-bottom: none; }
/* bandera + nombre en un envoltorio: es la pieza que viaja a la cabecera de
   la página del país. Un view-transition-name se le pone a UN elemento, no a
   dos hermanos. El gap de 12px es el mismo que tenía la fila entre los dos,
   así que visualmente no cambia nada. */
.panorama-id { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.panorama-flag { font-size: 20px; width: 26px; flex-shrink: 0; }
.panorama-name { width: 96px; flex-shrink: 0; font-size: 14px; }
/* Dos líneas por país (USDT y BTC) en vez de una sola barra -- pedido del
   usuario (2026-08-26): la brecha de BTC es su propia historia ("¿conviene
   comprar BTC acá o en otro país?"), separada de "¿conviene migrar a
   USDT?". Cada línea escala contra el máximo de SU propio activo dentro
   del grupo (ver panorama.js) para que un BTC ruidoso en un mercado chico
   no aplaste visualmente las barras de USDT del resto. */
.panorama-bars { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.panorama-bar-line { display: flex; align-items: center; gap: 8px; }
.panorama-bar-asset {
  width: 48px; flex-shrink: 0; font-size: 10px; color: var(--text-muted);
  font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.02em;
  display: flex; align-items: center; gap: 3px;
}
/* Ícono "i" de liquidez baja -- mismo componente que el resto del sitio
   (info-bubbles.js), solo un poco más chico para entrar en la columna
   angosta de 48px junto a la etiqueta "USDT"/"BTC". */
.panorama-liquidity-badge .info-btn { width: 12px; height: 12px; font-size: 8px; }
/* El left: -8px solo vale con la burbuja anclada al botón. En mobile es
   `position: fixed` pegada a los dos lados de la pantalla, y como esta regla
   viene después y es más específica, le pisaba el `left: 16px` y le dejaba el
   borde izquierdo 8 px FUERA de la pantalla. Acotado a partir de 481px, que
   es donde termina el modo hoja/toast. */
@media (min-width: 481px) {
  .panorama-liquidity-badge .info-bubble { left: -8px; }
}
/* La pista valía var(--ink) -- EXACTAMENTE el color de fondo de la página,
   en los dos temas -- así que no se veía: la barra flotaba sin escala contra
   la cual leerla. Con la escala global (decisión del 26 ago 2026), un +0,8%
   al lado de un +62% es un puntito sin nada que diga cuánto falta. Se calcula
   desde el color del texto, así que sirve en los dos temas sin regla aparte. */
.panorama-bar-track { flex: 1 1 auto; height: 14px; background: color-mix(in srgb, var(--text-primary) 9%, transparent); border-radius: 3px; overflow: hidden; min-width: 40px; }
/* scaleX, no width: width obliga a recalcular la página en cada fotograma.
   El relleno ocupa el ancho entero y se escala desde la izquierda. */
.panorama-bar-fill { display: block; width: 100%; height: 100%; background: var(--brass); border-radius: 3px; transform-origin: left center; transform: scaleX(0); transition: transform 0.4s cubic-bezier(0.2, 0.7, 0.3, 1), background-color 0.4s ease; }
/* Sin oferta ese ciclo (más común en BTC de los mercados más chicos) -- un
   track vacío punteado en vez de una barra sólida en 0%, para no leerse
   como "brecha real de cero". */
.panorama-bar-line-empty .panorama-bar-track { background: transparent; border: 0.5px dashed var(--hairline-strong); }

/* Semáforo de la brecha: mismo verde/ámbar/naranja que ya usa el sitio para
   subir/bajar (--sage/--brass/--rust), mezclados con color-mix() en vez de
   hardcodear hex nuevos -- así el degradé sigue el tema claro/oscuro solo.
   5 escalones según % absoluto (ver umbrales en panorama.js gapClass()),
   de "brecha mínima" (spread normal de mercado) a "brecha severa" (control
   de cambio real, ej. Venezuela). Pedido del usuario 2026-08-25. */
/* Un solo token por nivel (--g), que pinta el relleno Y el número. Antes el
   color se quedaba en la barra y la cifra salía en tinta de texto: el mismo
   dato pintado dos veces y una de las dos no se enteraba. Con un token
   compartido no se pueden desincronizar. Pedido de Mario, 20 sep 2026. */
.panorama-bar-fill.gap-minimal, .panorama-pct.gap-minimal { --g: var(--sage); }
.panorama-bar-fill.gap-low, .panorama-pct.gap-low { --g: color-mix(in srgb, var(--sage) 55%, var(--brass) 45%); }
.panorama-bar-fill.gap-mid, .panorama-pct.gap-mid { --g: var(--brass); }
.panorama-bar-fill.gap-high, .panorama-pct.gap-high { --g: color-mix(in srgb, var(--brass) 45%, var(--rust) 55%); }
.panorama-bar-fill.gap-severe, .panorama-pct.gap-severe { --g: var(--rust); }
.panorama-bar-fill { background: var(--g, var(--brass)); }
.panorama-pct { width: 58px; flex-shrink: 0; text-align: right; font-family: var(--font-mono); font-size: 13px; font-weight: 500; color: var(--g, inherit); }
.panorama-pct-muted { color: var(--text-muted); font-weight: 400; font-size: 11px; }
.panorama-link { width: 84px; flex-shrink: 0; text-align: right; font-size: 12px; color: var(--text-muted); }
.panorama-row:hover .panorama-link { color: var(--brass); }
.panorama-row:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; border-radius: 3px; }
@media (max-width: 480px) {
  .panorama-name { width: 72px; font-size: 13px; }
  .panorama-bar-asset { width: 38px; font-size: 9px; }
  .panorama-pct { width: 48px; font-size: 12px; }
  .panorama-link { display: none; }
}
.doc-endpoint { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.doc-method { font-family: var(--font-mono); font-size: 11px; font-weight: 600; color: var(--ink); background: var(--sage); padding: 2px 7px; border-radius: 3px; flex-shrink: 0; }
.doc-path { font-family: var(--font-mono); font-size: 14px; }
.doc-cors { font-size: 11px; color: var(--text-muted); }

/* Panel de métricas (metrics.html) -- no está linkeado desde la navegación,
   solo accesible con la clave por query string. */
.metrics-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin-bottom: 20px; }
.metrics-stat { background: var(--surface); border: 0.5px solid var(--hairline); border-radius: 4px; padding: 16px; }
.metrics-stat .m-label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; margin: 0 0 6px; }
.metrics-stat .m-value { font-family: var(--font-mono); font-size: 22px; margin: 0; }
.metrics-key-form { display: flex; gap: 8px; margin-bottom: 24px; }
.metrics-key-form input { flex: 1; }
.metrics-key-form button { background: var(--brass); color: var(--ink); border: none; border-radius: 3px; padding: 8px 16px; font-weight: 500; cursor: pointer; }
@media (max-width: 640px) {
  /* El toggle de tema le quita ancho al lado derecho del topbar -- en
     pantallas chicas, "Tasa VES · USDT" + "actualizado hace X" ya no
     entran los dos en una sola fila junto al botón. Se deja envolver en
     dos líneas prolijas en vez de que se corten o se superpongan. */
  .topbar { flex-wrap: wrap; row-gap: 10px; padding-bottom: 20px; }
  .cards { grid-template-columns: repeat(2, 1fr); }
  .board-subrow { gap: 24px; }

  /* Título + controles (fecha, rango, escala) de las secciones de
     histórico: en desktop entran cómodos lado a lado, pero en 375px un
     título largo ("Official BCV history") empujaba a los controles y se
     apretaban los dos -- se apilan en su lugar, cada uno con toda la
     fila para sí. */
  .history-head { flex-direction: column; align-items: flex-start; gap: 10px; }
  .bcv-history-controls, .bcv-chart-controls, .asset-history-controls { flex-wrap: wrap; width: 100%; }
  .calc-row { flex-direction: column; align-items: stretch; }
  .calc-equals { align-self: center; }

  /* Tabla del histórico BCV: en vez de forzar scroll horizontal (se veía
     feo, con columnas cortadas a la mitad), cada fila pasa a ser una
     tarjetita apilada -- la fecha como "título" y el resto como pares
     etiqueta/valor debajo. Técnica CSS clásica de tabla responsive: se
     lee la etiqueta de `data-label` (puesto en cada <td> desde JS). */
  .bcv-table-wrap { overflow-x: visible; }
  .bcv-table thead { display: none; }
  .bcv-table, .bcv-table tbody, .bcv-table tr, .bcv-table td { display: block; width: 100%; }
  .bcv-table tr { padding: 12px 14px; border-bottom: 0.5px solid var(--hairline); }
  .bcv-table tbody tr:last-child { border-bottom: none; }
  .bcv-table td {
    display: flex; justify-content: space-between; align-items: baseline;
    padding: 2px 0; border-bottom: none; white-space: normal;
  }
  .bcv-table td::before {
    content: attr(data-label); color: var(--text-muted); font-family: var(--font-sans);
    font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
  }
  .bcv-table td:first-child {
    display: block; text-align: left; font-size: 15px; font-weight: 500;
    color: var(--text-primary); margin-bottom: 4px;
  }
  .bcv-table td:first-child::before { content: none; }
  .bcv-table tr.today td:first-child { color: var(--brass); }
}

.ios-install-banner {
  position: fixed;
  left: 12px; right: 12px;
  bottom: calc(12px + env(safe-area-inset-bottom));
  z-index: 50;
  max-width: 460px;
  margin: 0 auto;
  background: var(--surface);
  border: 0.5px solid var(--hairline-strong);
  border-radius: 10px;
  padding: 12px 12px 12px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.ios-install-icon { width: 40px; height: 40px; border-radius: 9px; flex-shrink: 0; display: block; }
.ios-install-text { flex: 1; margin: 0; font-size: 13px; color: var(--text-primary); line-height: 1.45; }
.ios-install-text strong { color: var(--brass); font-weight: 500; }
.ios-share-icon { display: inline-flex; vertical-align: -5px; color: var(--brass); margin: 0 2px; }
.ios-install-dismiss {
  background: transparent; border: none; color: var(--text-muted);
  font-size: 22px; line-height: 1; cursor: pointer; padding: 4px 8px; flex-shrink: 0;
}
.ios-install-dismiss:hover { color: var(--text-primary); }
.ios-install-dismiss:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }
/* Sin esto, `.ios-install-banner { display: flex }` empataría en
   especificidad con la regla nativa de `[hidden]` y ganaría por venir
   después en la cascada -- el banner se vería aunque tuviera `hidden`. */
.ios-install-banner[hidden] { display: none; }

/* Barra de países -- pastillas con bandera, debajo del header. La activa
   (el país de la página actual) queda resaltada igual que un toggle
   activo en el resto del sitio (fondo latón). */
.country-bar {
  display: flex; gap: 6px; max-width: 760px; margin: 0 auto; padding: 10px 20px;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.country-bar a {
  display: flex; align-items: center; gap: 6px; padding: 5px 12px; flex-shrink: 0;
  border: 0.5px solid var(--hairline-strong); border-radius: 20px; text-decoration: none;
  color: var(--text-muted); font-family: var(--font-mono); font-size: 12px; white-space: nowrap;
}
.country-bar a .flag { font-size: 15px; line-height: 1; }
.country-bar a.active { color: var(--ink); background: var(--brass); border-color: var(--brass); }
.country-bar a:hover:not(.active) { color: var(--text-primary); border-color: var(--brass); }
.country-bar a:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }

/* Calculadora */
.calculator {
  background: var(--surface); border: 0.5px solid var(--hairline); border-radius: 4px;
  padding: 24px 28px; margin-bottom: 40px;
}
.calculator h2 { font-size: 17px; font-weight: 500; margin: 0 0 16px; }
.calc-row { display: flex; align-items: center; gap: 14px; }
.calc-field { flex: 1; flex-direction: row; align-items: stretch; gap: 0; }
.calc-asset-select {
  background: var(--ink); border: 0.5px solid var(--hairline-strong); border-right: none;
  color: var(--brass); border-radius: 3px 0 0 3px; padding: 8px 8px; font-family: var(--font-mono);
  font-size: 14px; font-weight: 500; flex-shrink: 0;
}
.calc-field input {
  background: var(--ink); border: 0.5px solid var(--hairline-strong); color: var(--text-primary);
  border-radius: 0 3px 3px 0; padding: 8px 10px; font-family: var(--font-mono); font-size: 16px;
  width: 100%; min-width: 0;
}
.calc-field:last-child input { border-radius: 3px; }
.calc-field input:focus, .calc-asset-select:focus { outline: none; border-color: var(--brass); }
.calc-equals { font-size: 18px; color: var(--text-muted); flex-shrink: 0; }
.calc-rate-note { margin: 14px 0 0; font-size: 12px; color: var(--text-muted); }

.alerts {
  background: var(--surface); border: 0.5px solid var(--hairline); border-radius: 4px;
  padding: 24px 28px; margin-bottom: 40px;
}
.alerts h2 { font-size: 17px; font-weight: 500; margin: 0 0 6px; }
.alerts-intro { margin: 0 0 20px; font-size: 14px; color: var(--text-muted); }
.alert-submit {
  background: var(--brass); color: var(--ink); border: none; border-radius: 3px;
  padding: 9px 16px; font-weight: 500; font-size: 14px; cursor: pointer; white-space: nowrap;
}
.alert-submit:hover { background: #DCAE5C; }
.alert-submit:disabled { opacity: 0.5; cursor: default; }
/* Push (item 15) es la opción secundaria -- outline en vez de sólido, para
   no competir visualmente con el botón de Telegram (la opción principal). */
.push-submit { background: transparent; color: var(--brass); border: 0.5px solid var(--brass-dim); margin-top: 14px; }
.push-submit:hover:not(:disabled) { background: rgba(208, 162, 76, 0.1); }
.alert-link-box { margin-top: 18px; padding: 16px; background: var(--ink); border: 0.5px solid var(--brass-dim); border-radius: 4px; }
.alert-link-box p { margin: 0 0 10px; font-size: 14px; }
.alert-telegram-btn {
  display: inline-block; background: #2AABEE; color: #fff; text-decoration: none;
  font-weight: 500; font-size: 14px; padding: 10px 18px; border-radius: 20px;
}
.alert-telegram-btn:hover { background: #1c96d6; }
.alert-link-note { margin: 10px 0 0 !important; font-size: 12px; color: var(--text-muted); }
.alert-status { margin: 14px 0 0; font-size: 13px; color: var(--text-muted); min-height: 1em; }
.alert-status.ok { color: var(--sage); }
.alert-status.error { color: var(--rust); }

/* ─────────────────────────────────────────────────────────────────────────
   Frescura del BCV: dos relojes distintos bajo una sola etiqueta, no.
   El USDT es de hace minutos; la tasa del BCV puede ser del viernes y regir
   el lunes. Hasta el 20 sep 2026 las dos compartían el "actualizado hace
   3 min" del topbar, que es la hora en que NOSOTROS leímos -- siempre
   fresca, aunque la tasa fuera de otro día.
   ───────────────────────────────────────────────────────────────────────── */
.bcv-freshness { margin: 10px 0 0; border-top: 0.5px solid var(--hairline); padding-top: 9px; display: grid; grid-template-columns: auto 1fr; gap: 3px 14px; font-size: 12px; }
.bcv-freshness dt { color: var(--text-muted); }
.bcv-freshness dd { margin: 0; font-family: var(--font-mono); }
.bcv-freshness .lead dd { color: var(--brass); }
.bcv-freshness[hidden] { display: none; }
/* El aviso de la tasa ya publicada que todavía NO rige. Es la mitad de la
   decisión del 20 sep 2026, no un adorno: sin él, mostrar la vigente
   reintroduce el problema del 14 de septiembre (el lunes feriado seguía
   saliendo la del viernes cuando todo el mundo ya daba la del martes).
   Se ve la nueva, pero no se presenta como la de hoy. */
.bcv-proxima { margin: 10px 0 0; padding: 7px 10px; border-left: 2px solid var(--brass-dim); background: color-mix(in srgb, var(--brass) 7%, transparent); font-size: 12px; color: var(--text-muted); border-radius: 0 3px 3px 0; }
.bcv-proxima strong { color: var(--brass); font-family: var(--font-mono); font-weight: 500; }
.bcv-proxima[hidden] { display: none; }

/* ─────────────────────────────────────────────────────────────────────────
   Transición entre el panorama y la página de un país.
   Dos escalones: el fundido lo hace el navegador solo con estas tres líneas
   (las dos páginas son del mismo dominio y cargan este mismo archivo); el
   traslado de la bandera + el nombre lo añade el JS poniendo
   view-transition-name a la fila que se tocó. El navegador que no soporte
   la API navega como siempre -- no hay nada que se rompa.
   ───────────────────────────────────────────────────────────────────────── */
@view-transition { navigation: auto; }
::view-transition-old(pais), ::view-transition-new(pais) { animation-duration: 0.28s; }
/* El otro extremo del traslado: en la página de un país, bandera + nombre
   del topbar. La clase está SOLO en las 24 páginas de país -- en el panorama
   el topbar dice "Dollar Now" y no es el destino de nada; si llevara el
   mismo nombre habría dos elementos marcados a la vez y no animaría ninguno. */
.topbar-mark-pais { view-transition-name: pais; }

/* ─────────────────────────────────────────────────────────────────────────
   Reducir movimiento: todo llega a su estado final, sin animarse. Ninguna
   información depende de que algo se mueva, así que no se pierde nada.
   ───────────────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0ms !important;
    transition-duration: 0.001ms !important;
  }
  @view-transition { navigation: none; }
}
