/* ============================================================================
   tokens.css — Sistema de diseño único "Oro sobre Medianoche"
   BM Premier Solutions · capital.bmpremiersolutions.com

   ESTE ARCHIVO SE ENLAZA ANTES QUE CUALQUIER OTRO CSS, en los dos sitios
   donde se pinta un <head>:
     - private/includes/layout.php  (portal /c/, solicitar.php, /admin/)
     - public_html/index.php, proceso.php, credito.php, privacidad.php,
       empezar.php  (páginas que pintan su propio <head>)

   Contiene TRES capas, en este orden:
     1. TOKENS  — la paleta, la tipografía, el espacio, los radios.
     2. BASE    — reset mínimo, body, titulares, foco.
     3. CHROME  — la cabecera, el pie, la marca, el botón, el chip, el badge
                  y el campo de formulario. Van aquí y no en home.css /
                  style.css a propósito: son las piezas que TIENEN que ser
                  idénticas en las dos hojas. Si vivieran duplicadas, en tres
                  meses el sitio público y el portal volverían a tener dos
                  cabeceras distintas — que es justo el problema que este
                  sistema viene a cerrar.

   Lo específico de cada zona sigue en su hoja:
     home.css  -> inicio, crédito, proceso, privacidad, empezar
     style.css -> portal del cliente, solicitar, login, panel

   Restricciones que este archivo respeta:
     - CSP del portal (script-src 'self', font-src 'self'): las fuentes se
       auto-alojan en assets/fonts/*.woff2. Nada de Google Fonts.
     - Ambos temas resuelven: cada token tiene valor en :root (claro) y se
       redefine bajo prefers-color-scheme:dark protegido con
       :root:not([data-theme="light"]) y otra vez bajo :root[data-theme="dark"].
       NINGÚN color vive solo dentro de un @media.
     - prefers-reduced-motion respetado al final del archivo.
   ============================================================================ */

:root {
  /* ==========================================================================
     1. PALETA DE MARCA (valores crudos; los componentes NO los usan directo,
        usan los tokens de rol de la sección 3)
     ========================================================================== */

  /* Oro — del emblema. 500 es el oro de marca. 800 es el único oro que pasa
     AA como TEXTO sobre blanco (5.9:1): en tema claro el oro "de texto" no
     puede ser el mismo que el oro "de relleno". Ese fue el error de
     landing.css, que usaba #e8821c como texto sobre blanco (3.1:1). */
  --oro-200: #FFE7A8;
  --oro-300: #FFD469;
  --oro-400: #FFC542;
  --oro-500: #FFAB00;   /* marca */
  --oro-600: #E08C0A;
  --oro-700: #B86E00;
  --oro-800: #8A5A00;   /* oro como texto en tema claro */

  /* Azul — el azul real del logo. 500 es el "cielo" sobre medianoche (5.8:1);
     600 es el del logo, que sobre blanco pasa AA (5.0:1) y es el relleno del
     botón secundario; 800 es el marino del logotipo de texto. */
  --azul-200: #CDE8FF;
  --azul-300: #9BD1FF;
  --azul-400: #7FC4FF;
  --azul-500: #2E90FF;
  --azul-600: #0B6CDB;
  --azul-700: #0F4FB0;
  --azul-800: #12328A;

  /* Medianoche — el marino del logo llevado a fondo de noche. 950 es también
     el color de las bandas de marca (hero y pie) en AMBOS temas. */
  --noche-700: #1F3557;
  --noche-800: #16294A;
  --noche-900: #0F1F3A;
  --noche-950: #08132A;

  /* Neutros con sesgo de marca (azul, no gris de fábrica). */
  --gris-50:  #F4F6FA;
  --gris-100: #EAEFF6;
  --gris-200: #D7DFEA;
  --gris-300: #B9C6DC;
  --gris-400: #8C9BB4;
  /* 2026-09-03: era #62728F. Como --text-3 medía 4.86:1 sobre una tarjeta
     blanca (pasa) pero 4.49:1 sobre el fondo de página --bg #F4F6FA (NO pasa)
     y 4.21:1 sobre --bg-3: hoy ninguna pantalla pone texto terciario ahí, así
     que era una trampa esperando a la primera que lo hiciera. Cuatro pasos más
     oscuro deja las tres superficies claras por encima de AA (4.88 / 5.28 /
     4.57) y a simple vista es el mismo gris. */
  --gris-500: #5E6C88;
  --gris-600: #4A5B7A;
  --gris-800: #22324D;
  --gris-950: #0B1830;

  --verde-500: #1E8E5A;  --verde-700: #176F46;  --verde-300: #30C48D;
  --rojo-500:  #B3261E;  --rojo-300:  #FF6B63;

  /* ==========================================================================
     COLOR POR BURÓ (encargo de Torre, 2026-09-04: "que se aprecie la
     diferencia de color por buró y que al cliente le sea fácil ver los
     avances, usa colores llamativos para lo que queremos resaltar").

     POR QUÉ ESTOS TRES Y NO LOS LOGOS DE LOS BURÓS:
     Equifax, TransUnion y Experian son marcas de terceros. Copiar su color
     corporativo exacto en nuestra página sugiere una relación que no existe —
     nosotros disputamos CONTRA ellos. Así que se toma el FAMILIAR de cada uno
     (rojo, turquesa, violeta), que es lo que el cliente ya asocia y lo que
     hace que las tres columnas se distingan de un vistazo, sin apropiarse de
     ninguna identidad ajena.

     POR QUÉ NO CHOCAN CON LA MARCA: oro y azul ya tienen significado fijo en
     este sitio (oro = crédito, azul = capital). Ninguno de los tres es oro ni
     es el azul de capital: rojo, turquesa y violeta caen en tres zonas del
     círculo que la marca tiene libres, así que aparecen SIEMPRE dentro de una
     tarjeta de resultados y nunca compiten con un botón.

     CONTRASTE — MEDIDO en el DOM real con preview/v5-contraste.js (no
     estimado a mano: los valores se leen del estilo computado sobre la
     superficie donde de verdad vive la cifra, que es la tarjeta --bg-2):
       tema claro (tarjeta #FFFFFF)   tema oscuro (tarjeta #0F1F3A)
       eq  #B3261E   6.54:1            #FF8A80   7.20:1
       tu  #0E6E62   6.13:1            #37D9C2   9.29:1
       ex  #6D28D9   7.10:1            #C0AAFF   8.17:1
     Los seis pasan AA como TEXTO NORMAL (4.5:1), no solo como texto grande.

     Y LO QUE NO ES NEGOCIABLE: el color es refuerzo, nunca el dato. Cada cifra
     lleva el nombre del buró escrito al lado (results_tarjeta() lo garantiza),
     así que la tarjeta se lee igual en blanco y negro. WCAG 1.4.1.
     ========================================================================== */
  --buro-eq: #B3261E;   /* Equifax    — carmín  */
  --buro-tu: #0E6E62;   /* TransUnion — turquesa hondo */
  --buro-ex: #6D28D9;   /* Experian   — violeta */
  --buro-otro: var(--gris-600);

  /* LOS CINCO TRAMOS DE LA ESCALA DE PUNTAJE (el medidor por buró de las
     tarjetas de resultado, v6). Rampa rojo -> oro -> verde, que es como se
     lee una escala de crédito en cualquier parte.

     SON DECORATIVOS Y ESO ES DELIBERADO: el valor va escrito en texto al lado
     (el puntaje, y la etiqueta del rango), así que el color no carga ningún
     dato — WCAG 1.4.1 otra vez. Aun así están definidos en los DOS temas, con
     luminancias distintas, porque un arco que se pierde contra el fondo
     tampoco decora: no se ve. */
  --rango-1: #B3261E;   /* 300-499  Muy bajo  */
  --rango-2: #D07A00;   /* 500-579  Bajo      */
  --rango-3: #FFAB00;   /* 580-669  Regular   */
  --rango-4: #47B37E;   /* 670-739  Bueno     */
  --rango-5: #1E8E5A;   /* 740-850  Muy bueno */

  /* ==========================================================================
     2. TIPOGRAFÍA
     Display: Sora (600/700/800). Cuerpo/UI: Manrope (400–700), con cifras
     tabulares para tablas y KPIs. Las dos son OFL y se auto-alojan.
     Respaldo: Segoe UI Variable / Segoe UI en Windows, system-ui en el resto.
     ========================================================================== */
  --font-display: "Sora", "Segoe UI Variable Display", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-body:    "Manrope", "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-mono:    ui-monospace, "Cascadia Mono", Consolas, "SF Mono", monospace;

  /* Escala fluida, una sola para el sitio y el panel.
     ------------------------------------------------------------------------
     RECALIBRADA EL 2026-09-04 (v5). La v4 había encogido el texto: medido en
     Chrome a 1440px contra el sitio en vivo, el cuerpo bajaba de 17.6 a 16.96
     px y la interlínea de 1.65 a 1.6, mientras el titular subía de 62.4 a
     73.6. Resultado: menos texto legible y más titular — exactamente el
     "todo se ve muy apiñado" que reportó Torre.

     La regla de esta escala, y no se negocia: LOS NÚMEROS DE PRODUCCIÓN SON EL
     SUELO, NUNCA EL TECHO. Producción usaba --step--1 … --step-3; cada peldaño
     de aquí queda POR ENCIMA de su equivalente en los cinco anchos medidos
     (390 / 768 / 1024 / 1440 / 1920), salvo el titular, que es el único que
     BAJA a propósito para no comerse la página.

     Medido (px), producción -> v5:
       cuerpo  --t-0   16.18/17.12/17.60/17.60/17.60  ->  16.73/17.75/18.24/18.24/18.24
       lead    --t-1   19.55/21.44/22.72/23.20/23.20  ->  20.27/22.27/23.56/24.00/24.00
       h3 rama --t-2   26.26/31.55/35.14/36.80/36.80  ->  27.00/32.07/35.50/37.44/37.44
       h2      --t-3   26.26/31.55/35.14/36.80/36.80  ->  28.64/34.69/38.40/38.40/38.40
       h1 hero --t-5   35.70/47.04/54.72/62.40/62.40  ->  40.53/49.41/55.42/64.00/64.00
     ------------------------------------------------------------------------ */
  --t--2: clamp(.82rem,  .80rem + .12vw, .88rem);
  --t--1: clamp(.94rem,  .90rem + .20vw, 1.02rem);
  --t-0:  clamp(1.04rem,  .98rem + .27vw, 1.14rem);
  --t-1:  clamp(1.20rem, 1.14rem + .52vw, 1.50rem);
  --t-2:  clamp(1.45rem, 1.36rem + 1.34vw, 2.34rem);
  --t-3:  clamp(1.72rem, 1.40rem + 1.60vw, 2.40rem);
  /* El h1 de las páginas interiores (.hero-mid: crédito, proceso). Medido:
     36.17 / 47.51 / 55.20 / 62.40 / 62.40 px — por encima de producción en los
     cinco anchos y con el mismo techo que ella. */
  --t-4:  clamp(2.20rem, 1.53rem + 3.01vw, 3.90rem);
  --t-5:  clamp(2.10rem, 1.96rem + 2.35vw, 4.00rem);

  --lh-tight: 1.06;
  --lh-snug:  1.30;
  /* 1.68, por encima del 1.65 de producción. La interlínea es la mitad de la
     sensación de "aire" en un párrafo; bajarla fue el otro error de la v4. */
  --lh-body:  1.68;

  --track-display: -.03em;
  --track-caps:     .14em;

  /* ==========================================================================
     3. TOKENS DE ROL — lo que consumen los componentes. Tema CLARO en :root.
     ========================================================================== */

  /* superficies */
  --bg:        var(--gris-50);
  --bg-2:      #FFFFFF;
  --bg-3:      var(--gris-100);
  --bg-raise:  #FFFFFF;

  /* bandas de marca: hero de inicio, hero reducido y pie. Son medianoche EN
     AMBOS TEMAS a propósito — es el momento "oro sobre medianoche" que hace
     memorable la marca, y resuelve que el emblema no se pierda. Si algún día
     se decide que sigan al tema, se cambian solo estas cinco. */
  --band-bg:     var(--noche-950);
  --band-bg-2:   var(--noche-900);
  --band-text:   #EAF0FA;
  --band-text-2: var(--gris-300);
  --band-line:   rgba(255,255,255,.10);

  /* filetes */
  --line:        rgba(11,24,48,.12);
  --line-2:      rgba(11,24,48,.07);
  --line-strong: #7F8FAA;   /* borde de controles: >=3:1 sobre blanco (WCAG 1.4.11) */

  /* tinta */
  --text:    var(--gris-950);
  --text-2:  var(--gris-600);
  --text-3:  var(--gris-500);
  --text-inverse: #FFFFFF;

  /* Acento de marca. REGLA DE COLOR CON SIGNIFICADO:
     ORO  = reparación de crédito / acción primaria
     AZUL = capital de negocio / acción secundaria
     El visitante lo aprende en la portada y esa lectura se sostiene en
     proceso.php, credito.php y solicitar.php. */
  --accent:        var(--oro-500);
  --accent-hi:     var(--oro-300);
  --accent-lo:     var(--oro-600);
  --accent-text:   var(--oro-800);
  --accent-soft:   rgba(255,171,0,.12);
  --on-accent:     #24160A;

  --accent-2:      var(--azul-600);
  --accent-2-hi:   var(--azul-400);
  --accent-2-text: #0A57B4;
  --accent-2-soft: rgba(11,108,219,.10);
  --on-accent-2:   #FFFFFF;

  /* semánticos */
  --ok:   var(--verde-500);  --ok-text:   var(--verde-700);  --ok-soft:   #E6F5EC;
  --err:  var(--rojo-500);   --err-text:  var(--rojo-500);   --err-soft:  #FBEAEA;
  --warn: var(--oro-500);    --warn-text: var(--oro-800);    --warn-soft: #FFF3D6;
  --info: var(--azul-600);   --info-text: #0A57B4;           --info-soft: #E6F0FC;

  /* Foco: oro en ambos temas, con halo exterior para que se vea sobre
     cualquier fondo (también sobre el propio botón dorado). */
  /* -------------------------------------------------------------------------
     EL ANILLO DE FOCO — REHECHO EL 2026-09-04 (v5), FALLO REAL DEL QA.

     Antes eran DOS trazos: 3px del color de fondo y 3px de oro. Sobre el botón
     dorado eso es oro sobre oro: el anillo desaparecía justo en el botón más
     importante del sitio ("Agenda tu consulta"), y quien navega con Tab no veía
     dónde estaba parado. Medido: --oro-500 #FFAB00 contra el fondo de página
     #F4F6FA da 1.86:1, y contra el propio botón dorado, 1:1. Muy por debajo del
     3:1 que pide WCAG 2.2 SC 2.4.11.

     Ahora son TRES trazos, y el orden importa:
        2px blanco   -> separa el anillo del elemento, sea cual sea su color
        3px oro      -> la marca; es el trazo que se ve
        2px medianoche -> lo separa de la página

     Por qué funciona en TODAS las superficies del sitio (medido con
     preview/v5-contraste.js, no supuesto):
                                 blanco vs. ella   medianoche vs. ella
       página clara #F4F6FA           1.08 (*)            17.07  PASA
       tarjeta blanca #FFFFFF         1.00 (*)            18.47  PASA
       botón dorado #FFAB00           1.90 (*)             9.74  PASA
       banda medianoche #08132A      18.47  PASA           1.00 (*)
       página oscura #08132A         18.47  PASA           1.00 (*)
     (*) en cada superficie hay AL MENOS UN trazo por encima de 3:1, y los dos
     trazos contrastan entre sí a 18.47:1, que es lo que hace que el anillo se
     lea como una figura y no como un borrón. Ninguna superficie del sitio deja
     los dos trazos por debajo del umbral a la vez.
     ------------------------------------------------------------------------- */
  --focus-ring:      0 0 0 2px #FFFFFF, 0 0 0 5px var(--oro-500), 0 0 0 7px var(--noche-950);
  /* Sobre la banda de marca se invierte el sándwich: medianoche pegado al
     elemento y blanco por fuera, que es el que contrasta contra el fondo de
     noche. Mismo grosor, misma lectura. */
  --focus-ring-band: 0 0 0 2px var(--noche-950), 0 0 0 5px var(--oro-400), 0 0 0 7px #FFFFFF;

  /* Sombras tintadas de medianoche, no de negro. El resplandor dorado es
     exclusivo del botón primario: ningún otro elemento lo lleva. */
  --shadow-1: 0 1px 2px rgba(11,24,48,.06), 0 4px 12px rgba(11,24,48,.06);
  --shadow-2: 0 2px 6px rgba(11,24,48,.08), 0 14px 32px rgba(11,24,48,.12);
  --shadow-3: 0 6px 14px rgba(11,24,48,.10), 0 28px 64px rgba(11,24,48,.18);
  --glow-accent: 0 6px 20px rgba(255,171,0,.30);

  /* ==========================================================================
     4. ESPACIADO, MEDIDAS, RADIOS
     ========================================================================== */
  --s-1: .25rem;  --s-2: .5rem;  --s-3: .75rem;  --s-4: 1.15rem;
  --s-5: 1.6rem;  --s-6: 2.25rem; --s-7: 3.25rem; --s-8: 4.25rem;
  /* v5: el aire entre secciones y dentro de las tarjetas sube ~10%. Torre
     pidió que se sintiera MÁS aireado que producción, nunca más apretado, y
     subir la tipografía sin subir el espacio habría hecho justo lo contrario. */
  --s-section: clamp(4rem, 8.5vw, 7.5rem);
  --s-block:   clamp(1.65rem, 4.2vw, 2.75rem);

  --frame:       1180px;
  --frame-panel: 1320px;
  /* 60ch, no 62: con el cuerpo a 18.24px la medida de 62ch se iba a 690px, por
     encima de los ~75 caracteres donde la lectura empieza a costar. */
  --measure:     60ch;
  /* El margen lateral en móvil de producción eran 20px; la v4 lo bajó a 16 y
     el texto quedó pegado al borde. Aquí queda en 18.4px a 390 y 36 en
     escritorio. */
  --gutter:      clamp(1.15rem, 4.2vw, 2.25rem);

  /* Un radio por función. Hoy convivían 8, 10, 12, 14, 16, 20 y 999px. */
  --r-ctl:  10px;   /* TODO lo que se pulsa: botones, inputs, selects, tabs */
  --r-card: 16px;   /* contenedores */
  --r-hero: 24px;   /* banda CTA, tarjetas del hero */
  --r-pill: 999px;  /* chips, badges, interruptor de idioma */

  /* Objetivos táctiles. Nunca por debajo de --tap. */
  --tap:    44px;
  --tap-lg: 48px;

  /* ==========================================================================
     5. MOVIMIENTO
     Se anima transform y opacity, nunca layout; nada en bucle infinito.
     ========================================================================== */
  --ease-out:    cubic-bezier(.2,.8,.2,1);
  --ease-spring: cubic-bezier(.22,1.15,.36,1);
  --dur-1: 150ms;
  --dur-2: 260ms;
  --dur-3: 600ms;
  /* El armado del logo del hero: 12 cuñas de .85s escalonadas cada 60ms. */
  --dur-armado: 850ms;

  color-scheme: light;
}

/* ============================================================================
   TEMA OSCURO por preferencia del sistema (no gana a data-theme="light").
   ============================================================================ */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:        var(--noche-950);
    --bg-2:      var(--noche-900);
    --bg-3:      var(--noche-800);
    --bg-raise:  var(--noche-800);

    --line:        rgba(255,255,255,.10);
    --line-2:      rgba(255,255,255,.06);
    --line-strong: #5F7090;

    --text:    #EAF0FA;
    --text-2:  #A5B3CC;
    --text-3:  #7E8DA8;
    --text-inverse: var(--noche-950);

    --accent-text:   var(--oro-400);
    --accent-soft:   rgba(255,171,0,.14);
    --accent-2:      var(--azul-500);
    --accent-2-text: var(--azul-400);
    --accent-2-soft: rgba(46,144,255,.16);
    --on-accent-2:   #04203E;

    --ok:  var(--verde-300);  --ok-text:  var(--verde-300);  --ok-soft:  rgba(48,196,141,.14);

    /* Los tres burós sobre medianoche. Mismo papel, misma familia de tono,
       subidos de luz hasta pasar AA sobre --bg-2 (#0F1F3A). */
    --buro-eq: #FF8A80;
    --buro-tu: #37D9C2;
    --buro-ex: #C0AAFF;
    --buro-otro: var(--gris-300);
    /* Los cinco tramos de la escala, subidos de luz para el fondo medianoche. */
    --rango-1: #FF6B63;  --rango-2: #FFA93D;  --rango-3: #FFD469;
    --rango-4: #58D8A6;  --rango-5: #30C48D;
    --err: var(--rojo-300);   --err-text: var(--rojo-300);   --err-soft: rgba(255,107,99,.14);
    --warn-text: var(--oro-400);  --warn-soft: rgba(255,171,0,.14);
    --info: var(--azul-500);  --info-text: var(--azul-400);  --info-soft: rgba(46,144,255,.14);

    --shadow-1: 0 1px 2px rgba(0,0,0,.30), 0 4px 12px rgba(0,0,0,.30);
    --shadow-2: 0 2px 6px rgba(0,0,0,.35), 0 14px 32px rgba(0,0,0,.45);
    --shadow-3: 0 6px 14px rgba(0,0,0,.40), 0 28px 64px rgba(0,0,0,.60);

    color-scheme: dark;
  }
}

/* Elección explícita del usuario: gana en las dos direcciones. */
:root[data-theme="dark"] {
  --bg:        var(--noche-950);
  --bg-2:      var(--noche-900);
  --bg-3:      var(--noche-800);
  --bg-raise:  var(--noche-800);
  --line:        rgba(255,255,255,.10);
  --line-2:      rgba(255,255,255,.06);
  --line-strong: #5F7090;
  --text:    #EAF0FA;
  --text-2:  #A5B3CC;
  --text-3:  #7E8DA8;
  --text-inverse: var(--noche-950);
  --accent-text:   var(--oro-400);
  --accent-soft:   rgba(255,171,0,.14);
  --accent-2:      var(--azul-500);
  --accent-2-text: var(--azul-400);
  --accent-2-soft: rgba(46,144,255,.16);
  --on-accent-2:   #04203E;
  --ok:  var(--verde-300);  --ok-text:  var(--verde-300);  --ok-soft:  rgba(48,196,141,.14);

  /* Los tres burós sobre medianoche (elección explícita del usuario). */
  --buro-eq: #FF8A80;
  --buro-tu: #37D9C2;
  --buro-ex: #C0AAFF;
  --buro-otro: var(--gris-300);
    /* Los cinco tramos de la escala, subidos de luz para el fondo medianoche. */
    --rango-1: #FF6B63;  --rango-2: #FFA93D;  --rango-3: #FFD469;
    --rango-4: #58D8A6;  --rango-5: #30C48D;
  --err: var(--rojo-300);   --err-text: var(--rojo-300);   --err-soft: rgba(255,107,99,.14);
  --warn-text: var(--oro-400);  --warn-soft: rgba(255,171,0,.14);
  --info: var(--azul-500);  --info-text: var(--azul-400);  --info-soft: rgba(46,144,255,.14);
  --shadow-1: 0 1px 2px rgba(0,0,0,.30), 0 4px 12px rgba(0,0,0,.30);
  --shadow-2: 0 2px 6px rgba(0,0,0,.35), 0 14px 32px rgba(0,0,0,.45);
  --shadow-3: 0 6px 14px rgba(0,0,0,.40), 0 28px 64px rgba(0,0,0,.60);
  color-scheme: dark;
}

/* ============================================================================
   6. FUENTES AUTO-ALOJADAS

   PENDIENTE PARA EL DESPLIEGUE: subir Sora-Variable.woff2 y
   Manrope-Variable.woff2 a public_html/assets/fonts/ y DESCOMENTAR el bloque
   de abajo. Los archivos NO viajan en este paquete: no se descargan fuentes
   sin autorización. Mientras siga comentado, el sistema cae a Segoe UI
   Variable / Segoe UI / system-ui, que es un respaldo válido — el diseño no
   depende de la fuente para leerse ni para pasar AA.

   Cómo se preparan: Sora y Manrope, versión variable, licencia OFL. Los .ttf
   de sus repositorios oficiales se convierten a .woff2 con woff2_compress o
   pyftsubset --flavor=woff2, subconjunto latin + latin-ext.
   Peso esperado: Sora ~45 KB, Manrope ~40 KB.
   Con font-display:swap el texto sale en Segoe UI mientras la fuente baja.
   ============================================================================ */
/*
@font-face {
  font-family: "Sora";
  src: url("../fonts/Sora-Variable.woff2") format("woff2");
  font-weight: 300 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Manrope";
  src: url("../fonts/Manrope-Variable.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}
*/

/* ============================================================================
   7. BASE
   ============================================================================ */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--t-0);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Móvil primero: ninguna decoración puede ensanchar el documento. */
  overflow-x: hidden;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: var(--track-display);
  line-height: var(--lh-tight);
  text-wrap: balance;
  margin: 0;
  color: var(--text);
}
h3 { line-height: var(--lh-snug); }
h4 { font-family: var(--font-body); font-weight: 700; line-height: var(--lh-snug); margin: 0; }

p { margin: 0 0 var(--s-4); }

a { color: var(--accent-2-text); text-underline-offset: .15em; transition: color var(--dur-1) var(--ease-out); }
/* EL HOVER DE ENLACE DE TODA LA VIDA — restituido el 2026-09-04 (v5).
   Producción lo tenía en style.css:60 (a:hover { color: var(--color-navy) })
   y la v4 lo perdió: un enlace de texto suelto no cambiaba nada al pasar el
   ratón. Aquí oscurece un paso y se subraya, que además ayuda a quien no
   distingue el azul del texto. Los enlaces que ya son un componente con su
   propio estado (.btn, .link, .brand, .second, .site-foot) lo neutralizan
   más abajo con su propia regla.

   El color de llegada es --accent-text, no un azul más oscuro: --accent-text
   ya está resuelto y medido en LOS DOS TEMAS (--oro-800 sobre claro, 5.9:1;
   --oro-400 sobre medianoche, 9.7:1). Un azul oscuro habría pasado sobre
   blanco y muerto sobre el fondo de noche — el error que este sistema vino a
   cerrar. Además el enlace pasa de azul a oro, que es la marca. */
a:hover { color: var(--accent-text); text-decoration: underline; }
.band a:hover, .site-foot a:hover { color: var(--oro-400); }
a.btn:hover, a.brand:hover, .site-nav a:hover, .site-foot ul a:hover,
.branch h3 a:hover, .second:hover, .elector-op:hover, .opt:hover, .stage-link:hover {
  text-decoration: none;
}

img, svg, video { max-width: 100%; }
/* Si una <img> lleva width/height como atributo (que debe llevarlos, para que
   el navegador reserve el hueco y la página no salte), SIN height:auto el
   atributo gana y la imagen sale deformada. Pasó el 2026-08-12 en proceso.php:
   las ilustraciones quedaron de 248x880 y el QR se estiró a 220x512 — un QR
   deformado puede dejar de escanearse. Esta regla lo cierra de raíz. */
img { height: auto; }

/* Cifras tabulares donde se comparan números. */
.tnum, table, .kpi, .delta .n { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }

/* Foco visible, siempre, igual en las dos apps. */
:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--r-ctl); }
.band :focus-visible, .site-foot :focus-visible { box-shadow: var(--focus-ring-band); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.wrap { width: min(var(--frame), 100% - 2 * var(--gutter)); margin-inline: auto; }

.eyebrow {
  font: 700 var(--t--1) var(--font-body);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--accent-text); margin: 0 0 var(--s-3);
}
.eyebrow a { color: inherit; }
.band .eyebrow { color: var(--oro-400); }

.lead { font-size: var(--t-1); color: var(--text-2); max-width: var(--measure); }
.band .lead { color: var(--band-text-2); }

.grad {
  background: linear-gradient(100deg, var(--oro-300), var(--oro-500) 60%, var(--oro-600));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

.band { background: var(--band-bg); color: var(--band-text); }
.band h1, .band h2, .band h3, .band h4 { color: var(--band-text); }

/* ============================================================================
   8. CHROME COMPARTIDO — cabecera, pie, marca, botón, chip, badge, campo.
   Idéntico en el sitio público y en el portal. No duplicar en otra hoja.
   ============================================================================ */

/* ---------- la marca ----------
   EL LOGO ES EL ARCHIVO DE TORRE: images/logo.webp, sin retocar. Decisión
   suya del 2026-09-03.

   LA MEDALLA. El logo es oro + azul sobre fondo transparente, y medido a 44px
   (preview/logo-contraste.js, Chrome decodifica el WebP y compone cada píxel):

     tinta                 % área   sobre barra clara   sobre medianoche
     oro #FDAB02/#F7A603    ~28%      1.76 / 1.86         9.69 / 9.17
     azul #025DD8/#0176EC   ~13%      5.46 / 4.05         3.13 / 4.22
     azul hondo #034DC3      ~3%      6.80                2.51

   El oro —la masa que dibuja la forma— muere sobre claro y brilla sobre
   medianoche; los azules hacen lo contrario. Ningún fondo plano deja las dos
   masas sobre 3:1 a la vez: exigirle 3:1 al oro pide luminancia <= 0.134 y
   exigírselo al azul hondo pide >= 0.378. No hay intersección posible.

   Por eso el logo no se apoya nunca en la barra: se apoya en su propia
   medalla medianoche, idéntica en los dos temas y en las once pantallas. Así
   el oro trabaja siempre a 8-11:1; la medalla se recorta a 16.4:1 contra la
   barra clara; y contra la barra oscura la separa el filete de oro (9.7:1).
   Es, además, la moneda de "oro sobre medianoche" — la misma que llueve en
   proceso.php.

   No se resuelve por el logo (no se toca) ni por un drop-shadow de contorno:
   un contorno claro alrededor de un dibujo multicolor lo ensucia a 44px, y el
   halo se come el aro dorado, que es justo lo que hay que conservar. */
.brand {
  display: inline-flex; align-items: center; gap: .6rem;
  text-decoration: none; color: var(--text); min-height: var(--tap);
}
.brand-medalla {
  width: var(--tap); height: var(--tap); flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  /* position + overflow: los pide el barrido de luz de abajo. El recorte es
     redondo, así que la luz entra y sale por el borde de la medalla, no por
     una caja cuadrada invisible. */
  position: relative; overflow: hidden;
  background: radial-gradient(circle at 50% 34%, var(--noche-800), var(--noche-950) 74%);
  /* El filete de oro es lo que separa la medalla de la barra medianoche;
     sobre barra clara la separa el propio medianoche a 16.4:1. */
  box-shadow: 0 0 0 1px rgba(255,171,0,.55), 0 1px 3px rgba(0,0,0,.35);
  /* LA ENTRADA DE LA MARCA (brand-logo-in). Estaba en style.css en producción
     y la v3 la perdió al mover la marca a este archivo; Torre pidió que
     volviera (2026-09-04). Vuelve con sus mismos 0.7s ease-out.

     Vive AQUÍ y no en style.css a propósito, y esto es una decisión, no un
     descuido: en producción .brand se estilaba en style.css, que solo cargan
     las pantallas del portal y del panel — la portada, crédito, proceso,
     privacidad y empezar cargan tokens.css + home.css y NUNCA vieron esta
     animación. Al vivir en tokens.css, que lo carga todo, la entrada de la
     marca es por fin la misma en las ONCE pantallas, que es justo lo que pide
     el encargo. El keyframe es el mismo; solo cambió de casa con su selector. */
  animation: brand-logo-in .7s ease-out both;
}
@keyframes brand-logo-in {
  from { opacity: 0; transform: translateY(-4px) scale(.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
/* UN SOLO BARRIDO DE LUZ (brand-shine), 0.9s después de cargar y nunca más.
   Es el "sigue viva" de la marca sin un bucle que compita con la pantalla que
   el visitante vino a leer. Producción lo pasaba por .brand entero (logo +
   nombre) con overflow:hidden en el enlace; aquí barre solo la medalla, que
   es la pieza de marca — así el nombre de la compañía no queda dentro de un
   contenedor recortado, que era lo que obligaba a .brand a llevar
   overflow:hidden y podía cortarle la cola a una tilde. */
.brand-medalla::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 40%, rgba(255,255,255,.35) 50%, transparent 60%);
  transform: translateX(-120%);
  animation: brand-shine 1.6s ease-in-out .9s 1;
}
@keyframes brand-shine { to { transform: translateX(120%); } }
/* Movimiento reducido: la marca ya está puesta y la luz no pasa. Se apagan
   las dos de forma explícita — la regla global de más abajo las llevaría a su
   último cuadro, y en el barrido ese último cuadro es un destello de un solo
   fotograma, exactamente lo que evita quien pide menos movimiento. */
@media (prefers-reduced-motion: reduce) {
  .brand-medalla { animation: none; opacity: 1; transform: none; }
  .brand-medalla::after { animation: none; display: none; }
}
/* 91%: deja 2px de medianoche alrededor del dibujo, que es lo que hace que se
   lea como medalla y no como un logo recortado. object-fit contain + fuente
   cuadrada: la proporción no se toca. */
.brand-medalla img { width: 91%; height: 91%; object-fit: contain; display: block; }
.brand:focus-visible .brand-medalla { box-shadow: 0 0 0 1px rgba(255,171,0,.55), 0 0 0 4px var(--accent-soft); }
.brand .name { font: 700 1.02rem var(--font-display); letter-spacing: -.02em; white-space: nowrap; }
.brand .name b { color: var(--accent-text); font-weight: 800; }
.band .brand, .site-foot .brand { color: var(--band-text); }
.band .brand .name b, .site-foot .brand .name b { color: var(--oro-400); }

/* ---------- botones: UN componente para el sitio y el portal ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  min-height: var(--tap-lg); padding: 0 1.35rem;
  border-radius: var(--r-ctl); border: 1px solid transparent;
  font: 600 var(--t-0) var(--font-body); text-decoration: none; cursor: pointer;
  color: var(--text); background: var(--bg-2);
  transition: transform var(--dur-1) var(--ease-out),
              box-shadow var(--dur-1) var(--ease-out),
              background var(--dur-1), border-color var(--dur-1);
}
/* -2px, no -1: es el levantón que tenían .cta, .pill-gold, .l-btn-primary y
   .book en producción, y a -1px casi no se nota en un portátil. */
.btn:hover { transform: translateY(-2px); }
.btn svg { flex: none; transition: translate var(--dur-1) var(--ease-out); }
/* LA FLECHA QUE AVANZA — restituida el 2026-09-04 (v5).
   Era home.css:219 (.pill-gold:hover svg { translate: 3px 0 }) y se perdió al
   renombrar .pill-gold -> .btn.btn-oro. Es un detalle diminuto y es de los que
   más se sienten: el botón contesta al ratón, no solo se ilumina. */
.btn:hover svg { translate: 3px 0; }
.btn-oro {
  color: var(--on-accent);
  background: linear-gradient(135deg, var(--oro-300), var(--oro-500) 55%, var(--oro-600));
  box-shadow: var(--glow-accent);
}
.btn-oro:hover { color: var(--on-accent); box-shadow: 0 10px 26px rgba(255,171,0,.42); }
.btn-azul { color: var(--on-accent-2); background: var(--accent-2); box-shadow: var(--shadow-1); }
.btn-azul:hover { color: var(--on-accent-2); }
.btn-ghost { border-color: var(--line-strong); background: transparent; color: var(--text); }
.btn-ghost:hover { background: var(--accent-soft); border-color: var(--accent); }
.band .btn-ghost, .site-foot .btn-ghost { color: var(--band-text); border-color: rgba(255,255,255,.35); }
.btn-peligro { background: var(--err); color: #FFF; }
.btn-peligro:hover { color: #FFF; }
/* ---------- EL BOTÓN GANCHO ----------
   Encargo de Torre (2026-09-04): "créame un botón que induzca al cliente a
   inscribirse, que al cliquear diga 'la solución es tan fácil como cliqueando
   aquí'". Es el botón grande de credito.php, y solo aparece ahí.

   Dos renglones dentro del mismo objetivo táctil: la invitación arriba, y
   debajo, en letra menor, QUÉ pasa al pulsarlo. El segundo renglón no es
   adorno — es lo que evita que el clic se sienta una trampa: dice que es sin
   costo y que contesta una persona. Sin él, un botón así de entusiasta en una
   página de crédito se lee como publicidad.

   NO PROMETE NADA. Habla de la facilidad de EMPEZAR, no de resultados: ni un
   punto, ni una fecha, ni un "te arreglamos el crédito". Esa raya es CROA y no
   se cruza por diseño.

   El texto se centra pero se alinea a la izquierda dentro del botón: dos
   renglones centrados de distinto largo hacen un triángulo y se leen peor. */
.btn-gancho {
  flex-direction: row; align-items: center; text-align: left;
  min-height: 4.6rem; padding: 1rem 1.6rem;
  gap: 1rem; max-width: 100%;
}
.btn-gancho > span { display: block; }
.btn-gancho-l1 {
  font: 800 var(--t-1) var(--font-display); letter-spacing: var(--track-display);
  line-height: 1.2;
}
.btn-gancho-l2 {
  font: 600 var(--t--1) var(--font-body); line-height: 1.35;
  opacity: .82; margin-top: .25rem;
}
.btn-gancho > span:first-child { flex: 1 1 auto; }
.btn-gancho-flecha { flex: none; align-self: center; }
/* En móvil el botón ocupa el ancho: es la acción de la página y no tiene por
   qué competir por el sitio con nada. */
@media (max-width: 560px) {
  .btn-gancho { width: 100%; padding: .95rem 1.15rem; }
}

/* --tap, nunca menos: es el mínimo que acierta un pulgar. */
.btn-sm { min-height: var(--tap); padding: 0 1rem; font-size: var(--t--1); }
.btn-icon { min-width: var(--tap); padding: 0; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; }

/* Nombres viejos de style.css, para que ninguna pantalla del panel se quede
   sin botón mientras el panel no se rediseña (no se toca en este encargo). */
.btn-primary { color: var(--on-accent); background: linear-gradient(135deg, var(--oro-300), var(--oro-500) 55%, var(--oro-600)); box-shadow: var(--glow-accent); }
.btn-primary:hover { color: var(--on-accent); }
.btn-secondary { color: var(--on-accent-2); background: var(--accent-2); box-shadow: var(--shadow-1); }
.btn-secondary:hover { color: var(--on-accent-2); }
.btn-outline { border-color: var(--line-strong); background: transparent; color: var(--text); }
.btn-outline:hover { background: var(--accent-soft); border-color: var(--accent); }
.btn-danger { background: var(--err); color: #FFF; }
.btn-danger:hover { color: #FFF; }

/* ---------------------------------------------------------------------------
   EL FOCO DEL BOTÓN, DESPUÉS DE TODOS LOS BOTONES. Y ES OBLIGATORIO QUE VAYA
   AQUÍ ABAJO.

   La regla genérica `:focus-visible { box-shadow: var(--focus-ring) }` vive en
   la capa BASE, cientos de líneas más arriba. `.btn-oro` (misma especificidad,
   0-1-0) declara `box-shadow: var(--glow-accent)` DESPUÉS, así que ganaba por
   orden de aparición y BORRABA el anillo de foco entero. Medido: el botón
   "Agenda tu consulta" enfocado con Tab devolvía
   `box-shadow: rgba(255,171,0,.3) 0 6px 20px` — su resplandor, y nada más.

   No era que el anillo tuviera poco contraste (que también, y por eso se
   rehizo --focus-ring): es que en los botones dorados NO EXISTÍA. Este es el
   fallo que encontró el QA, en su forma real.

   Aquí el anillo se declara al final y se le SUMA el resplandor del botón, en
   este orden: primero los tres trazos del anillo, después el resplandor. Un
   box-shadow pinta la primera sombra encima, así que el anillo queda por
   delante y no se lo come el halo dorado. */
.btn:focus-visible { box-shadow: var(--focus-ring); }
.btn-oro:focus-visible,
.btn-primary:focus-visible { box-shadow: var(--focus-ring), var(--glow-accent); }
.band .btn:focus-visible,
.site-foot .btn:focus-visible { box-shadow: var(--focus-ring-band); }
.band .btn-oro:focus-visible,
.site-foot .btn-oro:focus-visible { box-shadow: var(--focus-ring-band), var(--glow-accent); }

/* ---------- chips y badges ---------- */
.chips { display: flex; flex-wrap: wrap; gap: .5rem; }
.chip {
  display: inline-flex; align-items: center; gap: .5rem; padding: .5rem .9rem;
  border-radius: var(--r-pill); font: 600 var(--t--1) var(--font-body);
  border: 1px solid var(--line); background: var(--bg-2); color: var(--text);
}
/* OPACO, no rgba(255,255,255,.06). Sobre una banda lisa los dos colores son
   EL MISMO píxel; la diferencia aparece cuando hay algo detrás, y en las dos
   bandas de marca lo hay: la fotografía del hero de proceso.php y las monedas
   de la lluvia. Con el chip traslúcido, una moneda dorada pasando por detrás
   levanta el fondo bajo el texto y el contraste se cae ahí donde está — un
   fallo intermitente, que es el peor de encontrar. Medido el 2026-09-03 en
   375px: la moneda se veía a través del chip "Cuota solo si hay fondeo".
   color-mix da exactamente el mismo tono, ya compuesto. */
.band .chip { background: color-mix(in srgb, #FFFFFF 6%, var(--band-bg)); border-color: var(--band-line); color: var(--band-text); }
.chip svg { color: var(--ok); flex: none; }
.band .chip svg { color: var(--verde-300); }

.badge {
  display: inline-flex; align-items: center; gap: .35rem; padding: .25rem .65rem;
  border-radius: var(--r-pill); font: 700 var(--t--2) var(--font-body);
  letter-spacing: .04em; text-transform: uppercase; white-space: nowrap;
}
.badge-info  { background: var(--info-soft); color: var(--info-text); }
.badge-ok    { background: var(--ok-soft);   color: var(--ok-text); }
.badge-warn  { background: var(--warn-soft); color: var(--warn-text); }
.badge-err   { background: var(--err-soft);  color: var(--err-text); }
.badge-muted { background: var(--bg-3);      color: var(--text-2); }

/* ---------- la cabecera única ----------
   68px pegajosa, fondo del tema al 88% con desenfoque y un filete abajo.
   Por debajo de 900px los enlaces pasan a un <details> (sin JavaScript: la
   CSP prohíbe el script en línea, y un menú que no abre es peor que no tener
   menú). */
.site-head {
  position: sticky; top: 0; z-index: 60;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}
.site-head .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); min-height: 68px;
}
.site-nav { display: flex; align-items: center; gap: .25rem; }
.site-nav a.link {
  display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 .85rem;
  border-radius: var(--r-ctl); color: var(--text-2);
  font: 600 var(--t--1) var(--font-body); text-decoration: none;
}
.site-nav a.link:hover, .site-nav a.link[aria-current] { color: var(--text); background: var(--bg-3); }
/* El interruptor de idioma es discreto a propósito (decisión ya tomada en
   home.css): quien entiende la página no necesita verlo, y quien no la
   entiende busca exactamente este control. Contorneado, no dorado: no compite
   con "Agenda tu consulta", que es la acción que importa. */
.site-nav a.lang {
  display: inline-flex; align-items: center; gap: .4rem; min-height: var(--tap); padding: 0 .85rem;
  border-radius: var(--r-pill); border: 1px solid var(--line-strong); color: var(--text-2);
  font: 600 var(--t--1) var(--font-body); text-decoration: none; white-space: nowrap;
}
.site-nav a.lang:hover { border-color: var(--accent); color: var(--accent-text); }
.site-nav a.lang svg { flex: none; opacity: .8; }

.nav-menu { position: relative; display: none; }
.nav-menu summary {
  list-style: none; display: inline-grid; place-items: center;
  min-width: var(--tap); min-height: var(--tap);
  border-radius: var(--r-ctl); border: 1px solid var(--line-strong); cursor: pointer;
  color: var(--text);
}
.nav-menu summary::-webkit-details-marker { display: none; }
.nav-menu .sheet {
  position: absolute; right: 0; top: calc(100% + .5rem); min-width: 240px;
  display: grid; gap: .25rem; padding: .5rem;
  background: var(--bg-raise); border: 1px solid var(--line);
  border-radius: var(--r-card); box-shadow: var(--shadow-2);
}
.nav-menu .sheet a {
  display: flex; align-items: center; min-height: var(--tap); padding: 0 .85rem;
  border-radius: var(--r-ctl); color: var(--text);
  font: 600 var(--t--1) var(--font-body); text-decoration: none;
}
.nav-menu .sheet a:hover { background: var(--bg-3); }

/* La cabecera de las páginas con headerRight (portal del cliente y panel):
   mismo cascarón y mismos tokens; los enlaces son los que ya traía cada
   página. El panel no se rediseña en este encargo. */
.site-head-right { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: .1rem .35rem; }
.site-head-right a {
  display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 .6rem;
  border-radius: var(--r-ctl); color: var(--text-2);
  font: 600 var(--t--1) var(--font-body); text-decoration: none;
}
.site-head-right a:hover { color: var(--text); background: var(--bg-3); }
.site-head-right span { color: var(--text-3); font-size: var(--t--1); padding: 0 .3rem; }

@media (max-width: 900px) {
  /* misma especificidad que la regla base (a.link), si no la base gana */
  .site-nav a.link, .site-nav a.lang { display: none; }
  .nav-menu { display: block; }
  .site-head .btn { min-height: var(--tap); padding: 0 1rem; font-size: var(--t--1); }
  .brand .name { font-size: .94rem; }
}
/* El nombre se esconde SOLO en la barra pegajosa, donde compite por el ancho
   con el botón de agenda y el menú. En el pie y en la pantalla del QR sí cabe,
   y ahí es la única forma de saber de quién es el sitio: si la regla se deja
   suelta (`.brand .name`), el pie de un teléfono de 375 px se queda con un
   emblema huérfano. Medido el 2026-09-02 en la captura 375-claro-solicitar. */
@media (max-width: 420px) { .site-head .brand .name { display: none; } }

/* ---------- el pie único ----------
   Medianoche en ambos temas. Tres columnas: marca + descargo legal completo,
   Servicios, Contacto; y una línea de copyright. El descargo va COMPLETO,
   palabra por palabra: es lo que sostiene las cláusulas de no-garantía del
   contrato, y si el sitio dijera una cosa y el contrato otra, la diferencia
   se leería contra la compañía. */
.site-foot {
  background: var(--band-bg); color: var(--band-text);
  border-top: 1px solid var(--band-line); padding: var(--s-7) 0 var(--s-6);
}
.site-foot .wrap { display: grid; gap: var(--s-6); grid-template-columns: minmax(0,1.7fr) minmax(0,1fr) minmax(0,1fr); }
.site-foot h4 {
  font: 700 var(--t--2) var(--font-body); letter-spacing: var(--track-caps);
  text-transform: uppercase; color: var(--oro-400); margin: 0 0 .8rem;
}
.site-foot p { font-size: var(--t--2); line-height: 1.6; color: var(--band-text-2); margin: .8rem 0 0; max-width: 68ch; }
.site-foot p strong { color: var(--band-text); }
.site-foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .1rem; }
.site-foot ul a {
  display: inline-flex; align-items: center; min-height: var(--tap);
  color: var(--band-text); text-decoration: none; font: 500 var(--t--1) var(--font-body);
}
.site-foot ul a:hover { color: var(--oro-400); }
.site-foot .copy {
  grid-column: 1 / -1; border-top: 1px solid var(--band-line); padding-top: var(--s-4);
  font-size: var(--t--2); color: var(--band-text-2);
  display: flex; flex-wrap: wrap; gap: .2rem 1.5rem; align-items: center;
}
.site-foot .copy a { color: var(--band-text-2); min-height: var(--tap); display: inline-flex; align-items: center; }
.site-foot .copy a:hover { color: var(--oro-400); }
@media (max-width: 820px) { .site-foot .wrap { grid-template-columns: minmax(0,1fr); } }

/* Pie mínimo: portal del cliente y panel. Una línea, sin columnas. */
.site-foot-min {
  background: var(--band-bg); color: var(--band-text-2);
  text-align: center; font-size: var(--t--2); padding: var(--s-5) var(--gutter);
  border-top: 1px solid var(--band-line);
}
.site-foot-min p { margin: 0; }

/* ---------- campos de formulario ----------
   Etiqueta arriba (nunca el placeholder como etiqueta), control de 48px,
   borde --line-strong (>=3:1, WCAG 1.4.11), foco azul con halo de 4px, y
   estados de válido/error marcados con COLOR + ICONO + TEXTO, nunca solo
   con color. */
.field { display: grid; gap: .4rem; margin-bottom: var(--s-4); }
.field label { font: 600 var(--t--1) var(--font-body); color: var(--text); }
.field .hint { font-size: var(--t--2); color: var(--text-2); margin: 0; }
.control { position: relative; }

input[type="text"], input[type="email"], input[type="tel"], input[type="date"],
input[type="number"], input[type="password"], input[type="search"], select, textarea {
  width: 100%; min-height: var(--tap-lg); padding: .6rem .95rem;
  font: 500 var(--t-0) var(--font-body); color: var(--text);
  background: var(--bg-2); border: 1px solid var(--line-strong); border-radius: var(--r-ctl);
  transition: border-color var(--dur-1), box-shadow var(--dur-1);
}
.control input { padding-right: 2.8rem; }
input::placeholder, textarea::placeholder { color: var(--text-3); }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent-2); box-shadow: 0 0 0 4px var(--accent-2-soft);
}
textarea { resize: vertical; min-height: 110px; }
input:disabled, select:disabled, textarea:disabled { background: var(--bg-3); color: var(--text-2); }

.control .mark {
  position: absolute; right: .8rem; top: 50%; translate: 0 -50%;
  width: 22px; height: 22px; display: none; place-items: center; border-radius: 50%;
}
.field[data-state="ok"] .control input { border-color: var(--ok); }
.field[data-state="ok"] .mark-ok { display: grid; color: var(--ok-text); }
.field[data-state="err"] .control input { border-color: var(--err); box-shadow: 0 0 0 4px var(--err-soft); }
.field[data-state="err"] .mark-err { display: grid; color: var(--err-text); }
.field .msg { min-height: 1.2em; font-size: var(--t--2); color: var(--err-text); margin: 0; }
.field[data-state="ok"] .msg { color: var(--ok-text); }

.field-sep {
  display: flex; align-items: center; gap: .8rem; color: var(--text-3);
  font: 600 var(--t--2) var(--font-body); letter-spacing: .1em; text-transform: uppercase;
  margin: .2rem 0 var(--s-4);
}
.field-sep::before, .field-sep::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* Trampa anti-bot: fuera de pantalla, NO display:none (que algunos bots
   detectan y saltan). Se conserva tal cual estaba. */
.hp-field { position: absolute; left: -9999px; top: -9999px; width: 1px; height: 1px; overflow: hidden; }

.btn-row { display: flex; gap: .7rem; flex-wrap: wrap; margin-top: var(--s-4); }

/* ---------- avisos ---------- */
.flash {
  display: flex; gap: .7rem; align-items: flex-start;
  padding: .85rem 1rem; border-radius: var(--r-ctl);
  font-size: var(--t--1); margin-bottom: var(--s-4);
}
.flash svg { flex: none; margin-top: .15rem; }
.flash-ok,  .flash-success { background: var(--ok-soft);   color: var(--ok-text);   border: 1px solid color-mix(in srgb, var(--ok) 35%, transparent); }
.flash-err, .flash-error   { background: var(--err-soft);  color: var(--err-text);  border: 1px solid color-mix(in srgb, var(--err) 35%, transparent); }
.flash-info                { background: var(--info-soft); color: var(--info-text); border: 1px solid color-mix(in srgb, var(--info) 35%, transparent); }
.flash[hidden] { display: none; }

/* ============================================================================
   9. MOVIMIENTO REDUCIDO
   Nadie debería marearse por nuestra dirección de arte. Se corta todo
   movimiento y lo que se anima por transform queda en su ESTADO FINAL (sin
   animation-delay:0 un retraso de .35s dejaría el emblema invisible ese
   tiempo).
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  /* Se apaga el MOVIMIENTO del botón; el cambio de sombra y de color se queda,
     porque es la señal de "esto responde", no el adorno. */
  .btn:hover { transform: none; }
  .btn:hover svg { translate: 0 0; }
}

/* El aviso en vivo de solicitar.php lleva DOS iconos y enseña el que toca.
   Cuando el visitante corrige los campos el aviso pasa de rojo a verde
   (solicitar.js), y un aspa de advertencia sobre fondo verde diría lo
   contrario que el texto. El icono es parte del mensaje, no decoración. */
.flash .ico-ok  { display: none; }
.flash-ok .ico-err, .flash-success .ico-err { display: none; }
.flash-ok .ico-ok,  .flash-success .ico-ok  { display: block; }
