/* ==========================================================================
   MAK EDGE LAB — shared stylesheet for the hand-built pages
   Used by /tools, /setup, /faq, /docs and the content pages.
   The homepage keeps its Webflow stylesheet; this file deliberately does NOT
   depend on it, so these pages load without GSAP, Lenis, Barba or three.js.
   Tokens are matched to the homepage so both read as one site.
   ========================================================================== */

/* ---------- fonts: self-hosted, no external requests ---------- */
@font-face {
  font-family: Fraunces;
  src: url("/assets/fonts/fraunces-normal-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: Fraunces;
  src: url("/assets/fonts/fraunces-italic-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: Inter;
  src: url("/assets/vendor/66f1187e78a7b0a165e70cd6_inter-v12-latin-regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: Inter;
  src: url("/assets/vendor/66f1187e78a7b0a165e70cdd_inter-v12-latin-700.woff") format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ---------- tokens ---------- */
/* 🔴 LOS TRES DE ARRIBA LOS CAMBIO EL DUENO EL 4 SEP, igualandolos a los de
   `freefrontend.com/javascript-animations/`, que le gusta como se ve. Medidos en esa
   pagina, no copiados de memoria: fondo `rgb(25,25,25)`, texto principal declarado
   `rgba(255,255,255,.85)` —que sobre ese fondo se ve `#dddddd`— y secundario `#6b7280`.

   | token | antes | ahora | contraste antes | ahora |
   |-------|-------|-------|-----------------|-------|
   | --bg   | #090909 | #191919 | — | — |
   | --ink  | #ECEEEA | #DDDDDD | 17,0:1 | 12,9:1 |
   | --body | #9D9D9D | #6B7280 | 7,3:1  | **3,6:1** |

   ⚠️ **`--body` QUEDA EN 3,6:1, POR DEBAJO DEL 4,5 QUE PIDE UN TEXTO NORMAL.** Se avisa
   antes de aplicarlo y se aplica igual porque es su decision, tomada con el dato
   delante: en la pagina de referencia ese mismo color se usa 125 veces y tambien esta
   por debajo. **No es un descuido: es una eleccion informada.**

   ⚠️ Y UNA CONSECUENCIA QUE NO SE TOCO: `--muted` (#8A8787) y `--faint` (#6E756E)
   quedan mas CLAROS que `--body`, o sea la escala se invierte. La referencia tiene 3
   niveles de texto y esta paleta tiene 4, asi que no hay sitio para los dos ultimos.
   No se recolocan aqui a proposito: bajar `--muted` romperia el arreglo de la tarea 43
   —los porcentajes de la home— que se cerro ese mismo dia. Decision suya cuando quiera. */
:root {
  --bg:          #090909;   /* 4 sep: se probo #191919 y el dueno lo devolvio al original */
  --surface:     #101211;
  --surface-2:   #161918;
  --line:        #242826;
  --rule:        #333835;

  --ink:         #DDDDDD;   /* era #ECEEEA — 12.9:1 on --bg */
  --body:        #83858A;   /* 5,39:1 sobre --bg · 4,79 sobre la tarjeta de la FAQ. Ver la 47 */
  --muted:       #8A8787;   /* 4.94:1 on --bg — era 5.59 sobre el fondo viejo */
  --faint:       #7C837C;   /* 5,12:1 — era #6E756E, 4,20:1 */

  --primary:     #FBC30F;   /* 12.2:1 on --bg */
  --on-primary:  #111111;   /* never white on gold */
  --border-ctl:  #606565;   /* 3.4:1 — input and control boundaries */
  --danger:      #F2705C;   /* errores de formulario. Medido, ver mas abajo */

  --measure: 68ch;
}

*, *::before, *::after { box-sizing: border-box; }

html { background: var(--bg); }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, sans-serif;
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

/* ---------- enlaces: SUELO DE COLOR ----------
   Sin esta regla, un enlace que caiga fuera de un contenedor con estilo propio
   se queda con el azul del navegador. El 2 sep se midieron 42 asi, en 9 paginas:
   `rgb(0,0,238)` sobre `--bg`, que da 2,12:1 cuando el minimo para texto es 4,5.

   CAUSA: la hoja estilaba enlaces SOLO por contenedor —`.prose a`,
   `.site-footer a`, `.nav-overlay a`, `.index-list a`, `.contact-rows a`— y no
   habia suelo. Todo enlace de texto fuera de esos caia al azul. Se veia en
   /faq y /contact (14 cada una, del mismo partial), /docs (5), /how-we-build,
   /tools/mgi-hud-x y /tools/mgi-ict (2 cada una), /order-flow,
   /liquidity-zones y /setup (1 cada una).

   POR QUE ESTO NO ROMPE NADA DE LO YA ESTILADO: un `<a>` sin regla de autor no
   hereda el color de su padre — el navegador le impone el suyo. Asi que los
   unicos enlaces sin regla eran EXACTAMENTE los 42 azules. Y las reglas por
   contenedor son de 2 componentes (0-1-1) contra 1 de esta (0-0-1): siguen
   ganando todas. El logotipo tampoco cambia: sus tres `span` van pintados
   aparte y el `<a>` no tiene texto propio.

   `--primary` es el mismo que ya usaba `.prose a`, y da 12,2:1 sobre `--bg`.
   `:visited` se declara aparte para no depender de la precedencia de origen
   frente a la hoja del navegador. */
/* 🔴 `:not(.btn)` NO ES UN ADORNO: SIN EL, EL BOTON DE COMPRAR ERA INVISIBLE.
   Descubierto el 3 sep porque el dueno vio «un boton sin nombre». No era un
   boton sin texto: era texto DORADO SOBRE FONDO DORADO. Contraste medido: 1.00.

   La cadena de especificidad, medida en el DOM y no deducida:

       a                0-0-1   dorado   <- suelo de enlaces
       .btn             0-1-0   --on-primary (casi negro)
       a:visited        0-1-1   dorado   <- LE GANA A .btn
       .prose a         0-1-1   dorado   <- LE GANA A .btn
       .btn.ghost       0-2-0   --ink    <- este SI ganaba, por eso el
                                            secundario se leia bien

   ⚠️ AFECTABA A DOS BOTONES, Y UNO ERA «Buy — $279 USD». El unico boton del
      sitio que cobra dinero era un rectangulo dorado vacio. El otro, el «See
      the tools» de `/prop`.

   ⚠️ NO ES CULPA DEL SUELO DE ENLACES DEL 2 SEP. `.prose a` existe desde el
      refactor original a PHP — comprobado con `git log -S`. El suelo (0-0-1) ni
      siquiera le gana a `.btn`. Lo que gana es `.prose a` y `a:visited`.

   ➡️ SE ATACA LA CAUSA, NO EL SINTOMA. Lo facil era anadir un override mas
      especifico encima; eso deja la regla equivocada en pie y el siguiente
      boton dentro de `.prose` vuelve a romperse. Lo correcto es decir lo que
      siempre se quiso decir: **el color de enlace es para los ENLACES, no para
      los botones**. Con `:not(.btn)` fuera, `.btn` vuelve a ser la unica regla
      que les toca el color.

   ⚠️ Y NO SE DEJA AL ORDEN DE APARICION. Empatar en especificidad y confiar en
      que esta mas abajo es lo que ya fallo con `.price strong` (2 sep) y con
      `.field-error` (3 sep, la misma manania). A la tercera se cambia el metodo. */
/* 🔴 `.skip` ENTRA EN LA EXCLUSION EL 4 SEP — MISMO AGUJERO, TERCERA VEZ.
   El «Skip to content» —el enlace que deja a quien navega con teclado saltarse el
   menu— salia DORADO SOBRE DORADO al recibir el foco: 1,00:1, medido pulsando Tab
   de verdad y visto en captura (un rectangulo amarillo vacio arriba a la izquierda).

       a:not(.btn)   0-1-1   dorado            <- ganaba
       .skip         0-1-0   --on-primary

   Es EXACTAMENTE la cadena de la tarea 42, y el arreglo de entonces no lo cubrio
   porque solo se penso en `.btn`. La regla dice «el color de enlace es para los
   ENLACES»: `.skip` tampoco es un enlace de texto, es un control con su propio
   fondo. Por eso se amplia la exclusion en vez de anadir un override mas
   especifico encima — que es justo lo que el comentario de arriba prohibe.

   ⚠️ Y una correccion al diagnostico previo: se dijo que ademas le faltaba la regla
   `:focus`. **Es falso.** `.skip:focus` existe y funciona: al pulsar Tab aparece en
   x=8, y=8. El falso negativo salio de llamar a `focus()` dentro de un iframe. Solo
   fallaba el color.

   🔴 POR QUE `:where()` Y NO `:not(.btn):not(.skip)` A SECAS. El primer intento fue
   ese, y ROMPIO EL PIE EN EL ACTO: encadenar dos `:not()` de clase sube la regla de
   **0-1-1 a 0-2-1**, con lo que pasa a ganarle a `.site-footer a` (0-1-1) y los 17
   enlaces del pie se volvieron dorados. Se caza en el barrido, no llego a la
   pantalla del dueno — pero es la MISMA trampa que este archivo lleva documentando
   desde el 2 sep, ahora mordiendo por el otro lado: no solo hay que mirar a quien le
   gana una regla, sino **a quien deja de perder**.

   `:where()` tiene especificidad CERO, asi que excluye sin sumar nada:

       a:not(:where(.btn,.skip))           0-0-1   <- pierde contra todo lo demas
       .btn                                0-1-0   <- gana: botones bien
       .skip                               0-1-0   <- gana: el skip, casi negro
       .site-footer a / .prose a           0-1-1   <- ganan: pie y prosa intactos

   ⚠️ Y de paso arregla algo que ya estaba mal: `a:visited:not(.btn)` era **0-2-1**,
   asi que un enlace del pie YA VISITADO le ganaba a `.site-footer a` y salia dorado.
   Con `:where()` baja a 0-1-1 y empata, ganando la del contenedor por ir despues. */
a:not(:where(.btn, .skip)) { color: var(--primary); }
a:visited:not(:where(.btn, .skip)) { color: var(--primary); }

/* ---------- accessibility baseline ---------- */
:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: 2px;
}
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--primary); color: var(--on-primary);
  padding: 12px 18px; font-weight: 600;
}
.skip:focus { left: 8px; top: 8px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
html { scroll-behavior: smooth; }

/* ---------- layout ---------- */
.wrap { max-width: 1120px; margin: 0 auto; padding: 0 24px; }

/* ---------- header ----------
   Matches the homepage pattern: menu opener on the left, logo centred,
   links behind a full-screen overlay. Built without GSAP/Barba. */
.site-header {
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 60;
  background: rgba(9, 9, 9, .92);
  backdrop-filter: blur(8px);
}
.site-header .wrap {
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; min-height: 68px; gap: 12px;
}

.nav-toggle {
  justify-self: start;
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 0 2px; background: none; border: 0; cursor: pointer;
  color: var(--ink); font-family: inherit; font-size: 15px; line-height: 1;
}
.nav-toggle:hover { color: var(--primary); }
.nav-toggle .lbl-close { display: none; }
.nav-toggle[aria-expanded="true"] .lbl-open  { display: none; }
.nav-toggle[aria-expanded="true"] .lbl-close { display: inline; }

.brand {
  justify-self: center;
  font-family: Inter, ui-sans-serif, system-ui, sans-serif;
  font-weight: 900; font-size: 20px; text-transform: uppercase;
  text-decoration: none; white-space: nowrap;
  display: inline-flex; gap: .34em; align-items: baseline;
}
.brand .a { color: var(--primary); }   /* MAK and LAB */
.brand .m { color: #FFFFFF; }          /* EDGE */

/* El rotulo paso de texto a imagen el 10 sep. Las reglas de arriba se quedan:
   `.brand` sigue dando la posicion y el `.a`/`.m` no estorban, pero vuelven solas
   si algun dia se revierte.

   🔴 POR QUE CRECE A 210 EN ESCRITORIO Y NO EN MOVIL, que es al reves de lo normal.
   Lo vio el dueno: «lo veo poco nitido». Medido, y la causa NO era el archivo:
   · El movil YA ESTA NITIDO. Sus pantallas meten 2 o 3 pixeles fisicos por cada
     uno de diseno, asi que 155px con densidad 3 son 465 pixeles reales — y la
     imagen trae 454. Practicamente 1:1.
   · El ESCRITORIO va a densidad 1: 155px son 155 pixeles y punto. Y este logo
     lleva contornos y cortes internos finos que a 16px de alto miden 1 pixel.
     Se comprobo simulando el filtro del navegador a 155, 190 y 227: a 155 «EDGE»
     se emborrona, a 227 se lee limpio.
   ➡️ Se sube solo donde hace falta. A 1402px de ancho sobran 379px hasta el
      «Menu»; a 375px, con 210 quedarian 15px y se veria apretado.
   ⚠️ Y el archivo tambien se rehizo: era de 800px y el navegador reducia 5,16x
      con un filtro barato. Ahora son 454 (2x exacto de la home) y reduce 2,00x
      alli y 2,93x aqui. */
.brand img { display: block; width: 155px; height: auto; }
@media (min-width: 761px) { .brand img { width: 210px; } }

/* ---------- overlay menu ---------- */
.nav-overlay {
  position: fixed; inset: 0; z-index: 50;
  background: var(--bg);
  display: grid; align-content: center;
  padding: 96px 24px 48px;
  visibility: hidden; opacity: 0;
  transition: opacity .28s ease, visibility 0s linear .28s;
}
.nav-overlay[data-open="true"] {
  visibility: visible; opacity: 1;
  transition: opacity .28s ease, visibility 0s;
}
.nav-overlay ul {
  list-style: none; margin: 0 auto; padding: 0;
  width: 100%; max-width: 1120px;
}
.nav-overlay a {
  display: block; text-decoration: none; color: var(--body);
  font-family: Fraunces, Georgia, serif; font-weight: 600;
  font-size: clamp(30px, 5.4vw, 52px); line-height: 1.22;
  padding: 4px 0;
}
.nav-overlay a:hover { color: var(--ink); }
.nav-overlay a[aria-current="page"] { color: var(--primary); }
.nav-overlay .meta {
  max-width: 1120px; margin: 40px auto 0; padding-top: 22px;
  border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 8px 40px;
  font-size: 14px; color: var(--faint);
}
.nav-overlay .meta a {
  font-family: Inter, sans-serif; font-size: 14px; font-weight: 400;
  color: var(--body); padding: 0;
}
body.nav-open { overflow: hidden; }

/* ---------- page head ---------- */
.page-head { padding: 72px 0 40px; border-bottom: 1px solid var(--line); }
.eyebrow {
  font-size: 12px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--primary); font-weight: 700; margin: 0 0 18px;
}
h1 {
  font-family: Fraunces, Georgia, serif; font-weight: 600;
  font-size: clamp(38px, 6vw, 66px); line-height: 1.02;
  letter-spacing: -.015em; margin: 0 0 20px; text-wrap: balance;
}
.lede { max-width: var(--measure); color: var(--body); font-size: 18px; margin: 0; }
.lede strong { color: var(--ink); font-weight: 600; }

/* ---------- el reparto de lineas de los titulares — 4 sep, lo vio el dueno ----------
   Lo encontro el en el H1 de la home: "Indicators that make the market" y, debajo,
   "readable" sola, con la linea de arriba a tope. Dijo que ese detalle "da la
   impresion de que no se trata de una pagina web profesional", y al barrer salio
   que no era un caso: 33 titulares del sitio partian dejando UNA palabra sola.

   | ancho | paginas | viudas antes | despues |
   |-------|---------|--------------|---------|
   |  430  | 10 / 23 |      18      |    2    |
   |  768  |  3 / 23 |       5      |    0    |
   | 1024  |  6 / 23 |      10      |    0    |

   CAUSA: el navegador reparte en modo "greedy" —llena cada linea al maximo y lo
   que sobra cae solo—. `balance` reparte a partes iguales: el H1 del hero pasa de
   5+1 palabras a 3+3.

   ⚠️ POR QUE AQUI *Y* EN EL <style> DE index.php, Y NO EN UN SOLO SITIO: la home y
   las otras 22 paginas NO comparten hoja. La home carga solo `webflow.css`; las
   internas cargan solo `site.css`. Escribirlo una vez deja fuera la mitad del sitio
   — y eso es justo lo que pasaba: `h1` ya tenia `text-wrap: balance` desde antes
   (ahi arriba, linea ~237) y no llegaba ni a la home ni a ningun h2/h3.

   ⚠️ Quedan 2 sin arreglar a 430, y no es un fallo de la regla: Chrome deja de
   equilibrar por encima de unas 6 lineas, por coste. Son dos titulares de 8.

   Donde no hay soporte (Safari < 17.5, Firefox < 121) se ignora y se ve como hoy. */
h2, h3, h4 { text-wrap: balance; }

/* ---------- the index ---------- */
.index { padding: 34px 0 8px; }
.index-label {
  font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted); font-weight: 700; margin: 0 0 16px;
}
.index-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1px;
  background: var(--line); border: 1px solid var(--line);
}
/* Modificador para índices de 5 secciones. Con el minmax por defecto (230px) el
   quinto ítem cae solo a una segunda fila y deja tres celdas vacías. Bajar el
   mínimo a 196px permite que los 5 entren en una fila a anchos de escritorio, y
   sigue reflotando solo en pantallas estrechas. Sin `status` en estos ítems: a
   5 columnas no hay sitio para título + estado en la misma línea. */
.index-list.five { grid-template-columns: repeat(auto-fit, minmax(196px, 1fr)); }

/* Modificador para el indice de /tools — 30 ago, auditoria UX.
   Se diseño cuando la lista tenia DOS entradas y la mas larga era "MGI HUD X",
   9 caracteres. Hoy sale del array de indicadores y llega a 21
   ("Market Auction Live X"). Con el minmax por defecto caben 4 columnas de
   ~268px, y el presupuesto de una celda es: 40px de padding + 18 del numero +
   24 de huecos = 82px, quedan 186 para un titulo de 20px en Fraunces MAS el
   estado. El titulo se partia en dos lineas y el estado, con
   `align-items: baseline`, se quedaba clavado en la primera, visualmente
   desprendido del nombre al que se refiere.
   A 320px salen 3 columnas, y 12 entre 3 son 4 filas exactas sin huerfanas,
   con el estado en su propia linea debajo del titulo.
   ⚠️ NO se toca `.index-list` a secas: la comparten OCHO paginas, varias con 3,
   4 o 5 items, donde 320px dejaria celdas vacias. Por eso va como modificador. */
.index-list.wide { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.index-list.wide a,
.index-list.wide .idx-static { flex-wrap: wrap; }
.index-list.wide .s { flex: 1 0 100%; margin-left: 0; margin-top: 4px; }

.index-list a {
  display: flex; align-items: baseline; gap: 12px;
  background: var(--surface); padding: 18px 20px; min-height: 44px;
  text-decoration: none; color: var(--ink);
}
.index-list a:hover { background: var(--surface-2); }
.index-list .n {
  font-size: 12px; color: var(--primary); font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.index-list .t { font-family: Fraunces, Georgia, serif; font-size: 20px; font-weight: 600; }
.index-list .s { margin-left: auto; font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .08em; }

/* Item del indice SIN enlace — 30 ago, al crecer /tools de 2 a 12.
   El indicador existe pero todavia no tiene pagina que leer, asi que no se
   pinta un <a> muerto: misma caja que `.index-list a` para que la rejilla no se
   descuadre, pero sin hover y con el titulo apagado. Si parece un enlace y no
   lo es, el visitante hace clic igual y no pasa nada, que es peor que verlo
   claramente inerte. */
.index-list .idx-static {
  display: flex; align-items: baseline; gap: 12px;
  background: var(--surface); padding: 18px 20px; min-height: 44px;
  color: var(--body);
}
.index-list .idx-static .t { color: var(--body); }

/* ---------- product block ---------- */
.tool { padding: 76px 0; border-bottom: 1px solid var(--line); scroll-margin-top: 80px; }
.tool-meta {
  display: flex; flex-wrap: wrap; gap: 10px 18px; margin-bottom: 18px;
  font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--faint);
}
.tool-meta .code { color: var(--primary); font-weight: 700; }
.tool h2 {
  font-family: Fraunces, Georgia, serif; font-weight: 600;
  font-size: clamp(32px, 4.6vw, 50px); line-height: 1.05;
  letter-spacing: -.01em; margin: 0 0 22px;
}
/* 🔴 SUBTÍTULO DENTRO DE UNA SECCIÓN — 8 sep, ficha 76.
   Hasta hoy no existía: un `<h3>` suelto dentro de `.tool` salía con **el valor
   por defecto del navegador**, 18,72px de Inter en negrita. Medido al estrenar
   «What it needs loaded» en `/tools/mgi-hud-x`, y desentonaba con un h2 de 50px
   de Fraunces justo encima.

   ⚠️ NO SE INVENTA UNA ESCALA: `clamp(21px, 2.4vw, 26px)` en Fraunces 600 es
   exactamente el peldaño que el sitio ya usa para este nivel — el de
   `.steps h3` y el de `.prose h2`. Un tamaño nuevo habría añadido un cuarto
   peldaño a una escala que ya tenía tres.

   🔴 Y VA COMO `>` HIJO DIRECTO, NO COMO `.tool h3`. Dentro de `.tool` viven
   también los rótulos de `.refuse` y `.disclose`, que son de 12px en versalitas.
   `.tool h3` es 0-1-1, lo mismo que `.refuse h3`, y como esta regla va ANTES en
   la hoja... no: iría después si se pusiera junto a `.steps h3`, y entonces
   ganaría ella y los dos rótulos se volverían titulares de 26px.
   Con `>` el problema no existe por especificidad sino por ALCANCE: esos rótulos
   cuelgan de un `div` intermedio y este selector no los ve nunca, se ponga donde
   se ponga en la hoja. Es la salida robusta, no la que depende del orden. */
.tool > .wrap > h3 {
  font-family: Fraunces, Georgia, serif; font-weight: 600;
  font-size: clamp(21px, 2.4vw, 26px); line-height: 1.2;
  margin: 34px 0 12px;
}
.problem {
  font-family: Fraunces, Georgia, serif; font-size: clamp(21px, 2.6vw, 28px);
  line-height: 1.3; color: var(--ink); max-width: 24ch;
  margin: 0 0 20px; padding-left: 18px; border-left: 3px solid var(--primary);
}
.tool p { max-width: var(--measure); color: var(--body); margin: 0 0 18px; }

.spec {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1px; background: var(--line); border: 1px solid var(--line);
  margin: 30px 0;
}
.spec div { background: var(--surface); padding: 15px 18px; }
.spec dt {
  font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--faint); font-weight: 700; margin: 0 0 6px;
}
.spec dd { margin: 0; font-size: 14.5px; color: var(--ink); }

/* ---------- figuras de producto — 7 sep, tarea 6 ----------
   Para las capturas del indicador en la pagina del producto. Tres piezas:
   `.figuras.par` la comparacion antes/despues, `.figura.panel` el recorte del
   HUD a tamano natural, y `.media` (mas abajo) para el video.

   ⚠️ EL RECORTE VA A TAMANO NATURAL A PROPOSITO. La captura completa mide
   1920 y la columna la muestra a 1072: el texto del panel cae de ~10px a ~6 y
   deja de leerse — por debajo del suelo del propio sitio. Por eso la pieza que
   tiene que LEERSE es un recorte de 900px que se muestra 1:1. La comparacion
   par si funciona pequena: ahi el mensaje es la densidad, no el texto. */
.figuras { display: grid; gap: 20px; margin: 30px 0; }
@media (min-width: 720px) { .figuras.par { grid-template-columns: 1fr 1fr; } }
.figuras figure, .figura { margin: 0; }
.figura { margin: 30px 0; }
.figuras img, .figura img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line); background: #000;
}
.figura.panel .panel-scroll { max-width: 900px; margin: 0 auto; }
.figura.panel img { max-width: 900px; margin: 0 auto; }
/* Por debajo de 900 la imagen no encoge: se desplaza de lado dentro de su caja.
   Encogerla dejaria el texto del panel en la mitad de su tamano, que es
   exactamente lo que este recorte existe para evitar. */
@media (max-width: 899px) {
  .figura.panel .panel-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .figura.panel img { width: 900px; max-width: none; }
}
.figuras figcaption, .figura figcaption {
  margin-top: 10px; font-size: 13.5px; line-height: 1.55; color: var(--muted);
}
.figura.panel figcaption { max-width: 900px; margin-left: auto; margin-right: auto; }

/* media slot — replace with real video or image */
.media {
  border: 1px solid var(--line); background: var(--surface);
  aspect-ratio: 16 / 9; display: grid; place-items: center;
  margin: 30px 0; padding: 24px; text-align: center;
}
.media p { color: var(--faint); font-size: 13.5px; margin: 0; max-width: 42ch; }
.media video, .media img { width: 100%; height: 100%; object-fit: cover; }
/* Con video de verdad dentro, el relleno del hueco vacio sobra. Y el pie va
   FUERA del marco, no encima del video: `.media` es una rejilla centrada y
   dentro de ella el texto se montaria sobre la imagen. */
.media.mod-video { padding: 0; display: block; border: 0; aspect-ratio: auto; }
.media.mod-video video {
  display: block; width: 100%; height: auto; aspect-ratio: 16 / 9;
  border: 1px solid var(--line); background: #000;
}
.media.mod-video figcaption {
  margin-top: 10px; font-size: 13.5px; line-height: 1.55; color: var(--muted);
}

/* 🔴 `.disclose` COMPARTE EL MARCO DE `.refuse` Y NO LO COPIA — 8 sep.
   Las dos son un bloque con raya arriba y un rótulo en versalitas dentro de la
   sección «Limits», pero **no son lo mismo y por eso no es una sola clase**:
   `.refuse` es la lista de lo que la herramienta NO HACE (rejilla de items con
   guion), `.disclose` es prosa explicando CÓMO se calcula algo — el aviso de
   value area / POC, ficha 76.

   ⚠️ Se agrupan los selectores en vez de duplicar las declaraciones: así el
   marco tiene UNA definición. Si mañana la raya cambia, cambia en las dos, que
   es lo correcto — son hermanas visuales.
   ⚠️ Y `.disclose` NO hereda la rejilla de `.refuse ul`: sus párrafos y su `dl`
   se estilan solos. Meterlo dentro de `.refuse` habría traído esa rejilla.
   ⚠️ Nombre comprobado en las DOS hojas antes de estrenarlo (0 y 0), que es la
   lección de la colisión de `.path`. */
/* `.platform-block` se suma a estos selectores en vez de copiar sus valores: es el
   mismo componente —titulillo en versales y lista con guion— usado en /platform
   para enumerar lo que trae la descarga gratuita. 22 sep 2026. */
.refuse, .disclose, .platform-block { border-top: 1px solid var(--rule); padding-top: 24px; margin-top: 30px; }
.refuse h3, .disclose h3, .platform-block h3 {
  font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--faint); font-weight: 700; margin: 0 0 14px;
}
/* La prosa del aviso va al ancho de lectura del resto de la página, no al ancho
   del contenedor: es texto para leer seguido, no una ficha de datos. */
.disclose p { max-width: var(--measure); }
.refuse ul, .platform-block ul {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px 26px;
}
.refuse li, .platform-block li { color: var(--muted); font-size: 14.5px; padding-left: 22px; position: relative; }
.refuse li::before, .platform-block li::before {
  content: "—"; position: absolute; left: 0; color: var(--primary);
}

/* ---------- /platform · logos y captura de la plataforma ----------
   ⚠️ EL DE KINETICK VA SOBRE PANEL CLARO Y EL DE NINJATRADER NO: el primero es gris
      rgb(72,96,96) y sobre el fondo del sitio da ~2:1; el segundo es naranja puro y
      se lee solo. Retocar un logo suyo estaria prohibido; ponerle fondo, no.
   ⚠️ El relleno del panel no baja de 18px por los lados: es el aire libre que piden
      sus guias de marca alrededor del logotipo. */
/* El parrafo que sigue al bloque quedaba PEGADO a la lista: medido, 0px. `.refuse`
   y `.disclose` no lo notan porque siempre cierran su seccion. */
.platform-block { margin-bottom: 30px; }
/* 🔴 EL 20 DE ABAJO ES UNA EXIGENCIA DE SU MEDIA KIT, NO UNA ELECCION DE DISENO.
   «All approved NinjaTrader and Kinetick logos require a minimum of .25" or 18px of
   space on all sides». Aqui habia un 6, y medido en el DOM el hueco real bajo el logo
   eran 6px: un tercio de lo exigido, y **asi estaba en vivo en `/platform` desde el
   22 sep**, que es justo la pagina que se construyo para cumplir ese kit.
   ⚠️ Se caza midiendo el hueco entre el logo y el elemento siguiente, no leyendo el
   margen: los margenes colapsan y el numero de la regla no es el de la pantalla.
   ⚠️ Si se vuelve a tocar, el minimo son 18. Se deja 20 para tener margen. */
.platform-logo { margin: 26px 0 20px; }
.platform-logo img { display: block; width: auto; height: 26px; }
.platform-panel {
  display: inline-flex; align-items: center; justify-content: center;
  background: #E4E4E0; border-radius: 8px; padding: 14px 18px;
}
.platform-shot { margin: 30px 0 0; }
.platform-shot img { display: block; width: 100%; max-width: 420px; height: auto; }

.btn {
  display: inline-flex; align-items: center; min-height: 46px;
  padding: 0 22px; margin-top: 8px;
  background: var(--primary); color: var(--on-primary);
  font-weight: 600; font-size: 15px; text-decoration: none; border-radius: 2px;
}
.btn:hover { filter: brightness(1.08); }
.btn.ghost { background: transparent; color: var(--ink); border: 1px solid var(--border-ctl); }
.btn.ghost:hover { border-color: var(--primary); color: var(--primary); filter: none; }

.status {
  display: inline-block; font-size: 12px; letter-spacing: .1em; text-transform: uppercase;
  font-weight: 700; padding: 4px 9px; border: 1px solid currentColor; border-radius: 2px;
}
.status.live { color: var(--primary); }
.status.dev  { color: var(--faint); }

/* ---------- numbered steps (setup, how-we-build) ---------- */
.steps { list-style: none; margin: 0; padding: 0; }
.steps > li {
  display: grid; grid-template-columns: 62px 1fr; gap: 0 24px;
  padding: 32px 0; border-bottom: 1px solid var(--line);
}
.steps .num {
  font-family: Fraunces, Georgia, serif; font-weight: 600;
  font-size: 34px; line-height: 1; color: var(--primary);
  font-variant-numeric: tabular-nums;
}
.steps h3 {
  font-family: Fraunces, Georgia, serif; font-weight: 600;
  font-size: clamp(21px, 2.4vw, 26px); line-height: 1.2; margin: 0 0 12px;
}
.steps p { max-width: var(--measure); color: var(--body); margin: 0 0 12px; }
.steps p:last-child { margin-bottom: 0; }

kbd, .path {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px; color: var(--ink);
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 2px; padding: 2px 7px; white-space: nowrap;
}

/* ---------- pending marker — remove once the real content lands ---------- */
/* ---------- el precio de /store ----------
   Unico sitio del sitio donde se publica un importe. Se le da el cuerpo de un
   `h2` —misma familia y misma escala fluida— porque es lo que el visitante viene
   a buscar y no puede quedar como un parrafo mas.

   ⚠️ El importe va en `--primary`, que da 12,2:1 sobre el fondo. NO se usa el
      dorado para el resto de la frase: en este sitio el dorado significa "esto
      importa", y si se pinta la frase entera deja de significar nada.

   ⚠️ NO lleva tachado, ni "antes/ahora", ni cuenta atras. La §7 del brief
      prohibe la urgencia comercial, y sigue prohibiendola ahora que se vende. */
.price {
  font-family: Fraunces, Georgia, serif; font-weight: 600;
  font-size: clamp(21px, 2.4vw, 27px); line-height: 1.2;
  color: var(--body); margin: 0 0 10px;
}
/* ⚠️ DOS CLASES, NO UNA, Y NO ES ADORNO. `.prose strong` ya pinta los `strong`
      de `--ink` y esta MAS ABAJO en este archivo. Con `.price strong` a secas
      empatan en especificidad —una clase y un elemento cada una— y gana la
      ultima del documento: el importe salia gris en vez de dorado.
      Medido con `getComputedStyle`, no visto de refilon. Es la misma trampa que
      DESIGN.md documenta para `webflow.css`, aqui en la hoja propia. */
.prose .price strong { color: var(--primary); font-weight: 600; }

.pending {
  border: 1px dashed var(--border-ctl); background: var(--surface);
  padding: 14px 16px; margin: 14px 0; max-width: var(--measure);
}
.pending::before {
  content: "Pending"; display: block;
  font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--primary); font-weight: 700; margin-bottom: 7px;
}
.pending p { margin: 0; color: var(--muted); font-size: 14.5px; }

/* ---------- FAQ / disclosure list ---------- */
.qa { border-top: 1px solid var(--line); }
.qa details { border-bottom: 1px solid var(--line); }
.qa summary {
  cursor: pointer; list-style: none; padding: 22px 0;
  font-family: Fraunces, Georgia, serif; font-size: 20px; font-weight: 600;
  display: flex; gap: 16px; align-items: baseline; min-height: 44px;
}
.qa summary::-webkit-details-marker { display: none; }
.qa summary::after {
  content: "+"; margin-left: auto; color: var(--primary); font-family: Inter, sans-serif;
}
.qa details[open] summary::after { content: "\2212"; }
.qa details p { max-width: var(--measure); color: var(--body); margin: 0 0 22px; }
/* LAS FICHAS DE REFERENCIA — 8 sep, ficha 76. `/tools/mgi-hud-x` publica cada
   referencia con cuatro respuestas, y cada una empieza por su rótulo en negrita.
   ⚠️ El rótulo NECESITA su regla: fuera de `.prose` un `<strong>` solo es negrita
   y hereda `--body`, así que el rótulo pesaba lo mismo que el texto y la ficha se
   leía como un párrafo corrido. `--ink` lo separa sin añadir tamaño ni color. */
.qa details strong { color: var(--ink); font-weight: 600; }

/* 🔴 LA CUARTA RESPUESTA —«qué NO te dice»— LLEVA FILO PROPIO, Y NO ES ADORNO.
   Es la que no publica nadie y la que impide que alguien lea en un nivel un
   significado que nunca tuvo; el chat del indicador lo dijo de una en concreto
   (las proyecciones de balance inicial): «si una referencia necesita que se le
   pongan los límites por escrito, es esta».
   Un filo la separa de las tres descriptivas sin gritar: mismo tamaño, mismo
   color de texto, solo una raya y un poco de aire a la izquierda.
   ⚠️ Nombre comprobado en las DOS hojas antes de estrenarlo (0 y 0).
   ⚠️ Y NO se reutiliza `.art-libro`, que tiene el mismo filo pero significa otra
   cosa —una lectura recomendada en un artículo—. Compartir el aspecto no es
   compartir el significado: eso es lo que convierte una hoja en un campo de
   minas dentro de seis meses. */
.qa details p.ref-limit {
  border-left: 2px solid var(--rule);
  padding-left: 14px;
  margin-left: 1px;
}

/* ---------- FAQ en DOS COLUMNAS + buscador — 27 ago ----------
   `.qa` (la lista vertical de arriba) se mantiene para paginas con pocas
   preguntas. Este bloque es el de la FAQ larga: con 18 preguntas una sola
   columna obliga a un scroll largo para ver que hay, y el objetivo de una FAQ
   es que se ESCANEE, no que se lea entera.
   Lo pinta `partials/faq-items.php`, que es la fuente unica de las preguntas. */
.faq-search { margin: 0 0 30px; }
/* Etiqueta solo para lectores de pantalla: el `placeholder` no es una etiqueta
   accesible — desaparece al escribir y algunos lectores no lo anuncian. */
.faq-search-label {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.faq-search input {
  width: 100%; max-width: 640px; box-sizing: border-box;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--border-ctl); border-radius: 8px;
  padding: 13px 15px; font-family: inherit; font-size: 15px;
}
.faq-search input::placeholder { color: var(--faint); }
.faq-search input:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.faq-search-tip { margin: 10px 0 0; font-size: 13px; color: var(--faint); }
.faq-search-tip em { color: var(--primary); font-style: normal; }
.faq-count { margin: 6px 0 0; font-size: 12px; color: var(--faint); }

.faq-group { padding: 26px 0 0; }
.faq-group[hidden] { display: none; }

/* `align-items: start` es imprescindible: sin el, las dos tarjetas de una fila
   estiran a la altura de la mas alta y al desplegar una se abre un hueco
   enorme al lado. `minmax(0,1fr)` y no `1fr` para que una pregunta larga no
   ensanche su columna y descuadre la rejilla. */
.faq-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px; align-items: start;
}
.faq-grid details {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; padding: 0 18px;
}
.faq-grid details[open] { background: var(--surface-2); }
.faq-grid summary {
  cursor: pointer; list-style: none; padding: 16px 0;
  font-family: Fraunces, Georgia, serif; font-size: 17px; font-weight: 600;
  line-height: 1.35; color: var(--ink);
  display: flex; gap: 14px; align-items: flex-start;
}
.faq-grid summary::-webkit-details-marker { display: none; }
.faq-grid summary::after {
  content: "+"; margin-left: auto; color: var(--primary);
  font-family: Inter, sans-serif; font-weight: 400; line-height: 1.35;
}
.faq-grid details[open] summary::after { content: "\2212"; }
.faq-grid summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.faq-grid .faq-a { padding: 0 0 4px; }
.faq-grid .faq-a p { color: var(--body); margin: 0 0 14px; font-size: 15px; }
.faq-grid .faq-a .pending { margin: 0 0 14px; max-width: none; }

.faq-empty { margin: 26px 0 0; color: var(--muted); }
.faq-empty[hidden] { display: none; }

/* Una sola columna en cuanto la celda baja de ~300px utiles: a dos columnas
   estrechas las preguntas se parten en cuatro lineas y se lee peor que en
   vertical. */
@media (max-width: 760px) {
  .faq-grid { grid-template-columns: 1fr; }
}

/* ---------- closing ---------- */
.closing { padding: 72px 0; }
.closing h2 {
  font-family: Fraunces, Georgia, serif; font-weight: 600;
  font-size: clamp(26px, 3.4vw, 38px); line-height: 1.1; margin: 0 0 18px;
  max-width: 20ch;
}
.closing p { max-width: var(--measure); color: var(--body); margin: 0 0 24px; }
.actions { display: flex; flex-wrap: wrap; gap: 12px; }

/* ---------- footer ---------- */
.site-footer {
  border-top: 1px solid var(--line); padding: 46px 0 60px;
  font-size: 14px; color: var(--muted);
}
/* 🔴 EL `190px` ERA `190px` Y HACIA EL PIE INSOPORTABLE EN EL MOVIL.
   Lo vio el dueno en telefono y tablet, 3 sep. Medido antes de tocar nada:

       375px (movil) : 1 columna  ->  pie de 1208px = vez y media la pantalla,
                                      y el 18% de TODO el documento
       768px (tablet): 3 columnas ->  pie de 811px, y en DOS filas: la cuarta
                                      categoria caia sola debajo

   La causa era aritmetica, no de diseño: con `minmax(190px, …)` y 30px de hueco,
   dos columnas piden 190+30+190 = 410px, y un movil de 375px solo deja 327px de
   contenido. Nunca cabian dos. Con 140px piden 310px y SI caben.

   ➡️ UN SOLO NUMERO ARREGLA LOS TRES TAMAÑOS, porque `auto-fit` recalcula solo:
       375px -> 2 columnas de 148px
       768px -> 4 columnas de 157px, en UNA fila
      1072px -> las 4 de siempre, a 260px

   ⚠️ NO SE HIZO DESPLEGABLE, y es una decision. Era la otra opcion sobre la mesa
      y esconde detras de un toque los enlaces LEGALES —Terms of Sale, Risk
      Disclosure, Privacy Policy—, que son justo los que un sitio que vende tiene
      que poner faciles de encontrar. Ademas exige JavaScript y ARIA para no
      romper el teclado y el lector de pantalla. Dos columnas no cuestan nada de
      eso y no esconden nada.

   ⚠️ NO SE TOCA `min-height: 34px` DE LOS ENLACES. Es el area tactil: bajarla
      haria el pie mas corto a costa de que se falle al pulsar. */
/* 🔴 7 sep: LAS COLUMNAS SE TOPAN EN 260px Y SE REPARTEN A LOS BORDES.
   Antes era `minmax(140px, 1fr)`, o sea columnas elásticas que se comían todo el
   ancho a partes iguales. Con CUATRO columnas eso daba 246px cada una y cuadraba.
   Al pasar los legales a fila y quedar TRES, cada track se fue a **337px** para
   un contenido que no pasa de ~190, y el resultado medido a 1440 fue que la
   última columna terminaba en x=1025 mientras la fila de legales y el copyright
   llegaban hasta 1249: **224px de agujero en la esquina derecha**.

   Con el tope de 260 y `space-between`, las tres se colocan en 184 · 590 · 996 y
   la última cierra en **1256, que es exactamente donde cierra la fila de legales**.
   Todo el pie comparte los dos márgenes.

   ⚠️ EL 260 NO ES UN NÚMERO BONITO: es lo que necesita la descripción de
   Education, que va topada a `34ch` (~246px a 13px). Por debajo de eso la frase
   empieza a partirse en más líneas; por encima, la columna sobra. Si esa frase
   cambia de tamaño, este número se remide.

   ⚠️ `auto-fit` SE QUEDA, no se pone `repeat(3, …)`: colapsa los tracks vacíos, así
   que si algún día vuelve a haber cuatro columnas —o dos— esto sigue funcionando
   sin tocarlo.

   🔴 Y EL TOPE VA DENTRO DE UN `@media`, NO SUELTO — el primer intento lo puso
   suelto y ROMPIÓ EL MÓVIL. Un tope de 260px es un ancho FIJO para el reparto:
   cuando la pantalla no da para tres de 260 más sus huecos (840px de contenido),
   la rejilla no los encoge, los BAJA de línea. Medido con el tope suelto:

       768 →  2 filas,  pie de **755px**   (con 1fr era 1 fila)
       430 →  3 filas,  pie de **980px**
       375 →  3 filas,  pie de **980px**   (antes, con 4 columnas, eran 837)

   ⚠️ O sea: el arreglo de la esquina derecha del escritorio hacía el pie del móvil
   **143px más alto**, y el móvil es donde el dueño ya se quejó una vez de que el
   pie era insoportable de largo.

   ➡️ Por debajo del corte vuelve el `1fr` elástico de siempre, que es lo que hace
   falta ahí: columnas que encogen en vez de apilarse.

   🔴 Y EL CORTE SE PUSO EN 900 Y TAMBIÉN ESTABA MAL. Los tres tramos necesitan
   3×260 + 2×30 = **840px de contenido**, y a 900 el contenido mide **837**:
   faltaban **3 píxeles** y la rejilla partía en dos filas (pie de 668px en vez de
   462). Es literalmente la trampa que este proyecto acababa de anotar el mismo
   día — *«una holgura de 14px no es holgura, es el redondeo»*— mordiendo otra vez
   a 3px.
   ➡️ **960**: el contenido da 897 y sobran **57**. Entre 900 y 959 manda el `1fr`,
   que ahí reparte ~259px por columna — a ojo es lo mismo que el tope, así que el
   salto no se ve.
   Medido a 375, 430, 768, 899, 900, 959, 960, 991, 1440, 1920 y 2560. */
.footer-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 30px; margin-bottom: 34px;
}
@media (min-width: 960px) {
  .footer-grid {
    grid-template-columns: repeat(auto-fit, minmax(140px, 260px));
    justify-content: space-between;
  }
}
/* Tarea 31 — 6 sep: era `.site-footer h2`. Esos rotulos dejaron de ser
   titulares (ver `partials/footer.php`), asi que el estilo va por clase.
   Si vuelve a aparecer un h2 de verdad en el pie, NO heredara esto. */
.site-footer .footer-col-title {
  font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted); font-weight: 700; margin: 0 0 12px;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: 2px; }

/* Descripcion bajo un enlace del pie — 7 sep. Hoy solo la lleva Education, y
   ocupa el hueco que dejaron sus dos subenlaces (ver `partials/footer.php`).

   ⚠️ EL `margin-top` ES NEGATIVO A PROPOSITO Y NO ES UN AJUSTE FINO. Los enlaces
   del pie son `display:flex` con `min-height:34px` para tener area tactil: el
   texto queda centrado en esos 34px, asi que bajo la palabra «Education» sobran
   ~9px de caja vacia. Sin el -6px la descripcion parece suelta, de otro bloque.
   Si algun dia se cambia ese `min-height`, este numero se remide.

   ⚠️ `max-width` EN `ch` Y NO EN px: la columna del pie va de 140px (rejilla
   auto-fit) a ~330px a 1440. En px habria que elegir un ancho para uno de los
   dos. En `ch` el limite lo pone el texto y la rejilla manda por debajo.

   ⚠️ COLOR EXPLICITO, NO HEREDADO. `.site-footer` ya es `--muted`, pero heredar
   deja esto atado a un token que sirve a otras cosas — es exactamente como el
   4 sep los 19 enlaces del pie se fueron a 4,12:1 sin que nadie lo midiera.

   🎨 EL COLOR VA SOLO EN EL GANCHO, Y ES UNA DECISION DEL DUENO ENTRE TRES
   VARIANTES PUESTAS UNA AL LADO DE OTRA en el pie de verdad, no en una maqueta:

       A · la frase entera en #069494   ->  5,38:1
       B · la frase entera en #08BDBD   ->  8,56:1
       C · «A growing library» en #08BDBD, el resto en gris   <- ELEGIDA

   ⚠️ POR QUE C ES LA BUENA, Y NO ES CUESTION DE GUSTO: la frase hace DOS trabajos
   distintos. Las tres primeras palabras venden —tienen que verse desde lejos— y
   las otras catorce hay que LEERLAS. El color sirve al primero y estorba al
   segundo: cualquier teal contrasta menos que el gris del pie. Separandolos,
   cada mitad usa el recurso que le toca.

   CONTRASTES, medidos en el navegador sobre `--bg` (#090909):

       #08BDBD  el gancho   8,56:1   (y #069494 daba 5,38 — se descarto)
       #8A8787  el resto    5,6:1

   ➡️ `#08BDBD` NO ES UN COLOR NUEVO: lo eligio el dueno el 31 ago (tarea 17) para
   los destellos de la CTA, y por esta misma razon — pidio 0,4000 de luminancia,
   se intento subiendo la alfa y no bastaba, porque **la alfa nunca supera al
   color**. #069494 mide 0,2336 y ese es su techo; #08BDBD da 0,4012.

   ⚠️ CON ESTO QUEDA DICHO EL CRITERIO DE LOS DOS TEALES, que llevaba desde agosto
   sin escribir: `#069494` es lo que hace de FONDO —el filo de la X, el halo del
   rotulo— y `#08BDBD` lo que tiene que NOTARSE —el destello, y este gancho—.
   No se unifican: mismo matiz, papeles distintos.

   ⚠️ COLOR EXPLICITO EN HEX, NO HEREDADO NI POR TOKEN. `.site-footer` ya vale
   `--muted`, pero heredar deja esto atado a un token que sirve a otras cosas: es
   exactamente como el 4 sep los 19 enlaces del pie se fueron a 4,12:1 sin que
   nadie lo midiera.

   ➡️ Y NO SE TOCA LA OPACIDAD DE NINGUNO DE LOS DOS. Si se quiere otra
   intensidad se cambia el TONO, nunca la alfa. */
.site-footer .footer-col-desc {
  margin: -6px 0 12px;
  max-width: 34ch;
  font-size: 13px;
  line-height: 1.45;
  color: #8A8787;
}
.site-footer .footer-col-hook { color: #08BDBD; }

/* Sublista: artículos que pertenecen a la sección de arriba, no hermanas suyas.
   La barra a la izquierda hace la relación explícita sin necesitar viñetas. */
.site-footer .sub {
  margin: 0 0 6px 2px;
  padding-left: 12px;
  border-left: 1px solid var(--line);
}
.site-footer .sub a {
  font-size: 13px;
  color: var(--muted);
  min-height: 34px;   /* igual que el resto de enlaces del footer */
}
.site-footer .sub a:hover { color: var(--primary); }
/* ⚠️ NO PONER `var(--body)` AQUI. Lo llevaba, y el 4 sep `--body` paso de `#9D9D9D`
   a `#6B7280` para igualarlo a la pagina de referencia: **los 19 enlaces del pie se
   fueron de 7,34:1 a 4,12:1 de golpe** y nadie lo midio, porque el barrido de
   contraste de aquel cambio miro los colores dominantes de 3 paginas y no los
   enlaces. Lo vio el dueno y pidio devolverlos.
   Se fija el color aqui en vez de tocar `--body`, que sigue sirviendo al resto del
   sitio tal y como el lo eligio. `#9D9D9D` = 7,34:1 sobre `--bg`.
   De esto sale la casilla 9b de `ORQUESTADOR.md`: al tocar un TOKEN de color, el
   barrido A/B es del SITIO entero, no de la zona tocada. */
.site-footer a {
  color: #9D9D9D; text-decoration: none;
  display: flex; align-items: center; min-height: 34px;
}
.site-footer a:hover { color: var(--primary); }
/* 🟢 `--faint` YA VALE PARA TEXTO — 4 sep, tarea 52.
   ⚠️ EL AVISO DE ABAJO ESTUVO EN PIE DESDE EL 30 AGO Y NADIE LO APLICO: el token
   siguio usandose para texto durante cinco dias, en «24 questions» (×8 en
   `/contact/`) y en `/docs/` (×14). **Un aviso que no se aplica no protege nada.**

   El aviso original, del 30 ago:
     «`#6E756E` sobre `--bg` da 4,20:1, por debajo del 4,5:1 de un texto de 12,5px.
      Aqui vive el aviso de riesgo, que es el texto que mas obligados estamos a que
      se lea. El token se queda para bordes y decoracion, pero no para texto.»

   ➡️ En vez de perseguir cada uso, se sube el token: **#6E756E -> #7C837C**, que da
   **5,12:1**. Se aclaran los tres canales por igual, asi que **conserva su tinte**
   —sigue siendo el gris verdoso de la escala— y solo gana luz. La jerarquia se
   mantiene: `--muted` 5,59 por encima, `--faint` 5,12 por debajo.

   🔵 Decision del dueno el 4 sep: de la tarea 52 se hace SOLO esto. Las dos familias
   de gris —`--body` azulado frente al resto neutro/calido— siguen conviviendo a
   proposito; unificarlas queda para cuando el lo decida. */
/* LA FILA DE LOS 7 LEGALES — 7 sep. Antes era la cuarta COLUMNA del pie y la más
   larga de las cuatro; ahora es una fila, como en la home. Lo pidió el dueño:
   «este footer tiene una columna grande de legales… así el footer tendrá más
   espacio». El porqué completo, en `partials/footer.php`.

   ⚠️ ESTA FILA ES LA QUE PONE LA RAYA, Y ANTES LA PONÍA `.legal-line`. Van
   juntas: si algún día se quita la fila, la raya tiene que volver a la otra o el
   pie se queda sin su separador. Por eso `.legal-line` pierde aquí su
   `border-top` y su `padding-top`.

   ⚠️ `gap` de 26px en horizontal y NO menos: los enlaces heredan de
   `.site-footer a` un `min-height: 34px` (el área táctil) pero no un ancho, así
   que en móvil dos de ellos quedarían a un dedo de distancia. 26px los separa.

   ⚠️ Envuelve sola. Ya no puede «descuadrar la fila» del pie como avisaba la
   tarea 19 — una columna que crece empuja a sus vecinas; una fila que no cabe,
   baja de línea. */
/* 22 sep: los legales pasan a vivir DENTRO de `.legal-line`, en la misma fila que el
   copyright, como en la home. La linea separadora y el respiro suben de `.legal-row`
   a `.legal-line`, que ahora es quien abre el bloque legal. */
.legal-row {
  display: flex; flex-wrap: wrap; gap: 0 26px;
  font-size: 12.5px;
}
.legal-line {
  border-top: 1px solid var(--line); padding-top: 20px; margin-bottom: 18px;
  display: flex; flex-wrap: wrap; gap: 8px 26px; justify-content: space-between;
  align-items: baseline;
  color: var(--muted); font-size: 12.5px;
}
/* 22 sep: sin esto, de 768 a ~1390 el bloque de enlaces NO cabe al lado del copyright
   —medido a 1024: 255 + 726 = 981px en 961 disponibles— y bajaba ENTERO a otra fila.
   Con `flex:1 1 auto` y `min-width:0` el grupo se queda a la derecha y son sus propios
   enlaces los que pasan de linea, que es como se comporta la home.
   ⚠️ Solo desde 768: por debajo, apilados uno sobre otro se leen mejor. */
@media (min-width: 768px) {
  /* ⚠️ `flex-basis: 0` Y NO `auto`, Y AQUI ESTABA EL FALLO DEL PRIMER INTENTO: con
     `auto`, el navegador decide si cabe mirando el tamano NATURAL del bloque (726px a
     1024), asi que bajaba entero de linea aunque luego pudiera encogerse. Con base 0
     ocupa el hueco que quede y son sus enlaces los que pasan de linea. */
  .legal-line .legal-row { flex: 1 1 0; min-width: 0; justify-content: flex-end; }
}
.risk { max-width: 62ch; color: var(--muted); }
/* Descargo de marca de NinjaTrader (14 sep): va en su propia linea, DEBAJO de
   `.legal-line` y no dentro, porque esa fila reparte dos cosas con
   `space-between` y un tercer parrafo le quitaba el sitio al copyright.
   Hereda el tamano y el color de `.risk`, que es lo que piden las guias. */
.risk.trademark { margin: 14px 0 0; }

/* LOS TRES DESCARGOS LARGOS, IGUALES QUE EN LA HOME — 22 sep 2026.
   Lo vio el dueno comparando las dos capturas: en el molde salian a 543px de ancho,
   14px y #8A8787; en la home a todo el ancho, 12px y blanco al 62%. Tres diferencias,
   no una.
   ⚠️ El tope de 62 caracteres de `.risk` es para LEER, y es correcto en el aviso corto.
      Estos tres son texto legal que la home ya publica a ancho completo: manda la home,
      que es la pagina de referencia.
   ⚠️ 12px es el suelo del sitio y blanco al 62% da 7,76:1 sobre #090909 — por encima de
      lo que exigen sus guias y del minimo de accesibilidad. Medido, no estimado.
   El selector son los hermanos de `.legal-line`: exactamente los tres parrafos legales
   que van debajo, sin tocar el aviso corto que vive DENTRO de esa fila. */
.legal-line ~ .risk {
  max-width: none;
  font-size: 12px;
  color: rgba(255, 255, 255, .62);
}

/* ---------- social links ----------
   Los pinta `partials/social-links.php`, compartido con el footer de la home.
   Ojo: la home NO carga esta hoja (es el export de Webflow), asi que alli las
   mismas clases estan duplicadas en su <style> embebido. Si se cambia el aspecto,
   hay que tocar los dos sitios. */
.mak-social {
  display: flex; gap: 14px;
  margin: 0; padding: 0; list-style: none;
}
/* ⚠️ Se cualifica con el ancestro para ganar a `.prose a`, que pinta de dorado
   todos los enlaces del cuerpo y **esta declarada mas abajo en esta misma hoja**:
   con la misma especificidad ganaba ella y los cinco iconos salian dorados de
   entrada, sin dejar margen al hover. */
.contact-social a.mak-social-link,
.site-footer a.mak-social-link,
a.mak-social-link {
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;          /* target tactil completo */
  color: var(--muted);
  transition: color .25s ease;
}
.contact-social a.mak-social-link:hover,
.contact-social a.mak-social-link:focus-visible,
a.mak-social-link:hover,
a.mak-social-link:focus-visible { color: var(--primary); }
.contact-social { margin-top: 34px; }
.contact-social .mak-social { margin-left: -10px; }  /* alinea el icono, no su caja */

/* ---------- long-form prose (legal pages, about, education) ----------
   Legal text is read in sequence rather than scanned, so it gets a single
   narrow column and generous spacing between headings. --measure keeps the
   line length readable; a full-width legal page is unreadable. */
.prose { padding: 56px 0 80px; max-width: var(--measure); }
.prose h2 {
  font-family: Fraunces, Georgia, serif; font-weight: 600;
  font-size: clamp(21px, 2.4vw, 27px); line-height: 1.2;
  margin: 48px 0 14px;
}
.prose h3 {
  font-size: 17px; font-weight: 700; color: var(--ink);
  margin: 30px 0 10px;
}
.prose p,
.prose li { color: var(--body); }
.prose p { margin: 0 0 16px; }
.prose ul,
.prose ol { margin: 0 0 18px; padding-left: 22px; }
.prose li { margin-bottom: 8px; }
.prose strong { color: var(--ink); font-weight: 600; }
.prose a:not(.btn) { color: var(--primary); }   /* :not(.btn) — ver el suelo de enlaces, arriba */
.prose > :first-child { margin-top: 0; }

/* Tablas del cuerpo legal — hoy solo las usa /cookie-policy.
   ⚠️ `.prose` esta limitado a --measure (68ch) y una tabla de 4 columnas no cabe
   en movil. Por eso SIEMPRE va envuelta en `.table-wrap`: el scroll horizontal se
   queda dentro de la tabla y la pagina no se desplaza en bloque. */
/* ⚠️ Toda `.table-wrap` necesita ademas `tabindex="0" role="region" aria-label="..."`
   en el marcado, y `scope="col"` en sus `<th>`. El scroll horizontal que crea esta
   regla solo existe para raton y dedo: sin el `tabindex` un usuario de teclado no
   puede alcanzar las columnas que quedan fuera. Ver /cookie-policy. */
.table-wrap { overflow-x: auto; margin: 0 0 22px; }
.prose table {
  border-collapse: collapse; width: 100%; min-width: 520px;
  font-size: 14px; line-height: 1.5;
}
.prose th, .prose td {
  border: 1px solid var(--line); padding: 10px 12px;
  text-align: left; vertical-align: top;
}
.prose th {
  background: var(--surface); color: var(--ink);
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase; font-weight: 700;
}
.prose td { color: var(--body); }
.prose td code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px; color: var(--ink);
}

/* Bloque citado. Hoy solo lo usa el formulario de desistimiento de /terms-of-sale,
   que es un texto que el cliente copia: se separa del cuerpo para que se vea que
   es un modelo y no una clausula mas.
   Sin regla propia el navegador le mete `margin: 1em 40px`, que descuadra la
   sangria contra las listas de al lado. */
.prose blockquote {
  margin: 22px 0; padding: 18px 20px;
  border-left: 3px solid var(--rule); background: var(--surface);
}
.prose blockquote p { color: var(--muted); font-size: 14.5px; }
.prose blockquote p:last-child { margin-bottom: 0; }

/* Effective-date / revision line under a legal heading. */
.page-meta {
  font-size: 13px; letter-spacing: .04em; color: var(--muted);
  margin: 0 0 6px;
}

/* Callout with an accent rule — used for the "under legal review" warning. */
.notice {
  border-left: 3px solid var(--primary); background: var(--surface);
  padding: 16px 18px; margin: 26px 0;
}
.notice p { margin: 0; color: var(--muted); font-size: 14.5px; }

/* ---------- three-up card row (about) ---------- */
.cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 28px; margin: 0;
}
.cards .card { border-top: 2px solid var(--primary); padding-top: 16px; }
.cards h3 {
  font-family: Fraunces, Georgia, serif; font-weight: 600;
  font-size: 20px; line-height: 1.2; margin: 0 0 10px;
}
.cards p { color: var(--body); font-size: 14.5px; margin: 0; }

/* Section divider used to break a long content page into named parts. */
.band { border-top: 1px solid var(--line); padding: 52px 0; }
.band > .wrap > h2 {
  font-family: Fraunces, Georgia, serif; font-weight: 600;
  font-size: clamp(24px, 3vw, 34px); line-height: 1.1;
  margin: 0 0 18px; max-width: 24ch;
}

/* Tarea 31 — 6 sep. Un rotulo de banda que ES un h2 (para no saltarse el
   nivel) pero que NO debe parecerlo. La regla de arriba es 0-2-1 y le gana a
   `.index-label` (0-1-0), asi que hay que devolverle a mano lo que le quita.
   Comprobado: sin esto el rotulo salia en Fraunces a 34px. */
.band > .wrap > h2.index-label {
  font-family: inherit;
  font-weight: 700;
  font-size: 12px;
  line-height: normal;
  max-width: none;
  margin: 0 0 16px;
}
.band p { max-width: var(--measure); color: var(--body); margin: 0 0 16px; }

/* ---------- contact ---------- */
.contact-rows { border-top: 1px solid var(--line); margin: 34px 0 0; }
.contact-rows > div {
  border-bottom: 1px solid var(--line); padding: 22px 0;
}
.contact-rows h2 {
  font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--faint); font-weight: 700; margin: 0 0 8px;
}
.contact-rows p { margin: 0; color: var(--body); }
.contact-rows a { color: var(--primary); font-size: 18px; text-decoration: none; }
.contact-rows a:hover { text-decoration: underline; }

.form { max-width: 46ch; margin-top: 40px; }
.form label {
  display: block; font-size: 12px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint); font-weight: 700; margin: 0 0 8px;
}
.form input,
.form textarea,
.form select {
  width: 100%; background: var(--surface); color: var(--ink);
  border: 1px solid var(--border-ctl); border-radius: 2px;
  padding: 12px 14px; margin-bottom: 22px; font: inherit; min-height: 46px;
}
.form input:focus,
.form textarea:focus,
.form select:focus { border-color: var(--primary); outline: none; }
.form textarea { min-height: 140px; resize: vertical; }
.form button {
  min-height: 46px; padding: 0 22px; border: 0; border-radius: 2px;
  background: var(--primary); color: var(--on-primary);
  font: inherit; font-weight: 600; cursor: pointer;
}
.form button[disabled] {
  background: var(--surface-2); color: var(--faint);
  border: 1px solid var(--line); cursor: not-allowed;
}

/* Aqui vivio el estilo del campo de adjunto (`input[type=file]`, `.field-opt`,
   `.field-note`). Salio el 27 ago junto con el campo: el dueno decidio no aceptar
   subidas de archivos. Se retira tambien el CSS para no dejar reglas que no pintan
   nada y que dentro de un mes nadie sepa si estan en uso. */

/* ---------- selector de tema del formulario de contacto — 27 ago ----------
   El <select> nativo sobre fondo oscuro hereda la flecha del sistema, que en
   Windows se pinta casi negra y desaparece contra --surface. `appearance: none`
   la quita y se dibuja una propia en dorado. */
.form select {
  appearance: none; -webkit-appearance: none;
  padding-right: 42px; cursor: pointer;
  background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23FBC30F' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 15px center;
}
/* La opcion de arranque no es una respuesta: se ve gris, como un placeholder, y
   `required` la rechaza porque su value esta vacio. */
.form select:invalid { color: var(--faint); }
/* Las opciones desplegadas las pinta el sistema: sin esto salen sobre blanco. */
.form select option { background: var(--surface); color: var(--ink); }

/* Estado inactivo comun a los cuatro campos. Sin esto el <select> nuevo se veia
   igual de "vivo" que uno operativo, y el resto del formulario tampoco decia por
   si mismo que esta apagado: solo lo decia el aviso de arriba. */
/* ⚠️ `background-color`, NUNCA el atajo `background`. Con el atajo se resetea
   tambien `background-image` y la flecha dorada del <select> desaparecia — el
   campo quedaba como una caja de texto vacia, sin pista de que es desplegable. */
.form input[disabled],
.form textarea[disabled],
.form select[disabled] {
  background-color: var(--surface-2); color: var(--faint);
  border-color: var(--line); cursor: not-allowed;
  opacity: 1;                      /* Safari/iOS lo atenua ademas por su cuenta */
}

/* ---------- errores del formulario — 3 sep, al encender la tarea 1 ----------
   Hasta hoy el formulario no podia fallar porque no enviaba nada. Ahora valida
   en servidor y hay que poder decir QUE campo esta mal.

   ⚠️ EL COLOR NO ES LA UNICA SENIAL, y eso no es un detalle de purista: entre un
      8 y un 10% de los hombres no distingue rojo de verde, y el publico de este
      sitio es abrumadoramente masculino. Van tres seniales a la vez — texto
      escrito, borde marcado y `aria-invalid` para el lector de pantalla — y
      ninguna depende de ver el color.
   ⚠️ El mensaje va DEBAJO del campo y enlazado con `aria-describedby`. Encima
      queda separado de su campo cuando el navegador hace scroll al primer
      error. */
/* 🔴 `.form .field-error` Y NO `.field-error` A SECAS. Se escribio a secas y el
      error SALIA GRIS: `.prose p, .prose li` es de 2 componentes (0-1-1) y una
      clase suelta de 1 (0-1-0), asi que ganaba el gris del cuerpo de texto. El
      borde rojo si aparecia —esa regla ya tenia 2— y por eso el fallo era de los
      que se cuelan: el campo se marcaba, solo que el mensaje no se veia rojo.
      Medido en el DOM pintado, no leyendo la hoja.

   ⚠️ ES LA TERCERA VEZ QUE MUERDE ESTA TRAMPA en este archivo: paso con
      `.price strong` contra `.prose strong` el 2 sep, y antes con los selectores
      por nodo de `webflow.css`. La leccion no es «contar clases mejor»: es que
      **una regla que pinta color dentro de `.prose` necesita 2 componentes como
      minimo**, y no se deja al orden de aparicion, que se rompe al mover un
      bloque de sitio sin darse cuenta. */
.form .field-error {
  margin: -14px 0 22px;            /* Se come el hueco del campo de arriba: el   */
  font-size: 13.5px;               /* error tiene que pegarse a SU campo, no     */
  color: var(--danger);            /* flotar a medio camino del siguiente.       */
}
.form [aria-invalid="true"] {
  border-color: var(--danger);
}

/* Aviso de nivel formulario: envio caducado, limite de la IP, correo que no
   salio. No usa `.pending`, que significa «esto aun no existe» — aqui existe y
   ha fallado, y son dos cosas distintas que no deben verse igual. */
.form-alert {
  border: 1px solid var(--danger);
  border-left-width: 3px;
  background: var(--surface);
  padding: 16px 18px; border-radius: 2px; margin: 32px 0 0;
}
/* Mismo motivo que arriba: `.form-alert p` EMPATA a 0-1-1 con `.prose p` y el
   desempate seria el orden en el archivo — es decir, funcionaria hoy y se
   rompería el dia que alguien mueva un bloque. Con `.prose` delante son 0-2-1 y
   gana siempre. */
.prose .form-alert p { margin: 0; color: var(--ink); font-size: 14.5px; }

@media (max-width: 640px) {
  .page-head { padding: 44px 0 30px; }
  .tool { padding: 52px 0; }
  .site-header .wrap { min-height: 60px; gap: 12px; }
  .site-nav { margin-left: 0; width: 100%; }
  .prose { padding: 36px 0 56px; }
  .band { padding: 38px 0; }
}

/* ---------- ARTÍCULOS DE EDUCACIÓN — 7 sep ----------
   El molde de los 59 artículos del área de educación. Se apoya en `.prose`, que
   ya trae el ancho de lectura de 68ch y la tipografía; aquí solo van las piezas
   que `.prose` no tiene.

   🔴 CUATRO TIPOS DE PIEZA VISUAL, Y NO ES CAPRICHO. Lo dijo el dueño: «este
   sector, leer sin ver no funciona».
     · `.art-diagrama`  — SVG dibujado en el propio código. Para lo abstracto.
                          Pesa 2 KB, no se pixela, y **el navegador traduce sus
                          etiquetas**, que una imagen no.
     · `.art-hueco`     — captura real de la plataforma. La única que no puedo
                          hacer yo, y por eso va marcada mientras falte.
     · datos y comparaciones — NUNCA dentro de una imagen: un texto en imagen no
                          se traduce y no se corrige. Se usa lo que ya existe:
                          `.prose table` + `.table-wrap` para datos tabulares, y
                          `.spec` para comparar dos casos en prosa. Ver la nota de
                          más abajo: aquí no se crea una tabla nueva.
     · `.art-recorte`   — recorte a tamaño natural, con desplazamiento lateral en
                          móvil. Mismo criterio que el panel de MGI HUD X: si lo
                          que importa es el texto pequeño, encogerlo lo mata.

   ⚠️ LA MARCA DE AGUA VA DENTRO DEL SVG, no en el CSS. Así viaja con el archivo
   si alguien se lo lleva, que es justo lo que pidió el dueño. */
.art-fig { margin: 32px 0; }
.art-fig figcaption {
  margin-top: 10px; font-size: 13.5px; line-height: 1.55; color: var(--faint);
}
.art-fig figcaption b { color: var(--body); font-weight: 600; }

.art-diagrama { border: 1px solid var(--line); background: var(--surface); padding: 24px 18px; }
.art-diagrama svg { display: block; width: 100%; height: auto; margin: 0 auto; }

/* 🔴 UN SVG QUE SE ENCOGE SE LLEVA SU TIPOGRAFIA CON EL — 8 sep, medido.
   CAUSA: el `font-size` de dentro de un SVG esta en UNIDADES DEL viewBox, no en
   px de pantalla. Con `width: 100%` el navegador escala el lienzo entero, asi que
   el tamano real es `declarado x (ancho del contenedor / ancho del viewBox)`.
   Los diagramas estan dibujados a 640 de ancho, que es exactamente lo que mide su
   caja en escritorio, y ahi salen a escala 1,003.

   MEDIDO EN EL DOM PINTADO, no leido del CSS:
     · a 1402 de viewport -> caja 642, escala 1,003, altura de x = 7,02 px  ✅
     · a  430 de viewport -> caja 344, escala 0,537, altura de x = 3,76 px  ❌
   El suelo de la casilla 3 de la lista de verificacion son 6 px. A 430 se quedaba
   al 63% del minimo: no es «pequeno», es ilegible.
   ⚠️ Y NO ES SOLO DE LOS 13 NUEVOS: el articulo ya publicado tenia lo mismo
   —altura de x 5,30 px en su primer diagrama—, tres dias en vivo sin que ningun
   barrido lo viera, porque el desborde daba 0 y el contraste daba verde.

   ARREGLO: por debajo de ~726 de viewport la caja ya no da los 640, asi que en vez
   de encoger el dibujo se le deja su tamano natural y se desplaza de lado. Es la
   MISMA convencion que el sitio ya usa para las tablas (`.table-wrap`), y la que
   pide el comentario de `.art-recorte`: si lo que importa es el texto pequeno,
   encogerlo lo mata.
   ⚠️ SE ESCALA HACIA ABAJO PERO NUNCA HACIA ARRIBA. `--vb` lleva el ancho del
   viewBox de ese diagrama; sin declararlo son 640, que es lo que miden los 14 de
   la etapa 1. El primer diagrama de «How a price is made» mide 454 y lo declara,
   porque con 640 se agrandaria un 41% y saldria mas grande en el movil que en el
   escritorio.
   MEDIDO despues: a 430 la escala sube a 1,0 y la altura de x a 6,5 px. ✅ */
@media (max-width: 760px) {
  .art-diagrama { overflow-x: auto; }
  .art-diagrama svg { min-width: calc(var(--vb, 640) * 1px); }
}

.art-hueco {
  border: 1px dashed var(--rule); background: var(--surface);
  aspect-ratio: 16 / 9; display: grid; place-items: center; text-align: center; padding: 24px;
}
.art-hueco p { margin: 0; color: var(--faint); font-size: 13.5px; max-width: 46ch; }
.art-hueco p b { display: block; color: var(--body); font-size: 14px; margin-bottom: 6px; }

/* ⚠️ AQUÍ NO HAY ESTILO DE TABLA PROPIO, Y ES A PROPÓSITO — 7 sep.
   El primer artículo llevaba una `.art-tabla` nueva y fue un error de dos maneras:
   duplicaba una convención que el sitio YA tiene —`.prose table` con su
   `min-width: 520px` y su envoltorio `.table-wrap`, ver más arriba— y encima la
   pisaba a medias, que es como salió un desborde de 114 px a 430.
   ➡️ Para datos tabulares de verdad se usa la convención existente, con su
   `tabindex`, su `role` y su `aria-label`. Para comparar dos casos en prosa se usa
   `.spec`, que ya existe, se apila solo y no necesita ni una línea nueva. */
.art-firma {
  display: flex; gap: 12px; flex-wrap: wrap; margin: 24px 0 0;
  font-size: 12.5px; color: var(--faint);
}
.art-firma b { color: var(--body); font-weight: 600; }

/* Lecturas recomendadas. ⚠️ SIN ENLACE A NINGUNA TIENDA — decisión del dueño el
   2 sep: «no quiero poner enlace de cualquier librería». Sin enlace no hay
   afiliación que declarar, ni enlace que se pudra, ni librería favorecida. */
.art-lecturas { border-top: 1px solid var(--line); margin-top: 44px; padding-top: 26px; max-width: var(--measure); }
.art-lecturas h2 { font-family: Fraunces, Georgia, serif; font-weight: 600; font-size: 22px; margin: 0 0 6px; }
.art-lecturas .intro { color: var(--faint); font-size: 14px; margin: 0 0 18px; }
.art-libro { border-left: 2px solid var(--rule); padding: 2px 0 2px 14px; margin: 0 0 16px; }
.art-libro .t { color: var(--ink); font-weight: 600; font-size: 15px; }
.art-libro .a { color: var(--faint); font-size: 13px; }
.art-libro .p { color: var(--body); font-size: 14px; margin-top: 4px; }

.art-licencia {
  border-top: 1px solid var(--line); margin-top: 36px; padding: 20px 0;
  max-width: var(--measure); font-size: 13px; color: var(--faint);
}
.art-licencia b { color: var(--body); font-weight: 600; }

.art-siguiente { border-top: 1px solid var(--line); padding: 22px 0 64px; max-width: var(--measure); }
.art-siguiente .et { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--faint); }
.art-siguiente a { font-family: Fraunces, Georgia, serif; font-size: 22px; display: inline-block; margin-top: 6px; }

/* «Anterior» — 9 sep 2026. LO PIDIÓ EL DUEÑO: el pie solo tenía «Next in this
   stage», y en un camino de 62 piezas eso es un pasillo de una sola dirección.
   Se dio cuenta leyendo, no midiendo.
   ➡️ Va ENCIMA del siguiente y en PEQUEÑO, a propósito: quien acaba de leer un
   artículo quiere avanzar, y el enlace grande tiene que seguir siendo el de
   avanzar. Así el pie que ya existía no cambia de aspecto en ninguna página.
   ➡️ Y por eso no hay rejilla de dos columnas: apilado funciona igual a 375 que
   a 1920, sin consulta de medios y sin invertir el orden del DOM en móvil.
   ⚠️ SE ESCRIBE `.art-siguiente .art-anterior a` Y NO `.art-anterior a` A SECAS.
   La regla de aquí arriba, `.art-siguiente a`, tiene la MISMA especificidad
   (0,1,1) y ganaría por ir después. Es la trampa de especificidad que ya mordió
   cinco veces en este archivo. */
.art-anterior { margin: 0 0 18px; }
.art-siguiente .art-anterior a {
  font-family: Inter, system-ui, sans-serif; font-size: 13.5px;
  color: var(--body); margin-top: 0; display: inline-block;
}
.art-siguiente .art-anterior a b { color: var(--ink); font-weight: 600; }
.art-siguiente .art-anterior a:hover b { color: var(--primary); }



/* `.spec` nació para datos cortos —«Platform: NinjaTrader 8»— y ahí sus dos
   columnas van bien. Con PROSA dentro no: medido a 430, sus celdas quedan en
   189 px, que son ~24 caracteres por línea cuando lo cómodo empieza en 45.
   `mod-prosa` es solo para ese uso; el `.spec` de la ficha del producto no se
   entera. — 7 sep */
@media (max-width: 560px) {
  .spec.mod-prosa { grid-template-columns: 1fr; }
}

/* ---------- EL CAMINO DE EDUCACIÓN — 7 sep ----------
   ⚠️ SE LLAMA `.edu-path` Y NO `.path` POR UNA COLISIÓN QUE YA MORDIÓ.
   `.path` YA EXISTE en esta hoja —`kbd, .path`, los trocitos de ruta y de menú
   que usan /setup, /faq y la ficha del producto— y lleva `white-space: nowrap`.
   Al llamar `.path` a la sección, TODA la página heredó el nowrap: ni un texto
   podía partir y el documento se fue 500 px de lado.
   ➡️ Antes de estrenar un nombre de clase se busca en la hoja. Un nombre
   genérico —`path`, `card`, `item`, `box`— casi siempre está cogido.
   Las 10 etapas del área, en `/education`. Idea del dueño: publicar el camino
   entero ahora y rellenarlo después, en vez de esperar a tenerlo escrito.

   🔴 LOS TÍTULOS SIN ESCRIBIR VAN EN `<span>`, NO EN `<a>`, Y ESO NO ES UN
   DETALLE: enlazarlos serían 58 páginas dando 404, y crearlas vacías para que el
   enlace funcione es peor —páginas flacas, que Google penaliza y que bajan la
   calidad del sitio entero—. Como texto no hay ni 404 ni página flaca, y el día
   que se escribe una basta con cambiar el `<span>` por un `<a>`.
   ⚠️ Por eso el `.stage-list li` NO lleva estilo de enlace: lo pinta el `<a>`
   cuando existe. Si algún día parece que «faltan enlaces», es que faltan
   artículos, que es justo lo que la página debe decir. */
.edu-path { padding: 8px 0 20px; }
.edu-path-note {
  max-width: var(--measure); color: var(--faint); font-size: 13.5px;
  margin: 0 0 30px; padding-bottom: 22px; border-bottom: 1px solid var(--line);
}
.stages { list-style: none; margin: 0; padding: 0; }
.stage { border-bottom: 1px solid var(--line); padding: 26px 0; }
.stage:last-child { border-bottom: 0; }
.stage-n {
  font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--primary); font-weight: 700; margin: 0 0 8px;
}
.stage h2 {
  font-family: Fraunces, Georgia, serif; font-weight: 600;
  font-size: clamp(20px, 2.2vw, 25px); line-height: 1.2; margin: 0 0 8px;
}
.stage-d { max-width: var(--measure); color: var(--body); margin: 0 0 16px; font-size: 15px; }
/* 🔴 UNA COLUMNA Y NUMERADOS — 8 sep, y lo pidió el dueño con la razón medida.
   ANTES: `repeat(auto-fit, minmax(250px, 1fr))`, o sea 3 columnas en escritorio.
   La rejilla se rellena POR FILAS, así que el orden era correcto —fila 1 = 1·2·3,
   fila 2 = 4·5·6— pero **nadie lee así una columna de títulos**.
   ⚠️ NO ERA UNA HIPÓTESIS: le pasó a él. Entró en «Why the NQ» (3º, arriba a la
   derecha) esperando que el siguiente fuera «Leverage and margin» —el de debajo—
   y el enlace del final del artículo le dijo «Minis and micros». La maqueta
   contradecía al artículo, y el artículo tenía razón.
   ➡️ El camino es UNA SECUENCIA. Se dibuja como una secuencia: una por línea y
   con su número. El número sale de un contador CSS y se reinicia en cada etapa,
   igual que la firma de los artículos («Stage 1, article 7 of 13»).
   ⚠️ Y el marcado pasó de `<ul>` a `<ol>`: no es cosmética, es lo que hace que un
   lector de pantalla anuncie «elemento 3 de 13» en vez de una lista sin orden. */
.stage-list {
  list-style: none; margin: 0; padding: 0; counter-reset: paso;
}
.stage-list li {
  font-size: 14.5px; color: var(--faint); padding: 4px 0 4px 32px; position: relative;
  counter-increment: paso;
}
.stage-list li::before {
  content: counter(paso); position: absolute; left: 0; width: 20px;
  text-align: right; color: var(--faint); font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
/* ⚠️ EL NÚMERO VA EN `--faint`, NO EN `--rule` COMO IBA EL PUNTO QUE SUSTITUYE.
   Medido: `--rule` (#333835) da **1,67:1** sobre el fondo — valía para un `·`
   decorativo y no vale para una cifra que hay que leer. `--faint` da **5,12:1**.
   🔴 La regla que deja: al convertir un adorno en información, su color se
   vuelve a medir. Heredarlo es heredar un contraste que nunca fue de texto. */
/* 🔴 ESTA REGLA PISABA EL NÚMERO — 8 sep. Ponía `content: "→"` dorada, así que
   los escritos enseñaban FLECHA y los no escritos NÚMERO: justo al revés de lo
   que hace falta, porque los que se pueden leer en orden son los escritos.
   ⚠️ Lo cazó medir el `::before` en el DOM (`content` devolvía "→"), no mirar el
   CSS: la regla estaba 10 líneas más abajo y gana por ir después con la misma
   especificidad.
   ➡️ Se queda SOLO el color. El número lo pone la regla de arriba para todos, y
   el dorado sigue diciendo «este se puede abrir» sin robarle el sitio.
   ⚠️ Y no es color solo: el enlace además va en `--ink` y subrayado. */
.stage-list li:has(a)::before { color: var(--primary); }
.stage-list a { color: var(--ink); }
.stage-list a:hover { color: var(--primary); }
