/* ============================================================
   TradingFight — TOKENS
   Fuente única de verdad del lenguaje visual. Ver docs/context/DESIGN_SYSTEM.md
   Aprobado 2026-07-15.

   PRINCIPIO RECTOR: el color es información, no decoración.
   En una plataforma de trading, verde y rojo SIGNIFICAN algo. Gastarlos en
   adornar destruye esa señal.

   Este fichero se carga ANTES que main.css. Solo define variables: no puede
   romper nada por sí solo.

   Sin build step (ver PROJECT.md) -> CSS Custom Properties, no Sass.
   ============================================================ */

:root {
    /* ── SUPERFICIES ─────────────────────────────────────────
       La jerarquía se expresa subiendo de capa, NO con sombras.
       Gris frío con tinte azul: el negro puro produce halos en OLED
       y cansa en sesiones largas (un trader mira esto durante horas). */
    --tf-bg-base:      #0A0C10;   /* fondo de la app */
    --tf-bg-sunken:    #070910;   /* hundido: inputs, pozo del gráfico */
    --tf-surface-1:    #12151C;   /* por defecto: paneles, cards */
    --tf-surface-2:    #181C25;   /* elevada: header, hover, dropdowns */
    --tf-surface-3:    #20252F;   /* flotante: modales, popovers */

    /* ── BORDES ─────────────────────────────────────────────── */
    --tf-border-subtle:  #232833;  /* separadores, líneas de tabla */
    --tf-border-default: #2E3441;  /* borde de panel */
    --tf-border-strong:  #3D4552;  /* foco, activo */

    /* ── TEXTO (contrastes verificados WCAG AA sobre --tf-surface-1) ── */
    --tf-text-primary:   #E8EBF0;  /* ~14:1  — cifras, títulos */
    --tf-text-secondary: #9AA3B2;  /* ~6.5:1 — etiquetas */
    --tf-text-tertiary:  #5E6675;  /* ~3.2:1 — solo texto NO esencial */

    /* ── ACENTO DE MARCA — UNO SOLO ──────────────────────────
       Azul a propósito: es el único color que no compite con la
       semántica verde/rojo del trading. */
    --tf-accent:       #4C8DFF;
    --tf-accent-hover: #6BA1FF;
    --tf-accent-muted: #1C2B47;   /* fondo sutil de "seleccionado" */
    --tf-accent-ink:   #08111F;   /* texto sobre --tf-accent */

    /* ── SEMÁNTICA DE TRADING — SAGRADA ──────────────────────
       🔴 NO USAR PARA NADA MÁS. Ni un botón de borrar en --tf-loss,
       ni un "éxito" en --tf-profit. Para eso están los de sistema. */
    --tf-profit:    #26A96C;
    --tf-profit-bg: #0E2B1E;
    --tf-loss:      #E5484D;
    --tf-loss-bg:   #2E1416;
    --tf-neutral:   #7A8494;

    /* ── ESTADO DEL SISTEMA (separado de la semántica de trading) ──
       Desaturados a propósito: un aviso no debe gritar más que el precio. */
    --tf-success: #3E9E75;
    --tf-warning: #C99A2E;
    --tf-danger:  #C0484D;
    --tf-info:    #4C8DFF;

    /* ── LIGAS — metales apagados, sin brillos ───────────────── */
    --tf-tier-bronze:   #9C6B4A;
    --tf-tier-silver:   #9BA3AD;
    --tf-tier-gold:     #C6A15B;
    --tf-tier-platinum: #6FA5A8;
    --tf-tier-diamond:  #7C93C9;

    /* ── TIPOGRAFÍA ──────────────────────────────────────────
       Self-hosted (ver fonts.css). Nada de CDN: ya hay 4 dominios
       externos en la ruta crítica. */
    --tf-font-ui:   'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --tf-font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', 'Roboto Mono', monospace;

    /* Base 14px, no 16px: la densidad es un requisito. Las terminales
       financieras trabajan a 12-14px porque la información por pantalla
       importa más que la comodidad de lectura larga. */
    --tf-text-xs:   11px;
    --tf-text-sm:   12px;
    --tf-text-base: 14px;
    --tf-text-lg:   16px;
    --tf-text-xl:   20px;
    --tf-text-2xl:  28px;
    --tf-text-3xl:  40px;

    --tf-leading-tight: 1.25;
    --tf-leading-base:  1.5;

    /* Pesos: 400 cuerpo, 500 énfasis, 600 títulos y cifras.
       NUNCA 700+: la negrita gruesa es lenguaje de videojuego. */
    --tf-weight-normal: 400;
    --tf-weight-medium: 500;
    --tf-weight-semi:   600;

    /* ── ESPACIADO — escala de 4 ─────────────────────────────── */
    --tf-space-1: 4px;
    --tf-space-2: 8px;
    --tf-space-3: 12px;
    --tf-space-4: 16px;
    --tf-space-5: 24px;
    --tf-space-6: 32px;
    --tf-space-7: 48px;
    --tf-space-8: 64px;

    /* ── RADIOS — pequeños = instrumento ─────────────────────
       Los radios grandes (12-16px) son lenguaje de app de consumo. */
    --tf-radius-sm:   3px;
    --tf-radius-md:   5px;
    --tf-radius-lg:   8px;
    --tf-radius-full: 9999px;

    /* ── SOMBRAS — tres en toda la app, NINGUNA de color ──────
       🔴 Ningún box-shadow con color de marca. Ningún glow.
       Es lo que más "cripto-gaming" hace. La elevación se consigue
       subiendo de --tf-surface-N. */
    --tf-shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);
    --tf-shadow-md: 0 4px 12px rgba(0, 0, 0, .4);
    --tf-shadow-lg: 0 12px 32px rgba(0, 0, 0, .5);   /* solo modales */

    /* ── MOVIMIENTO ──────────────────────────────────────────
       Solo se animan transform y opacity. Nada más. */
    --tf-motion-fast: 120ms;
    --tf-motion-base: 200ms;
    --tf-motion-slow: 320ms;
    --tf-ease: cubic-bezier(.2, 0, 0, 1);
}

/* ============================================================
   UTILIDADES BASE
   ============================================================ */

/* Cifras tabulares: OBLIGATORIO en precios, P&L, ELO, saldos, contadores
   y cualquier columna numérica.
   Sin esto, un precio que pasa de 41.999 a 42.000 CAMBIA DE ANCHO y baila.
   En un ticker que actualiza cada segundo, ese temblor es la diferencia
   más barata y más visible entre "una app" y "una terminal". */
.tf-tabular,
.tf-num {
    font-family: var(--tf-font-mono);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

/* Semántica de mercado */
.tf-profit  { color: var(--tf-profit); }
.tf-loss    { color: var(--tf-loss); }
.tf-neutral { color: var(--tf-neutral); }

/* ============================================================
   ANILLOS DE AVATAR — familia ÚNICA
   Sustituye a las 6 familias paralelas (ps-, pf-, lb-, gp-, uc-, hd-):
   202 selectores con keyframes triplicados byte a byte.
   El marco es un anillo NÍTIDO, no un halo difuso. La rareza se lee por
   precisión y contención, no por cuánto brilla.
   Sin animación -> el tono serio y el rendimiento salen de la misma acción.
   ============================================================ */
.tf-ring {
    position: relative;
    border-radius: var(--tf-radius-full);
}

.tf-ring::after {
    content: '';
    position: absolute;
    inset: -3px;
    border-radius: var(--tf-radius-full);
    border: 2px solid var(--tf-ring-color, var(--tf-border-strong));
    pointer-events: none;
}

/* Rareza alta: un SEGUNDO FILO FINO, no un resplandor. */
.tf-ring-elite::before {
    content: '';
    position: absolute;
    inset: -6px;
    border-radius: var(--tf-radius-full);
    border: 1px solid var(--tf-ring-color, var(--tf-border-strong));
    opacity: .38;
    pointer-events: none;
}

.tf-ring-common    { --tf-ring-color: var(--tf-border-strong); }
.tf-ring-uncommon  { --tf-ring-color: var(--tf-tier-bronze); }
.tf-ring-rare      { --tf-ring-color: var(--tf-tier-silver); }
.tf-ring-epic      { --tf-ring-color: var(--tf-tier-gold); }
.tf-ring-legendary { --tf-ring-color: var(--tf-tier-platinum); }
.tf-ring-mythic    { --tf-ring-color: var(--tf-tier-diamond); }

/* ── GEOMETRÍA DEL MARCO ─────────────────────────────────────
   La RAREZA da el color (arriba). La GEOMETRÍA distingue marcos de la MISMA rareza:
   sin esto, los 7 marcos épicos se verían idénticos (mismo filo dorado) y coleccionar
   35 marcos no tendría sentido. Decisión de producto aprobada por el dueño (16-jul).

   Solo `border-style` / `border-width` → sigue siendo un filo NÍTIDO. Sin box-shadow de
   color, sin filter, sin animación: cumple el tono serio y el coste por frame ≈ 0.
   `solid` es el filo por defecto (.tf-ring::after) y NO lleva clase. Estas ganan por
   ORDEN (van después) con la misma especificidad, no por fuerza. */
.tf-ring-g-dashed::after { border-style: dashed; }
.tf-ring-g-dotted::after { border-style: dotted; }
.tf-ring-g-double::after { border-style: double; border-width: 3px; }
.tf-ring-g-groove::after { border-style: groove; border-width: 3px; }
.tf-ring-g-ridge::after  { border-style: ridge;  border-width: 3px; }
.tf-ring-g-inset::after  { border-style: inset;  border-width: 3px; }
.tf-ring-g-outset::after { border-style: outset; border-width: 3px; }

/* ============================================================
   BADGE DE LIGA — punto + etiqueta, sin halo
   ============================================================ */
.tf-tier {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--tf-text-xs);
    color: var(--tf-text-secondary);
    white-space: nowrap;
}

.tf-tier-dot {
    width: 6px;
    height: 6px;
    border-radius: var(--tf-radius-full);
    flex-shrink: 0;
    background: var(--tf-tier-color, var(--tf-neutral));
}

.tf-tier-bronce   { --tf-tier-color: var(--tf-tier-bronze); }
.tf-tier-plata    { --tf-tier-color: var(--tf-tier-silver); }
.tf-tier-oro      { --tf-tier-color: var(--tf-tier-gold); }
.tf-tier-platino  { --tf-tier-color: var(--tf-tier-platinum); }
.tf-tier-diamante { --tf-tier-color: var(--tf-tier-diamond); }

/* ============================================================
   BADGE "DEMO"
   Los datos de previsualización son una FEATURE del dueño, pero deben ser
   EXPLÍCITOS y nunca dispararse por un error: un fallback silencioso ante
   fallo es lo que ocultó durante meses que /api/leaderboard y /api/clans
   devolvían 500 (BUG-062, BUG-066). La app fingía funcionar.
   ============================================================ */
.tf-badge-demo {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: var(--tf-text-xs);
    font-weight: var(--tf-weight-medium);
    padding: 2px var(--tf-space-2);
    border-radius: var(--tf-radius-sm);
    text-transform: uppercase;
    letter-spacing: .05em;
    background: var(--tf-surface-2);
    color: var(--tf-warning);
    border: 1px solid var(--tf-warning);
}

/* ============================================================
   MOVIMIENTO REDUCIDO
   Se respeta tanto la preferencia del SO como el toggle de Ajustes
   (app.js:_applyReducedMotion, arreglado el 15-jul: antes no sobrevivía
   a un reload, justo para quien más lo necesitaba).
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
    :root {
        --tf-motion-fast: 0.01ms;
        --tf-motion-base: 0.01ms;
        --tf-motion-slow: 0.01ms;
    }
}
