/* ============================================================================
   SOMOS TRUFAS — LA MARCA
   ============================================================================

   Las dos tipografías y los tokens de color y medida. NADA MÁS: aquí no hay
   componentes, ni reset, ni maqueta. Eso vive en base.css.

   POR QUÉ ESTÁ SEPARADO DE base.css, QUE ES DE DONDE SALIÓ. Porque el panel
   interno (admin.somostrufas.org) es OTRO Worker, en otro origen, y necesita
   la marca pero no necesita el nav, el hero ni las tarjetas de la web
   pública. Cargando base.css entero se traería 950 líneas que no usa —y, lo
   que de verdad importa, se traería `.panel`, que en base.css es el
   desplegable del menú móvil y en el panel sería la pantalla entera. Dos
   componentes con el mismo nombre es el bug que aún no ha pasado.

   ASÍ QUE ESTE ARCHIVO ES LA FRONTERA: lo que comparten la web pública y el
   panel, y solo eso.

   CÓMO LE LLEGA AL PANEL (desde el 28 sep 2026): COPIADO AL PUBLICAR. El
   `build` de panel/wrangler.jsonc corre scripts/comun-panel.mjs, que copia
   este archivo a panel/assets/comun/ y las fuentes a panel/assets/fonts/.
   Los `url('/assets/fonts/…')` de abajo resuelven igual en los dos sitios.
   Hasta ese día el panel lo leía de somostrufas.org en cada visita, con
   CORS para las fuentes: un cambio aquí cambiaba el panel sin probarlo, y en
   las previews del panel las fuentes no cargaban. Los componentes que
   comparten los dos sitios (botones, píldoras, cajas, menú de cuenta) están
   en componentes.css, que viaja igual.

   NO SE ENLAZA CON @import DESDE base.css, y no es un detalle: un @import
   obliga al navegador a pedir base.css, leerlo y ENTONCES pedir este —dos
   viajes en fila antes de pintar una letra. Es exactamente el paso que se
   quitó de encima el día que Poppins dejó de venir de Google. Va con su
   propio <link> en cada página, ANTES del de base.css, y los dos se piden a
   la vez.
   ========================================================================== */

/* ---------- LA TIPOGRAFÍA DE LA MARCA ----------
   DHARMA GOTHIC M, LA DE VERDAD. Hasta ahora el sitio pedía Big Shoulders
   Display a Google Fonts como SUSTITUTO: la del manual es Dharma Gothic M,
   que es de pago y no está en ningún servicio público. El parecido llegaba
   para el aire condensado, pero no es la letra de la marca, y en el manual la
   letra no es un detalle.

   Los archivos viven en /assets/fonts/ y salen de la carpeta de marca
   (Drive → Somos Trufas → Directiva → Branding Público → Fonts). Se sirven
   desde nuestro dominio por velocidad. La licencia de la organización es
   completa (aclarado el 27 sep 2026): no obliga a servirla solo desde aquí.

   VAN EN WOFF2 Y NO EN TTF, que es como llegaron: 15 KB por peso en vez de
   55. El navegador que no entienda woff2 —ninguno de los últimos diez años—
   se queda con Impact, que es la reserva condensada de la pila.

   LOS ARCHIVOS CONVERTIDOS ESTÁN EN EL REPOSITORIO Y ESO NO ES PROVISIONAL:
   Drive guarda los .ttf originales, esto guarda lo que sirve el sitio. La
   conversión se hace UNA VEZ por peso, con `python3 scripts/fuentes.py`, y no
   vuelve a hacer falta ni al clonar ni al desplegar.

   TRES PESOS Y NO CATORCE: el sitio pide 500, 700 y 800 a la display, y cada
   peso que se declara es un archivo que alguien descarga. Las cursivas no
   entran porque la display nunca va en cursiva (el `em` del titular está
   puesto a font-style:normal a propósito).

   `font-display:swap` es el mismo trato que había con Google Fonts: primero
   se lee con la letra de reserva y la de marca entra cuando llega. Nunca hay
   un hueco en blanco esperando a una fuente.

   Los rangos de peso —100 600, 800 900— cubren de sobra lo que se pida: sin
   ellos, un font-weight:600 suelto en cualquier hoja se quedaría sin cara y
   el navegador engordaría la Regular a la fuerza. */
@font-face{
  font-family:'Dharma Gothic M';
  src:url('/assets/fonts/DharmaGothicM-Regular.woff2') format('woff2');
  font-weight:100 600;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Dharma Gothic M';
  src:url('/assets/fonts/DharmaGothicM-Bold.woff2') format('woff2');
  font-weight:700;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Dharma Gothic M';
  src:url('/assets/fonts/DharmaGothicM-ExBold.woff2') format('woff2');
  font-weight:800 900;font-style:normal;font-display:swap;
}

/* ---------- DHARMA GOTHIC E, LA DEL ESCALÓN MEDIO (26 sep 2026; corte del 19 oct) ----------
   La misma familia en un ancho mayor: el mismo titular ocupa un 26 % más
   que en la M. Desde el corte tipográfico del 19 oct 2026 (COO) solo va de
   24 a 31 px: a 32 y más, la M; por debajo de 24, Poppins 600 (ver «EL CORTE
   TIPOGRÁFICO», en el :root). Por debajo de 24 ni la E se lee.

   Dos pesos y ni uno más, los que se usan: Bold y ExBold. Salen de Drive → Fonts/Website/ (.woff) pasados a woff2. Misma
   licencia completa que la M. */
@font-face{
  font-family:'Dharma Gothic E';
  src:url('/assets/fonts/DharmaGothicE-Bold.woff2') format('woff2');
  font-weight:100 700;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Dharma Gothic E';
  src:url('/assets/fonts/DharmaGothicE-ExBold.woff2') format('woff2');
  font-weight:800 900;font-style:normal;font-display:swap;
}

/* ---------- POPPINS, LA DE TEXTO, TAMBIÉN NUESTRA ----------
   ANTES VENÍA DE GOOGLE FONTS y ahora se sirve desde /assets/fonts/, como la
   display. Los archivos salen de la misma carpeta de marca en Drive
   (Somos Trufas → Directiva → Branding Público → Fonts → Poppins) y se
   convirtieron con `python3 scripts/fuentes.py`, igual que Dharma.

   POR QUÉ SE MUDÓ. Cada visita pedía la hoja a fonts.googleapis.com y los
   archivos a fonts.gstatic.com: dos dominios ajenos, con su DNS y su TLS, en
   el camino crítico antes de pintar una sola letra de texto. Y cada persona
   que abría la web le hacía una petición a Google sin haberlo pedido, que
   para una organización benéfica no es un detalle menor.

   CUATRO PESOS, LOS MISMOS QUE PEDÍA A GOOGLE: 300, 400, 500 y 600. Ni uno
   más, y esto importa: el sitio usa font-weight:700 y 800 en varios sitios,
   pero SIEMPRE sobre la pila de Dharma, nunca sobre esta. Antes tampoco los
   servía Google, así que lo que se pintaba con 700 en Poppins —nada, hoy—
   seguiría engordándose igual. El cambio es exacto: mismas caras, mismos
   pesos, otro servidor.

   NÚMEROS SUELTOS Y NO RANGOS, al revés que Dharma. Allí la Regular cubre
   100 600 porque solo hay tres caras y hay que tapar los huecos; aquí las
   cuatro caras son contiguas, y un rango ancho en la Regular se comería a la
   Light, la Medium y la SemiBold. El script lo detecta solo desde que se
   convirtió esta familia: ver `RANGO_REGULAR` en scripts/fuentes.py.

   PESAN 11 KB CADA UNA Y NO 47 porque se les quitó el devanagari, que Poppins
   trae entero: 94 caracteres hindi y unas 650 ligaduras para componerlos, dos
   tercios del archivo, para un alfabeto que esta web no escribe. Ninguna letra
   latina se tocó. El porqué largo está en la cabecera de scripts/fuentes.py. */
@font-face{
  font-family:'Poppins';
  src:url('/assets/fonts/Poppins-Light.woff2') format('woff2');
  font-weight:300;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Poppins';
  src:url('/assets/fonts/Poppins-Regular.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Poppins';
  src:url('/assets/fonts/Poppins-Medium.woff2') format('woff2');
  font-weight:500;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Poppins';
  src:url('/assets/fonts/Poppins-SemiBold.woff2') format('woff2');
  font-weight:600;font-style:normal;font-display:swap;
}

/* ---------- TOKENS ----------
   Marca: Mikado Yellow #FFC621 · Liver #583F37 (Manual TRUFAS)
   Display: Dharma Gothic M  → la del manual, servida desde /assets/fonts/
   Texto:   Poppins          → según manual, servida desde /assets/fonts/
   Este es el único sitio donde se declaran los colores de marca.

   EL SITIO ES DICROMÁTICO: amarillo y marrón, sus variantes tonales, y una
   escala de grises neutra. No hay un tercer matiz, y eso es una regla y no una
   casualidad — si aparece uno nuevo, es que algo se coló.

   AQUÍ VIVÍA `--live:#FF4D3D`, el rojo, y conviene saber por qué se fue. Hacía
   dos trabajos a la vez: era «está pasando ahora» (la barra superior, el botón
   de únete, la píldora, el borde de la tarjeta en directo) y era «algo va mal»
   (los errores de formulario, el sello negativo del panel, el aviso de
   plantilla del media kit). Un color que significa dos cosas opuestas no
   significa ninguna, y encima el amarillo de marca —que es el que debería
   llevarse la mirada— competía con él en cada pantalla.

   EL REPARTO DE AHORA, y es lo único que hay que recordar para no romperlo
   (COO, 28 oct 2026; revierte «el error en gris», que vivía aquí):

     amarillo  → lo que se puede pulsar, lo que está pasando ahora Y LO QUE
                 FALLA O AVISA: la alerta encendida (abajo, --alerta-*)
     marrón    → el soporte: superficies (las capas --capa-*), tinta sobre
                 amarillo, estados tibios
     gris      → SOLO lo apagado y lo que no se verificó (una oferta sin
                 verificar, una beta, lo que no está disponible)

   EL ERROR YA NO ES GRIS. En gris no resaltaba: una caja gris más entre
   cajas marrones. Ahora es un AMARILLO ENCENDIDO, y no se confunde con la
   llamada a la acción porque las dos se pintan al revés: el botón es
   amarillo RELLENO con tinta oscura (se pulsa); la alerta es TEXTO amarillo
   que brilla sobre fondo oscuro, con su icono, un filo lateral y SIN relleno
   (se lee). Tres intensidades: error (filo y texto encendidos, un latido al
   aparecer), importante (filo amarillo apagado, texto crema, sin brillo) e
   info (filo marrón claro). Lo que salva al error, además del color, sigue
   siendo el icono y la frase (quien no distingue matices lee la forma).
   Se aplica primero en el Dashboard (bot-dashboard/assets/dashboard.css); la
   web y Administración, en la fase F5 del plan planes/rediseno-dashboard.html.
   Muestrario, «Componentes 20» y «Estados 5».

   `--live` NO se dejó como alias de nada. Un token llamado «live» que ya no
   pinta lo que está en vivo es el resto que engaña dentro de seis meses. */
:root{
  --ink:#17110D;
  --surface:#241A15;
  --surface-2:#2E211A;
  --line:#4A362B;
  --cream:#F2E8DC;
  --muted:#B09781;
  --yellow:#FFC621;
  --brown:#583F37;

  /* EL COLOR DE CADA REGIÓN. Solo pinta el tag de región de un torneo
     (esports), relleno y con el texto en --ink. Comprobados el 26 sep 2026
     contra --ink y con simulación de daltonismo (Machado 2009):
       norte  #E23DFF  contraste 5,7:1; distinto del amarillo y del verde en
                       deuteranopia, protanopia y tritanopia.
       sur    #2FFFB0  contraste 14:1. NO #89FF2F, el primero que se eligió:
                       con daltonismo rojo-verde quedaba a ΔE 6 del --yellow,
                       o sea que se leía como el amarillo de la marca. El menta
                       se separa (ΔE ~50) sin dejar de ser verde.
     Aun así el color nunca va solo: el tag dice la región en texto, y es el
     único relleno de su fila. */
  --region-norte:#E23DFF;
  --region-sur:#2FFFB0;

  /* LAS VARIANTES DEL AMARILLO. Las tres estaban ya escritas a mano repartidas
     por el sitio —#FFD558 en seis hovers, #C99000 y #8A6200 en la rampa del
     media kit—, así que esto no inventa color: le pone nombre al que había. */
  --yellow-alto:#FFD558;     /* el hover: un punto más encendido */
  --yellow-bajo:#C99000;     /* apagado, pero todavía amarillo */
  --yellow-hondo:#8A6200;    /* el fondo de la rampa, y el amarillo del papel */
  /* La tinta sobre amarillo. Más oscura que --ink a propósito: sobre un fondo
     tan luminoso, el casi-negro puro es lo único que no vibra. */
  --sobre-amarillo:#1A1207;

  /* LA ESCALA DE GRISES — lo apagado y lo que no se verificó (COO, 28 oct
     2026: el error salió de aquí, ver --alerta-* más abajo).
     Neutros de verdad, no marrones desaturados: si llevaran tinte cálido se
     leerían como una variante más de la marca, que es justo lo contrario de
     lo que tienen que decir. Cuatro pasos y ni uno más. */
  --gris-1:#3A3633;          /* superficie de un aviso */
  --gris-2:#6E6864;          /* su filete */
  --gris-3:#9A938D;          /* su texto y su icono (lo apagado; el error ya no: --alerta-*) */
  --gris-4:#C6C1BC;          /* claro, para banda con tinta oscura (la beta) */

  /* LA RAMPA ORDINAL — sube en PESO, no cambia de matiz, que es lo que la hace
     legible para quien no distingue colores. Vivía suelta en el media kit
     (--ord-1..4); subió aquí el día que /esports/ la necesitó para los tres
     niveles del calendario, que antes se separaban por matiz y uno era rojo. */
  --ord-1:#FFE09A;
  --ord-2:#FFC621;
  --ord-3:#C99000;
  --ord-4:#8A6200;

  /* LAS CAPAS DE CHOCOLATE (COO, 28 oct 2026; plan «Rediseño del Dashboard»,
     dirección A + B). La profundidad la da la LUZ, no el trazo: cinco tonos
     del mismo marrón, de la más honda a la más alta. Lo que más ocupa (el
     área de trabajo de una pantalla o una ventana) va en las más oscuras;
     cabeceras, rieles, laterales y la barra de guardar, un escalón más claros;
     cajas y tarjetas, elevadas (3 → 2); ventanas, menús y la etiqueta, la
     más alta (4 → 3). El campo se HUNDE por debajo de todas (--campo-fondo).
     Ninguna superficie es plana: cada una es un degradado VERTICAL de un 2–4 %
     de luz, siempre con la luz desde arriba (el campo, más oscuro arriba; la
     caja y la ventana, más claras arriba), nunca en diagonal ni de color.
     Contraste del texto crema sobre la más alta (#3A2A22): 11,4:1.
     Muestrario, «Color y ambiente 6». Hoy solo las usa el Dashboard. */
  --capa-0:#120D0A;          /* el fondo de la página y de una ventana */
  --capa-1:#1A130F;          /* el área de trabajo, arriba (la luz) */
  --capa-2:#241A15;          /* marcos: cabecera, lateral, riel, barra; el pie de una caja (= --surface) */
  --capa-3:#2F2219;          /* lo alto de una caja elevada */
  --capa-4:#3A2A22;          /* lo alto de una ventana, un menú o la etiqueta */
  --campo-fondo:linear-gradient(180deg,#0D0907,#16100C);   /* hundido: más oscuro arriba */
  --luz-filo:rgba(255,214,140,.07);   /* la raya de luz de arriba de lo que se eleva (inset 0 1px 0) */
  --sombra-hundido:inset 0 2px 5px rgba(0,0,0,.6);
  --sombra-caja:0 14px 28px -18px rgba(0,0,0,.9);
  --sombra-ventana:0 40px 80px -24px rgba(0,0,0,.95);

  /* UNA TEXTURA POR TIPO DE CAJA (COO, 28 oct 2026). Todas son degradados de
     CSS, muy bajos y sin filtros SVG, grano ni imagen (gastan al desplazarse).
     Van como capa de `background-image`, encima del color de la caja:
       luz    → cifras: un brillo amarillo suave desde la esquina de arriba
       (las listas y la vista previa de Discord, sin puntos ni rayas: COO, 28 oct 2026)
       peligro→ lo que borra o no se deshace: rayado amarillo
     Premium no lleva textura: la nebulosa y el barrido de siempre (.oro-aura,
     .pill-gold). Muestrario, «Color y ambiente 6». */
  --tex-luz:radial-gradient(120% 90% at 20% 0,rgba(255,198,33,.10),transparent 60%);
  --tex-peligro:repeating-linear-gradient(135deg,rgba(255,198,33,.12) 0 6px,transparent 6px 14px);

  /* LA ALERTA ENCENDIDA (COO, 28 oct 2026; revierte «el error en gris», ver
     EL REPARTO arriba). Recuadro compacto y oscuro, filo lateral con brillo
     hacia dentro, texto con halo e icono. Tres intensidades, cada una con su
     filo: error (amarillo, brillo y latido), importante (amarillo apagado,
     texto crema) e info (marrón claro). Contraste del texto de error
     (--yellow-alto) sobre --alerta-fondo: ≈13:1; el halo no lo baja. */
  --alerta-fondo:var(--sobre-amarillo);
  --alerta-texto:var(--yellow-alto);
  --alerta-filo:var(--yellow);
  --alerta-filo-importante:var(--yellow-bajo);
  --alerta-filo-info:var(--muted);
  --alerta-velo:linear-gradient(90deg,rgba(255,198,33,.16),rgba(255,198,33,.03) 45%,transparent 70%);
  --alerta-brillo:inset 10px 0 18px -10px rgba(255,198,33,.55);   /* del filo hacia dentro */
  --alerta-halo:0 0 2px rgba(255,246,214,.55),0 0 8px rgba(255,198,33,.8),0 0 18px rgba(255,198,33,.4);
  --alerta-aro:inset 0 0 14px -3px rgba(255,198,33,.7);   /* el campo que falla: brillo por dentro (el bisel recorta lo de fuera) */


  --bevel: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 14px 100%, 0 calc(100% - 14px));
  --bevel-sm: polygon(0 0, calc(100% - 9px) 0, 100% 9px, 100% 100%, 9px 100%, 0 calc(100% - 9px));
  /* EL DE LAS ETIQUETAS (26 sep 2026). El corte va en proporción a la altura:
     9px sobre un botón de ~40px es casi un cuarto, pero sobre una etiqueta de
     ~21px es casi la mitad y la pieza se leía como un rombo. 5px devuelve la
     proporción del botón. Solo para lo que mide --tipo-etiqueta. */
  --bevel-xs: polygon(0 0, calc(100% - 5px) 0, 100% 5px, 100% 100%, 5px 100%, 0 calc(100% - 5px));
  /* EL COMPACTO (16 oct 2026, COO: «el chaflán siempre proporcional a la
     caja»). Los botones de 32 px (`.btn-sm`, filtros) llevaban 9 px: el 28 %
     de su alto, contra el 23 % del `.btn` de 39 y el 19–24 % de una etiqueta.
     Medido con capturas a 3×, a 32 px el de 9 se veía pesado y el de 7 lo
     deja en el 22 %, la misma proporción que el resto. Va de 31 a 36 px;
     desde 37 sigue el de 9. */
  --bevel-compacto: polygon(0 0, calc(100% - 7px) 0, 100% 7px, 100% 100%, 7px 100%, 0 calc(100% - 7px));
  /* LA PERILLA DEL INTERRUPTOR (COO, 28 oct 2026): la pieza de dentro lleva
     los MISMOS chaflanes que su caja (arriba a la derecha y abajo a la
     izquierda), a escala, nunca un cuadrado ni el corte entero de la caja:
     la caja mide 24 con 5 px de corte; la perilla, 16 → 5 × 16 / 24 ≈ 3 px.
     Así encaja en el contenedor. Muestrario, «Formularios 7». */
  --bevel-perilla: polygon(0 0, calc(100% - 3px) 0, 100% 3px, 100% 100%, 3px 100%, 0 calc(100% - 3px));

  /* Y ESO ES UNA REGLA PARA TODO BISEL (27 sep 2026): el chaflán va en
     proporción al alto de la caja. `clip-path` no sabe leer ese alto —en un
     `polygon()` el % de la x es del ancho y el de la y del alto, y un chaflán
     a 45° necesita la misma medida en los dos—, así que va por escalones:

       ≤ 30px   etiqueta, píldora, chip, tooltip  → --bevel-xs       ·  5px
       31–36px  botón compacto, filtro, chip      → --bevel-compacto ·  7px
       37–60px  botón, control, chip de red       → --bevel-sm       ·  9px
       > 60px   tarjeta, panel, aviso, caja        → --bevel          · 14px

     Cada uno con su aro (--filo-*) y su foco (--filo-foco-*) del mismo
     tamaño: un aro de otro escalón no casa con el recorte. */

  /* EL FILO DEL BISEL — el contorno que `clip-path` no sabe dibujar.
     ────────────────────────────────────────────────────────────────────
     Un clip recorta TODO lo que pinta el elemento, el borde incluido. Y el
     borde —sea `border:1px solid` o `box-shadow:inset 0 0 0 1px`— se dibuja
     sobre el RECTÁNGULO, así que las dos esquinas cortadas se llevan su
     trozo por delante y el contorno se queda con dos huecos, justo en los
     chaflanes. Se veía en la píldora del premio, en el Discord de la barra,
     en la hamburguesa y en otras veinte cajas.

     Esto lo arregla dibujando el contorno como lo que es: UN ARO con la
     forma del bisel. La `polygon()` lleva los dos contornos —el de fuera y
     el de dentro— y `evenodd` deja hueco lo de en medio.

     LA GEOMETRÍA DE DENTRO: CORTE + 1px, NO «CORTE + 0,414». La diagonal
     de un aro tiene que VERSE del mismo grueso que los lados, y eso no es lo
     mismo que MEDIR lo mismo. Hasta el 16 oct 2026 el polígono de dentro
     caía en `corte + 0.414px` (9.414 para el de 9): es la cuenta exacta
     para que la diagonal quede a 1px EN PERPENDICULAR de la de fuera, y aun
     así la raya del chaflán se veía más fina que la de los lados (el
     corazón del riel plegado, el chip BETA, los botones y las píldoras).
     Medido a 1× con Chromium sobre amarillo, en píxeles CSS (suma de
     cobertura y pico del perfil; los lados dan 1,00 y 1,00):

       aro de 1px, dentro a corte + 0,414  → diagonal 0,81–0,91 y pico 0,86
       aro de 1px, dentro a corte + 0,7    → 1,02–1,14 y pico 0,96
       aro de 1px, dentro a corte + 1      → 1,19–1,33 y pico 1,00   ← el elegido
       `.caja` (capa doble)                → 1,39–1,43 y pico 1,00

     Una diagonal a 45° no cae en una sola fila de píxeles: se reparte entre
     dos, ninguna llega al 100 % (pico 0,86 a 1×), y lo que se pinta mide
     menos de lo que dice la geometría. Con `corte + 1px` la diagonal sale de
     1,41px perpendiculares —la misma que da a `.caja` el `inset:1px` con el
     mismo bisel dentro— y, ya suavizada, se lee igual de firme que los
     lados. Y a 2px (el foco), lo mismo: `corte + 1px` mide 1,92–2,04 contra
     los 2,00 de los lados; `+ 0,828` (la cuenta exacta) se quedaba en 1,78–
     1,93 y `+ 2` se pasaba a 2,6–2,75, más gruesa que los lados.

     Por eso las coordenadas de dentro son siempre `corte + 1px`, sea el aro
     de 1px o de 2px: 15, 10 y 6 (14, 9 y 5 + 1). No se vuelve a la cuenta
     exacta ni se escribe «a ojo»: si se cambia el grosor, el corte o el
     escalón, se mide de nuevo (Playwright, DSF 1 y 2, el perfil perpendicular
     de la diagonal contra el de un lado) antes de dar el aro por bueno. Las
     copias sueltas de este aro (`r/guia-aurea`, el aviso de idioma de
     `i18n.js`) llevan el mismo +1.

     Y LOS DOS CONTORNOS VAN EN UNA SOLA LISTA, CON UNA COSTURA QUE SE ANULA.
     Esto es lo que más fácil se rompe al retocarlo, así que conviene leerlo
     antes de tocar un punto: `polygon()` NO admite dos contornos: es UN camino
     cerrado y nada más. Los catorce puntos de abajo son el de fuera, luego una
     costura hasta el de dentro, el de dentro AL REVÉS, y la vuelta por la
     misma costura (el cierre automático del último punto al primero).

     Que la ida y la vuelta de esa costura sean EXACTAMENTE la misma línea es
     lo único que hace que funcione: así encierra área cero y `evenodd` la
     ignora. Por eso `0 0` y `1px 1px` aparecen dos veces, y por eso el
     contorno de dentro se recorre en sentido contrario al de fuera.

     La primera versión no lo hacía —saltaba de `0 calc(100% - 9px)` a `1px
     1px` y volvía por otro sitio—, y esas dos costuras distintas encerraban
     una cuña que corría justo por el canto izquierdo: `evenodd` le daba la
     vuelta a la paridad y EL FILO IZQUIERDO SALÍA CASI BORRADO mientras el
     derecho salía entero. Medido a 8×: 2.3 de cobertura a la izquierda contra
     8.0 a la derecha, donde 8.0 es 1px justo. Con la costura anulada los
     cuatro cantos miden 8.0.

     Y HAY RESERVA PARA QUIEN NO LO ENTIENDA, que es de lo que va
     `--filo-borde`. El `border`/`box-shadow` de antes NO se ha borrado: se
     queda declarado como `var(--filo-borde, var(--filo-color))`, o sea del
     color del filo. El `@supports` que enciende el aro pone
     `--filo-borde:transparent` en el `:root` una sola vez, y con eso apaga
     todas las reservas del documento de golpe — sin tener que repetir un
     `border-color:transparent` regla por regla, y sin que un `:hover` que
     toque el color lo vuelva a encender por especificidad.

     Así el navegador que entienda el `fill-rule` ve el aro limpio, y el que no
     lo entienda ve EXACTAMENTE lo de hoy: el contorno con sus dos huecos. Lo
     que no ve nadie es una caja sin contorno.

     ⚠ PARA UNA CAJA OPACA GRANDE NO SE USA ESTO: se usa `.caja`
     (componentes.css), la capa doble, que no pierde raya en medio píxel ni
     depende de `evenodd` (medido el 28 sep 2026). El aro es para lo pequeño o
     translúcido: botones, píldoras, chips.

     CÓMO SE USA — en un `::after`, nunca en el elemento:

       .algo{position:relative; --filo-color:var(--line);
             box-shadow:inset 0 0 0 1px var(--filo-borde, var(--filo-color))}
       @supports (clip-path:polygon(evenodd,0 0,1px 1px,0 1px)){
         :root{--filo-borde:transparent}          · una vez por documento
         .algo::after{content:''; position:absolute; inset:0; pointer-events:none;
                      clip-path:var(--filo-sm); background:var(--filo-color)}
       }

     · Si el elemento tiene `border:1px` de verdad (que aporta caja), el
       borde se deja pero en `transparent` y el pseudo va a `inset:-1px`,
       que es lo que alcanza la caja de borde: `inset:0` se queda en la de
       relleno y el aro saldría 1px por dentro, en doble raya.
     · Si el filo era un `box-shadow:inset`, se queda como reserva, pero
       leyendo `--filo-borde`: apagado, no pinta nada y no se suma al aro —
       que con un filo translúcido importa, porque dos capas del mismo color
       al 30 % sumarían en los tramos rectos y no en las diagonales.
     · El color se cambia en un solo sitio, `--filo-color`, y por eso los
       estados (`:hover`, `.destacada`) tocan esa variable y no el borde: así
       cambian el aro y su reserva a la vez, con una línea.

     ⚠ SIEMPRE DENTRO DE SU `@supports`. Si un navegador no acepta el
     `fill-rule` dentro de `polygon()`, la declaración entera es inválida,
     `clip-path` vuelve a su valor inicial (`none`) y el pseudo se pintaría
     como UN RECTÁNGULO MACIZO tapando el elemento. Sin la guarda el fallo
     no es un hueco, es una mancha. La condición que hay que escribir es:

       @supports (clip-path: polygon(evenodd, 0 0, 1px 1px, 0 1px)) { … } */
  --filo: polygon(evenodd,
    0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 14px 100%, 0 calc(100% - 14px), 0 0,
    1px 1px, 1px calc(100% - 15px), 15px calc(100% - 1px),
    calc(100% - 1px) calc(100% - 1px), calc(100% - 1px) 15px,
    calc(100% - 15px) 1px, 1px 1px);
  --filo-sm: polygon(evenodd,
    0 0, calc(100% - 9px) 0, 100% 9px, 100% 100%, 9px 100%, 0 calc(100% - 9px), 0 0,
    1px 1px, 1px calc(100% - 10px), 10px calc(100% - 1px),
    calc(100% - 1px) calc(100% - 1px), calc(100% - 1px) 10px,
    calc(100% - 10px) 1px, 1px 1px);
  --filo-xs: polygon(evenodd,
    0 0, calc(100% - 5px) 0, 100% 5px, 100% 100%, 5px 100%, 0 calc(100% - 5px), 0 0,
    1px 1px, 1px calc(100% - 6px), 6px calc(100% - 1px),
    calc(100% - 1px) calc(100% - 1px), calc(100% - 1px) 6px,
    calc(100% - 6px) 1px, 1px 1px);
  --filo-compacto: polygon(evenodd,
    0 0, calc(100% - 7px) 0, 100% 7px, 100% 100%, 7px 100%, 0 calc(100% - 7px), 0 0,
    1px 1px, 1px calc(100% - 8px), 8px calc(100% - 1px),
    calc(100% - 1px) calc(100% - 1px), calc(100% - 1px) 8px,
    calc(100% - 8px) 1px, 1px 1px);

  /* Y LOS MISMOS A 2px, PARA EL FOCO. El `:focus-visible` del sitio es un
     `outline` con `outline-offset:3px`, o sea que en cualquier cosa biselada
     cae ENTERO fuera del recorte: hoy ningún botón con bisel enseña dónde
     está el teclado. El anillo tiene que ir por dentro, y es el mismo aro
     con otro color y otro grosor. Es la salida que el panel ya tomó — ver
     la cabecera de panel/assets/panel.css. */
  --filo-foco: polygon(evenodd,
    0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 14px 100%, 0 calc(100% - 14px), 0 0,
    2px 2px, 2px calc(100% - 15px), 15px calc(100% - 2px),
    calc(100% - 2px) calc(100% - 2px), calc(100% - 2px) 15px,
    calc(100% - 15px) 2px, 2px 2px);
  --filo-foco-sm: polygon(evenodd,
    0 0, calc(100% - 9px) 0, 100% 9px, 100% 100%, 9px 100%, 0 calc(100% - 9px), 0 0,
    2px 2px, 2px calc(100% - 10px), 10px calc(100% - 2px),
    calc(100% - 2px) calc(100% - 2px), calc(100% - 2px) 10px,
    calc(100% - 10px) 2px, 2px 2px);
  --filo-foco-xs: polygon(evenodd,
    0 0, calc(100% - 5px) 0, 100% 5px, 100% 100%, 5px 100%, 0 calc(100% - 5px), 0 0,
    2px 2px, 2px calc(100% - 6px), 6px calc(100% - 2px),
    calc(100% - 2px) calc(100% - 2px), calc(100% - 2px) 6px,
    calc(100% - 6px) 2px, 2px 2px);
  --filo-foco-compacto: polygon(evenodd,
    0 0, calc(100% - 7px) 0, 100% 7px, 100% 100%, 7px 100%, 0 calc(100% - 7px), 0 0,
    2px 2px, 2px calc(100% - 8px), 8px calc(100% - 2px),
    calc(100% - 2px) calc(100% - 2px), calc(100% - 2px) 8px,
    calc(100% - 8px) 2px, 2px 2px);
  /* En rem, no en px, y esto importa más de lo que parece: toda la
     tipografía del sitio va en rem, así que si alguien tiene la fuente
     base del navegador por encima de 16px el texto crecía mientras el
     ancho de columna se quedaba clavado. Resultado: las tarjetas se
     estiraban a lo alto, la miniatura seguía igual de baja y las fechas
     se partían en dos renglones. Con la maqueta en la misma unidad que
     el texto, todo escala junto y la proporción se mantiene.
     82.5rem × 16 = 1320px (16 oct 2026, CEO: el contenido dejaba demasiado
     margen a los lados; antes 73.75rem = 1180). En el lienzo (≥960) manda
     el de assets/pantalla.css. Los textos largos (legal, artículos) limitan
     su línea con su propio max-width en rem: nunca van a este ancho. */
  --wrap: 82.5rem;
  /* EL CANAL: el relleno lateral de .wrap (y de lo que se alinee con él).
     30 px; 20 en el móvil (≤520, abajo). Nunca un padding lateral suelto.
     CEO, 21 oct 2026: un 25 % más de margen a los lados en todo (antes 24 y
     16); el Dashboard (.vista) y Administración (.contenido) lo siguen. */
  --canal: 1.875rem;
  /* UNA SOLA ALTURA DE BARRA PARA TODO EL SITIO. Antes la portada iba a 68 y
     el media kit a 64, y cada página redeclaraba la suya. Cuatro píxeles no
     los identifica nadie a simple vista, pero al pasar de una página a otra
     se percibe que la barra "encoge", que es peor que si la diferencia fuera
     grande: se nota y no se sabe por qué.
     Si alguna página necesitara otra medida, que la sobrescriba con un motivo
     escrito al lado — no por haberse quedado así. */
  --nav-h: 68px;

  /* ════════════════════════════════════════════════════════════════════
     EL SISTEMA DE DISEÑO — 26 sep 2026
     ════════════════════════════════════════════════════════════════════
     Tipografía, texto, espaciado y movimiento, sacados del home y
     aprobados sobre un muestrario con las fuentes de verdad. Los usa toda
     la web pública desde el mismo día; el panel, todavía no. Las reglas de uso, el
     porqué y la lista de lo que falta migrar están en la skill
     `.claude/skills/diseno-trufas/`, que es donde hay que mirar antes de
     tocar nada visual.

     `--tipo-*` Y NO `--t-*`: el panel ya usa `--t-rapido/medio/lento` para
     DURACIONES y lee este archivo. Un `--t-titulo` al lado de un `--t-medio`
     que es un tiempo es la confusión que se evita con cuatro letras más. */

  /* EL CORTE TIPOGRÁFICO (CEO, 21 oct 2026; revierte «24 a 31 px → Dharma
     E», COO, 19 oct 2026). La familia de un titular la decide SU TAMAÑO
     EFECTIVO, no su papel: en pequeño la Dharma (M y E) no se lee, y el CEO
     no la quiere. Escala de referencia 12 · 14 · 16 · 18 · 20 · 24 · 28 · 32
     · 40 px:
       · ≥ 32 px (2rem)  → Dharma Gothic M  (--fuente-display), 700/800; la E
                           (--fuente-display-e, con --tracking-e) solo si hace
                           falta su ancho, y también ≥ 32 px
       · < 32 px         → Poppins 600      (--fuente-titular + --peso-titular),
                           con --tracking-titular si va en mayúsculas y
                           --interlinea-titular (Poppins no aguanta el .9)
     Un tamaño fluido (clamp) se juzga por lo que mide de verdad: si en móvil
     baja de 32 pasa a Poppins (con un @media, o con el token de familia del
     escalón de abajo). Lo que ya va en mayúsculas sigue en mayúsculas: solo
     cambian familia, grosor y aire. Reglas y tabla viva en /muestra, «Textos
     1 · El corte tipográfico». */
  --fuente-display:   'Dharma Gothic M', 'Oswald', Impact, sans-serif;           /* ≥ 32 px */
  --fuente-display-e: 'Dharma Gothic E', 'Dharma Gothic M', 'Oswald', Impact, sans-serif; /* ≥ 32 px, si hace falta ancho */
  --fuente-texto:     'Poppins', system-ui, sans-serif;
  --fuente-titular:   var(--fuente-texto);                                       /* < 32 px */
  --peso-titular:     600;          /* el 600 que ya se sirve: no se añade 700 */
  --tracking-titular: .05em;        /* Poppins en mayúsculas pequeñas: abre la versal */
  --interlinea-titular: 1.2;
  /* Más aire entre letras en la E, siempre (COO, 18 oct 2026): suma al
     tracking propio de cada uso, no lo reemplaza. */
  --tracking-e: .02em;

  /* LA FAMILIA DE CADA ESCALÓN DISPLAY. Subtítulo, numeral y dato cambian de
     tamaño con la escala compacta, así que su familia va con ellos: se usan
     SIEMPRE juntos, tamaño, familia y aire —
       font-family:var(--fuente-subtitulo);font-size:var(--tipo-subtitulo);
       letter-spacing:calc(.01em + var(--tracking-subtitulo));
     y nunca --fuente-display ni --fuente-display-e a pelo sobre un --tipo-*
     que cambia.
     Hero, título y cifra son siempre M (≥ 50 px): --fuente-display. */
  --fuente-subtitulo: var(--fuente-display);   --tracking-subtitulo: 0em;  /* 34 → 42: M */
  --fuente-numeral:   var(--fuente-display);   --tracking-numeral:   0em;  /* 44: M */
  --fuente-dato:      var(--fuente-display);   --tracking-dato:      0em;  /* 32: M */

  /* TIPOGRAFÍA · DISPLAY (mayúsculas, interlínea .9) */
  --tipo-hero:      clamp(4.7rem, 8.5vw, 6.4rem);           /* 75 → 102 · h1 */
  --tipo-titulo:    clamp(3.1rem, 5.5vw, 4.75rem);          /* 50 → 76 · h2 de sección */
  --tipo-cifra:     clamp(4.1rem, 9vw, 5.6rem);             /* 66 → 90 · cifras de impacto */
  --tipo-subtitulo: clamp(2.125rem, 1.45rem + 1.6vw, 2.625rem);/* 34 → 42 · tarjeta, evento, creador · M */
  --tipo-numeral:   2.75rem;                                /* 44 · números de paso · M */
  --tipo-dato:      2rem;                                   /* 32 · cifra pequeña, chip de logo · M */

  /* TIPOGRAFÍA · TEXTO (Poppins). ESTA ES LA ESCALA DE ADMINISTRACIÓN (el
     panel no lleva `escala-compacta`; la web y el Dashboard, la de más abajo).
     COO, 27 oct 2026: «los textos pequeños apenas se leen». Todo lo pequeño
     subió y la leyenda dejó de ser un nivel: UN NIVEL MENOS. Cada valor es el
     de la escala compacta × la proporción que ya tenía el panel sobre ella
     (17/15, 15/14, 14/13, 13/12, 14/12, 11/10), a medio píxel. Antes entre
     paréntesis. Por debajo de 13 px no se escribe nada. */
  --tipo-entradilla:  1.15625rem; /* 18,5 (17) · bajada del hero; h3 de caja en 600 */
  --tipo-cuerpo:      1.03125rem; /* 16,5 (15) · párrafos de lectura */
  --tipo-descripcion: .96875rem;  /* 15,5 (14) · bajada de sección, texto de tarjeta, pie… y notas, fuentes y copyright */
  --tipo-control:     .9375rem;   /* 15 (13) · botones y enlaces de la barra */
  --tipo-antetitulo:  1rem;       /* 16 (14) · «01 / …» y el antetítulo del hero, en todas las páginas */
  --tipo-rotulo:      .90625rem;  /* 14,5 (11) · rótulo de panel, del pie, del selector de idioma: no es antetítulo */
  --tipo-etiqueta:    .84375rem;  /* 13,5 (10) · tags, píldoras, metadatos. UN tamaño,
                                     tres niveles: relleno / contorno amarillo /
                                     contorno gris. La jerarquía no va en el tamaño. */
  /* LA LEYENDA YA NO ES UN TAMAÑO (COO, 27 oct 2026). Notas, fuentes, lo
     legal y el copyright miden lo mismo que la descripción: lo que las separa
     de ella es el COLOR (--texto-3, el marrón pálido de bajo contraste), no un
     tamaño más pequeño que no se lee. El nombre se queda como alias, con UNA
     sola fuente de verdad: cientos de reglas dicen `font-size:var(--tipo-leyenda)`
     (580 en 60 archivos) y así dicen, además, «esto es una nota». Quien
     redeclare --tipo-descripcion en un contenedor (el lateral del panel)
     repite esta línea: un var() se resuelve donde se declara. */
  --tipo-leyenda:     var(--tipo-descripcion);

  /* CHIPS Y BOTONES · MEDIDAS (16 oct 2026, pedido por el COO). Todos los
     chips de la web, el panel y el dashboard bajaron ~15 % de alto y de
     relleno y un escalón de letra, DESDE AQUÍ y no página a página: botón,
     botón pequeño, filtro, píldora, tag, selector de idioma, chip de fase.
     El alto manda el bisel (escalones de más arriba): botón y filtro 32–39 →
     --bevel-sm; píldora, tag, selector y chip de fase ≤ 30 → --bevel-xs.
     Suelo táctil: 32 px de alto visual en todo lo pulsable (btn-sm, filtro). */
  --btn-pad-y:      .62rem;       /* 10 · .btn   (antes .85rem) → 39 px de alto (antes 46) */
  --btn-pad-x:      1.25rem;      /* 20 · .btn   (antes 1.5rem) */
  --btn-sm-alto:    2rem;         /* 32 · .btn-sm, filtros (antes ~36–37). El suelo táctil */
  --btn-sm-pad-x:   .85rem;       /* 14 · .btn-sm (antes 1.05rem) */
  --pill-pad-y:     .2rem;        /*  3 · .pill, .bv-tag (antes .32rem) → 26–27 px de alto con la letra a 13,5 (27 oct 2026; eran 21 con la de 10) */
  --pill-pad-x:     .55rem;       /*  9 · (antes .65rem) */
  --chip-alto:      1.625rem;     /* 26 · «Más info» de la tarjeta (antes 32) */
  --flotante-alto:  2.375rem;     /* 38 · los dos flotantes de abajo: el de estado (beta/staff) y el índice (CEO, 22 oct 2026) */

  /* EL ANCHO DE UN CAMPO sale del dato que lleva, nunca del contenedor
     (COO, 19 oct 2026; muestrario «Inicio 3»). Un nombre de 32 caracteres no
     ocupa 1200 px: un campo crece hasta su escalón y, si sobra sitio, los
     campos se ponen en columnas (.campos de componentes.css). */
  --campo-s:        10rem;        /* 160 · número, color, hora, TAG, código corto */
  --campo-m:        18rem;        /* 288 · nombre, apodo, canal, rol (≤ 32 caracteres) */
  --campo-l:        28rem;        /* 448 · título, enlace, frase (≤ 100) */
  --campo-xl:       40rem;        /* 640 · texto largo de varias líneas; el máximo de lectura */
  /* EL ANCHO MÁXIMO DEL CONTENIDO DE UNA PANTALLA DE AJUSTES (COO, 28 oct
     2026; avanza «El Dashboard gestiona mal el espacio», CEO, 23 oct 2026):
     a 1280 los ajustes no cruzan la pantalla de un lado a otro. Las listas y
     tablas siguen a lo ancho. */
  --ancho-lectura:  60rem;        /* 960 */

  /* TEXTO · TRES NIVELES. Había cinco tonos que medían como tres (crema al
     86 % y la mezcla de la bajada, 11,6 y 11,9:1; crema al 62 % y --muted,
     6,8 y 6,8:1). En pantalla lo más claro es el crema: los titulares
     también. Contrastes sobre --ink. */
  --texto-1: var(--cream);                                       /* 15,5:1 · títulos y texto principal */
  --texto-2: color-mix(in srgb, var(--cream) 65%, var(--muted)); /* 11,9:1 · bajadas y apoyo */
  --texto-3: var(--muted);                                       /*  6,8:1 · metadatos, leyendas, pies */

  /* ESPACIADO. Los dos que cambian con la pantalla se redefinen abajo. */
  --esp-seccion:  6rem;     /* 96 · entre secciones (64 en ≤900) */
  --esp-cabecera: 2.75rem;  /* 44 · cabecera de sección → contenido */
  --esp-bloque:   3rem;     /* 48 · entre bloques de una sección, antes del cierre */
  --inicio-pagina:3rem;     /* 48 · de la cabecera al antetítulo: TODAS las páginas empiezan a la misma altura (CEO, 22 oct 2026; 44 en ≤520) */
  --cab-alto:     3rem;     /* 48 · la cabecera delgada de la web, Administración y el Dashboard (CEO, 22 oct 2026) */
  --esp-rejilla:  1.25rem;  /* 20 · hueco entre tarjetas */
  --esp-caja:     2.5rem;   /* 40 · relleno de una caja biselada (24 en ≤520) */

  /* MOVIMIENTO AL HACER SCROLL. Desvanecido (el del home, conducido por el
     scroll) + colocación: el bloque salta a su sitio con un rebote leve. En
     inglés: scroll reveal, fade-up, ease-out-back, stagger. */
  --mov-tramo:   160px;                         /* scroll que dura el desvanecido */
  --mov-desde:   1.25rem;                       /* 20 · de dónde sube al colocarse */
  --mov-colocar: .6s;                           /* duración del salto */
  --mov-escalon: 80ms;                          /* retraso entre hermanos de una rejilla */
  --mov-rebote:  cubic-bezier(.34, 1.56, .64, 1); /* se pasa ~2px y vuelve */

  /* LO APAGADO (CEO, 21 oct 2026; revierte «en gris»): lo que no está
     disponible o aún no existe se ve IGUAL que lo activo (mismos colores,
     imagen, amarillo y etiquetas) pero con esta opacidad, sin hover ni realce.
     Es un ESTADO, no un nivel de texto. Un solo valor para `.es-inactivo`, las
     tarjetas de ofertas y todo lo que se apague. */
  --opacidad-apagado: .45;
}
@media (max-width:900px){ :root{ --esp-seccion:4rem } }
/* El canal en el móvil: 20 px a cada lado (CEO, 21 oct 2026; antes 16). */
@media (max-width:520px){ :root{ --canal:1.25rem } }
@media (max-width:520px){ :root{ --esp-caja:1.5rem; --inicio-pagina:2.75rem } }

/* LA ESCALA COMPACTA (10 oct 2026, pedido por el CEO: «parece un sitio para
   ancianos»). Un escalón por debajo en todo lo que NO es titular: título de
   tarjeta, cifras pequeñas, bajadas, botones, antetítulos y rótulos. Hero,
   título y cifra no se tocan. (El 27 oct 2026 los textos pequeños subieron:
   ver más abajo; el suelo de lo que se escribe es hoy 13 px.)

   La lleva TODA LA WEB PÚBLICA desde el 10 oct 2026 (<html class=
   "escala-compacta"> en cada página; una página nueva también). El panel
   no: tiene su propia escala, un escalón POR ENCIMA (el :root de arriba), y
   por eso estos valores no van allí, que el panel también lee.
   En el lienzo de ordenador la acompañan un tope al zoom y los titulares
   compensados (assets/pantalla.css y pantalla.js). Reglas, en la skill. */
:root.escala-compacta{
  --tipo-subtitulo:   1.25rem;    /* 20 · Poppins */
  --tipo-numeral:     2.25rem;    /* 36 · M */
  --tipo-dato:        1.125rem;   /* 18 · Poppins */
  /* Su familia, con ellos (el corte del CEO, 21 oct 2026): por debajo de
     32 px, Poppins 600; en su escala (20 y 18), no en la de la Dharma. */
  --fuente-subtitulo: var(--fuente-titular); --tracking-subtitulo: var(--tracking-titular);
  --fuente-dato:      var(--fuente-titular); --tracking-dato:      var(--tracking-titular);
  /* El cronómetro (base.css) baja con el título que acompaña: 54 → 44. */
  --cifra-cuenta:     clamp(2.125rem, 1.45rem + 1.8vw, 2.75rem);
}

/* LA ESCALA DE LO PEQUEÑO, de la web y del Dashboard (`escala-compacta`) y
   del lateral y el dock de Administración (`.barra`, `.lat-movil`), que
   llevan la misma que el home aunque el panel use la suya: UNA sola
   declaración, sin copias en panel.css ni lateral.css. Lo pequeño, más
   grande (COO, 27 oct 2026: «los textos pequeños apenas se leen»): lo normal
   +10 %; botones y antetítulos a 14; rótulos y etiquetas a 13,5. La leyenda
   ya no es un tamaño: --tipo-leyenda es el alias de la descripción y la
   jerarquía de una nota la da el color (--texto-3). Entre paréntesis, lo de
   antes. Si un nivel cambia aquí, cambia todo lo que lo usa. */
:root.escala-compacta, .barra, .lat-movil{
  --tipo-entradilla:  1.03125rem; /* 16,5 (15) */
  --tipo-cuerpo:      .96875rem;  /* 15,5 (14) */
  --tipo-descripcion: .90625rem;  /* 14,5 (13) · y la leyenda (11) */
  --tipo-leyenda:     var(--tipo-descripcion);
  --tipo-control:     .875rem;    /* 14 (12) */
  --tipo-antetitulo:  .875rem;    /* 14 (12) */
  --tipo-rotulo:      .84375rem;  /* 13,5 (10) */
  --tipo-etiqueta:    .84375rem;  /* 13,5 (10) */
}

/* ---------- TEXTO SIN VIUDAS NI HUÉRFANAS (8 oct 2026, pedido por el COO) ----------
   Ningún título termina con una palabra sola en su último renglón y ningún
   párrafo deja una palabra colgando al final. Lo hace el navegador:
     · títulos: `balance` reparte las palabras para que los renglones midan
       parecido («JUGAMOS / PARA AYUDAR» y no «JUGAMOS PARA / AYUDAR»);
     · párrafos y bajadas: `pretty` evita la última palabra sola.
   Donde el navegador no lo sabe hacer, el texto fluye como siempre. Lo que
   CSS no resuelve va a mano, con espacio duro (&nbsp;): cifra y unidad
   («6.5K&nbsp;USD»), y palabras que no deben separarse. La regla completa,
   en /muestra y en la skill diseno-trufas. */
h1,h2,h3,h4,h5,h6{text-wrap:balance}
p,li,dd,dt,figcaption,blockquote,label,small{text-wrap:pretty}

/* ---------- LA LETRA NO DEPENDE DEL NAVEGADOR (16 oct 2026, decidido por el CEO) ----------
   El rem vale 16 px en TODO ancho y en los tres sitios (web, panel y
   dashboard del bot, que leen este archivo). Hasta hoy solo se fijaba en el
   lienzo de ordenador (≥960, html.pantallas en pantalla.css, decisión del
   COO del 8 oct); por debajo, quien tuviera la letra del navegador en
   «Grande» (20 px) veía todo lo que va en rem un 25 % más grande y
   descuadrado frente a lo que va en px.
     · `font-size:16px` y no 100 %: el 100 % es justo la preferencia que se
       ignora a sabiendas, como hacen Google o Instagram.
     · `text-size-adjust:100%`: Safari en iPhone y Chrome en Android no
       agrandan la letra por su cuenta al girar el móvil o en columnas que
       crean «de lectura».
   NO ROMPE LA ACCESIBILIDAD que importa: el ZOOM del navegador (Ctrl + /
   pellizcar) sigue escalándolo todo, rem y px por igual, y pantalla.css
   congela sus tokens a 1440 sobre este mismo rem. Lo que deja de hacer
   efecto es solo el ajuste «Tamaño de fuente» de la configuración. */
html{font-size:16px;-webkit-text-size-adjust:100%;text-size-adjust:100%}
