/* ==========================================================================
   ril.css · GENERADO por laravel-simple/_generador/build.mjs
   Une en este orden: tokens → base → marca → componentes → secciones → páginas.
   Cada bloque lleva su cabecera «───── ruta ─────» con el archivo de origen.
   Editable a mano (sigue las mismas reglas: colores solo en la zona de tokens).
   Clases renombradas con «ril-» para no chocar con el CSS actual de ril:
   .alert .btn .container .hero .marquee .media .menu-servicios .section  →  .ril-alert .ril-btn .ril-container .ril-hero .ril-marquee .ril-media .ril-menu-servicios .ril-section
   ========================================================================== */
/* ==========================================================================
   app.css  —  entrada única del CSS (Vite; en Laravel, @vite('resources/css/app.css'))
   El orden de capas lo fija tokens-ril.css con su primera línea:
     @layer tokens, reset, base, layout, components, utilities;
   El orden de los @import solo importa dentro de cada capa.

   Para añadir una pieza: crear su archivo y sumar UNA línea en el _index.css
   de su carpeta. Este archivo no se toca.
   ========================================================================== */

/* base de marca compartida (D3: algún día, submódulo o paquete) */

/* ───── ril/tokens-ril.css ───── */
/* ==========================================================================
   tokens-ril.css  —  marca rIL · v1.6 (borrador) · 11/10/2026
   v1.6  «360°» en móvil, la capa visible de Figma (198,5, a todo el ancho);
         --fs-subp (subpárrafo, 11/16); párrafo de 12 en móvil; pie de móvil más ligero (--fs-closing,
         body-lg 14, small 12, btn-closing 22); paleta «brasa» --ril-glow-* (degradados
         de luz del Presupuestador); cabecera de 56/60 (antes 71/77);
         las animaciones ligadas al scroll (hero, servicios, proyectos, pie)
         no necesitan tokens nuevos.
   v1.5  fidelidad exacta a Figma: la escala fluida va de 402 a 1728 (los dos
         frames); tamaños por rol medidos en Figma (display-2xl/xl/lg, menu,
         cta, h1-lg, eyebrow-*, label, nav, btn-*); cuerpo 18; legales 16/18;
         «360°» decrece (160 → 84); anchos 75/84/87 además del 77; interlineados
         0,88 y 0,95; margen 14/40; cabecera 71/77. Los «a confirmar» de la
         v1.4 se cierran con el valor de Figma.
   v1.4  los tokens son la fuente única de verdad (SSOT): Figma los recibe
         como variables, no al revés. Los PENDIENTE DE DECISIÓN pasan a
         SET · rIL · a confirmar con la propuesta aplicada: --fs-stat 44/74,
         --header-height 56/80, --ls-wider 0,02em, sol del 100 % y del 10 %.
   v1.3  cierre de los SET · FIGMA contra Figma (lienzo «Home»), validado por
         el equipo el 09/10/2026: amarillo y crema de Figma; rango fluido
         390-1920; escala tipográfica nueva (+ display-xl y tamaños de
         botón --fs-btn-*); contenedor de 1920 con márgenes 16-40; radios
         --radius-small y --radius-large; botón con radio de 8 px; degradado
         crema → amarillo; interlineado normal 1,4 → 1,5. Nueva marca
         PENDIENTE DE DECISIÓN.
   v1.2  todo el archivo va en @layer tokens (base.css v3.3); tokens de API
         de .eyebrow; rellenos de feedback --color-*-fill (PENDIENTE DE
         REVISIÓN); fuera --alert-radius (era igual a su fallback).
   v1.1  .theme-dark pasa a .theme-space; el tema sol admite data-theme="sun";
         propuesta de estados de feedback (PENDIENTE DE REVISIÓN).
   Copia de la plantilla tokens.css (v3.3). La NORMA (nombrado, unidades,
   breakpoints, capas, guía de marcas) vive en tokens.css y NO se repite aquí.

   ORIGEN DE LOS VALORES
     Guía de estilo y comunicación de rIL (beta, julio 2026), Presupuestador
     rIL 1.0 (kit_web.py 6.3), que es la aplicación web de la marca ya cerrada,
     y Figma «rIL - Web Design 2026», lienzo «Home» (nodo 3736:2808; frames
     de 1728 y 402 px), leído con Figma MCP desde el terminal. El archivo de
     Figma no tiene variables ni estilos: los valores se midieron en las
     capas y los validó el equipo (09/10/2026).

   MARCAS DE ESTADO (sustituyen a los "TODO" de la plantilla)
     SET · rIL     valor de marca, definitivo.
     SET · FIGMA   valor provisional pendiente de contrastar con Figma.
                   Quedan 0 desde la v1.3.  Buscar:  grep -n "FIGMA" tokens-ril.css
     DEF           valor por defecto de la plantilla, sin tocar.
     DEF · rIL     valor por defecto cambiado con motivo (se indica el motivo).
     SET · rIL · a confirmar   valor aceptado por el equipo y en uso, con
                   confirmación pendiente (se indica qué falta confirmar).
                                               Buscar:  grep -n "a confirmar" tokens-ril.css
     PENDIENTE DE REVISIÓN   propuesta de diseño aún no aprobada por el equipo
                   (estados de feedback y componente .alert de marca-ril.css).
                                               Buscar:  grep -n "PENDIENTE" *.css

   Carga:  tokens-ril.css → fuentes-ril.css → base.css → marca-ril.css
           → components/ → sections/ → pages/
   ========================================================================== */

/* Orden de capas: la misma línea que base.css. Tiene que ir aquí porque este
   archivo se carga primero y el orden lo fija la primera declaración. */
@layer tokens, reset, base, layout, components, utilities;

/* Todo el archivo va en la capa "tokens" (se cierra al final): las reglas de
   tema (background-color, color) pierden frente a cualquier otra capa. Sin
   sangría extra para no mover el archivo entero. */
@layer tokens {


/* ==========================================================================
   2. TOKENS · COLOR
   ========================================================================== */

/* ---- 2.1 PRIMITIVOS ----------------------------------------------------
   QUÉ     paleta de la marca.
   NOMBRE  --color-{palabra}
   VALOR   hex exacto de la guía de marca (#rrggbb). Nunca muestreado de captura.
   REGLA   el nombre comercial ("azul noche") va en el comentario, no en la variable.
   ----------------------------------------------------------------------- */
:root {
  --color-dark:   #000000;  /* SET · rIL   · Negro Eclipse: texto base y fondos oscuros            */
  --color-brand:  #F6A700;  /* SET · rIL   · Amarillo Solar: color principal. Valor de Figma; la
                                             guía beta dice #F7A808 (RGB 247, 168, 8): actualizarla */
  --ril-color-white:  #FFFFFF;  /* SET · rIL   · blanco puro: superficies (tarjetas, campos)           */
  --color-light:  #FBF9F4;  /* SET · rIL   · crema: fondo de página de rIL (ver OVERRIDES). Valor
                                             de Figma; la guía beta dice #F9F8F3                   */
  --color-accent: #EB5C16;  /* SET · rIL   · Naranja Impulso. Uso restringido: avisos y destacados
                                             puntuales, nunca como color de acción               */
}

/* ---- 2.2 SEMÁNTICOS · asignación base (tema claro) ---------------------
   QUÉ     rol de cada color. Es lo que leen los componentes.
   TABLA DE ROLES
     background      fondo de página
     background-alt  fondo de secciones alternas
     surface         contenedores elevados (tarjeta, panel, input)
     text            texto de cuerpo
     heading         titulares (por defecto = text)
     link            enlaces en texto
     primary         acción principal (botón, foco, acento)
     secondary       segunda acción / segunda parada de degradado
     on-primary      texto/icono sobre fondo primary
     focus           anillo de foco
     overlay         velo de modales y menús
     success error warning info   estados de feedback
   rIL: las reasignaciones de marca (fondo crema, enlaces y foco en negro,
   texto negro sobre amarillo) están en OVERRIDES, al final.
   ----------------------------------------------------------------------- */
:root,
.theme-light {
  --color-background:     var(--ril-color-white);   /* DEF · rIL lo cambia a crema en OVERRIDES */
  --color-background-alt: var(--color-light);   /* DEF · rIL lo cambia en OVERRIDES */
  --color-surface:        var(--ril-color-white);   /* DEF */
  --color-text:           var(--color-dark);    /* DEF */
  --color-heading:        var(--color-text);    /* DEF */
  --color-primary:        var(--color-brand);   /* DEF */
  --color-secondary:      var(--color-accent);  /* DEF · ver aviso en 5.1 (degradados) */
  --color-on-primary:     var(--ril-color-white);   /* DEF · rIL lo cambia a negro en OVERRIDES (blanco sobre amarillo: 2,0:1) */
  --color-link:           var(--color-primary); /* DEF · rIL lo cambia a texto en OVERRIDES (amarillo sobre crema: 1,9:1) */
  --color-focus:          var(--color-primary); /* DEF · rIL lo cambia a texto en OVERRIDES */
  --color-overlay:        color-mix(in srgb, var(--color-dark) 60%, transparent); /* DEF */

  /* Feedback: valores con contraste AA sobre blanco y sobre crema.
     PENDIENTE DE REVISIÓN. Propuesta: estos valores son los de TEXTO (AA);
     el relleno de los iconos de .alert se explica en marca-ril.css.
       success  verde algo cálido, para convivir con el amarillo
       error    rojo carmín (tono 353°), lejos del naranja (20°) para no confundirlos
       warning  Naranja Impulso oscurecido: el puro da 3,3:1 sobre crema
       info     neutra: color del texto. La marca la pone el icono amarillo */
  --color-success: #2F7A3B;            /* PENDIENTE DE REVISIÓN · 5,0:1 sobre crema */
  --color-error:   #B42333;            /* PENDIENTE DE REVISIÓN · 6,1:1 sobre crema */
  --color-warning: #BC4A12;            /* PENDIENTE DE REVISIÓN · 4,8:1 sobre crema */
  --color-info:    var(--color-text);  /* PENDIENTE DE REVISIÓN · sin azul fuera de marca */

  /* Cristal (ver 5.2): receta para fondo CLARO. Se reasigna en .theme-space. */
  --glass-bg:        color-mix(in srgb, var(--color-background) 60%, transparent);  /* DEF */
  --glass-bg-strong: color-mix(in srgb, var(--color-background) 82%, transparent);  /* DEF */
  --glass-border:    color-mix(in srgb, var(--color-text) 12%, transparent);        /* DEF */

  color-scheme: light;
}

/* ---- 2.3 SEMÁNTICOS · derivados (se recalculan en cada tema) ----------
   QUÉ     tokens calculados a partir de los de 2.2. Se declaran en TODOS los
           selectores de tema para que se evalúen con los valores de su ámbito.
   REGLA   se tocan solo reasignando el porcentaje o la fórmula; nunca con hex.
   rIL     se añade el tema sol a la lista de selectores (tema propio, ver 2.5).
   ----------------------------------------------------------------------- */
:root,
.theme-light,
.theme-space,
.theme-sun,
[data-theme="sun"] {
  /* texto */
  --color-text-muted:      color-mix(in srgb, var(--color-text) 68%, var(--color-background)); /* DEF · sobre crema ≈ #50504E, 7,7:1 */
  /* bordes */
  --color-border:          color-mix(in srgb, var(--color-text) 16%, var(--color-background)); /* DEF */
  --color-border-strong:   color-mix(in srgb, var(--color-text) 40%, var(--color-background)); /* DEF */
  /* primary */
  --color-primary-hover:   color-mix(in srgb, var(--color-primary) 85%, black);                /* DEF */
  --color-primary-soft:    color-mix(in srgb, var(--color-primary) 12%, var(--color-background)); /* DEF · tinte: hover suave, píldoras, fondos de icono */
  /* enlaces */
  --color-link-hover:      color-mix(in srgb, var(--color-link) 80%, var(--color-text));       /* DEF */
  /* feedback: fondo suave de avisos */
  --color-success-soft:    color-mix(in srgb, var(--color-success) 12%, var(--color-background)); /* DEF */
  --color-error-soft:      color-mix(in srgb, var(--color-error)   12%, var(--color-background)); /* DEF */
  --color-warning-soft:    color-mix(in srgb, var(--color-warning) 12%, var(--color-background)); /* DEF */
  --color-info-soft:       color-mix(in srgb, var(--color-info)    12%, var(--color-background)); /* DEF */
  /* feedback: relleno de iconos (círculo de .alert). Puede diferir del de
     texto: el naranja y el amarillo puros no llegan a AA como texto, pero
     sí sostienen un glifo negro encima. */
  --color-success-fill:    var(--color-success);  /* PENDIENTE DE REVISIÓN */
  --color-error-fill:      var(--color-error);    /* PENDIENTE DE REVISIÓN */
  --color-warning-fill:    var(--color-accent);   /* PENDIENTE DE REVISIÓN · Naranja Impulso puro */
  --color-info-fill:       var(--color-brand);    /* PENDIENTE DE REVISIÓN · Amarillo Solar */
  /* deshabilitado */
  --color-disabled-bg:     color-mix(in srgb, var(--color-text) 8%,  var(--color-background)); /* DEF */
  --color-disabled-text:   color-mix(in srgb, var(--color-text) 40%, var(--color-background)); /* DEF */
  /* sombras: se declaran aquí (y no en 4.5) para que usen el --shadow-color de cada tema */
  --shadow-color:          color-mix(in srgb, var(--color-text) 18%, transparent);             /* DEF */
  --shadow-sm:             0 1px 2px var(--shadow-color);                                      /* DEF */
  --shadow-md:             0 6px 16px -4px var(--shadow-color);                                /* DEF */
  --shadow-lg:             0 20px 40px -12px var(--shadow-color);                              /* DEF */
  /* cristal: sombra según tema (el cristal sobre claro necesita una para despegar) */
  --glass-shadow:          var(--shadow-sm);                                                   /* DEF */
}

/* ---- 2.4 TEMA OSCURO · .theme-space -----------------------------------
   Uso:  <section class="theme-space"> ... </section>
   rIL   fondo Negro Eclipse.
   Reasigna SOLO los semánticos que cambian. Todo lo derivado (2.3) se
   recalcula solo. Para volver a claro dentro de un bloque oscuro: .theme-light.
   ----------------------------------------------------------------------- */
.theme-space {
  --color-background:     var(--color-dark);                                          /* DEF */
  --color-background-alt: color-mix(in srgb, var(--color-dark) 88%, var(--ril-color-white)); /* DEF */
  --color-surface:        color-mix(in srgb, var(--color-dark) 92%, var(--ril-color-white)); /* DEF */
  --color-text:           var(--ril-color-white);                                         /* DEF · rIL lo cambia a crema en OVERRIDES */
  --color-heading:        var(--color-text);                                          /* DEF */
  --color-link:           var(--color-text);                                          /* DEF */
  --color-focus:          var(--color-text);                                          /* DEF */

  --color-success: #7BD389;               /* PENDIENTE DE REVISIÓN · 11,5:1 sobre negro */
  --color-error:   #FF7A85;               /* PENDIENTE DE REVISIÓN ·  8,4:1 sobre negro */
  --color-warning: var(--color-accent);   /* PENDIENTE DE REVISIÓN · Naranja Impulso puro, 6,1:1 sobre negro */
  --color-info:    var(--color-text);     /* PENDIENTE DE REVISIÓN */

  /* Cristal: receta para fondo OSCURO */
  --glass-bg:        color-mix(in srgb, var(--ril-color-white) 10%, transparent);  /* DEF */
  --glass-bg-strong: color-mix(in srgb, var(--ril-color-white) 22%, transparent);  /* DEF */
  --glass-border:    color-mix(in srgb, var(--ril-color-white) 28%, transparent);  /* DEF */
  --glass-shadow:    none;                                                     /* DEF */
  --shadow-color:    color-mix(in srgb, black 45%, transparent);               /* DEF */

  color-scheme: dark;
  background-color: var(--color-background);
  color: var(--color-text);
}
.theme-light {
  background-color: var(--color-background);
  color: var(--color-text);
}

/* ---- 2.5 TEMA SOL (propio de rIL) --------------------------------------
   Uso:  <section class="theme-sun"> ... </section>
         o  <section data-theme="sun"> ... </section>   (como en el Presupuestador)
   Fondo Amarillo Solar y texto negro. Misma mecánica que 2.4. Clase y
   atributo tienen la misma especificidad: se pueden usar indistintamente.
   Sobre amarillo, "primary" pasa a crema (el amarillo no se ve sobre sí
   mismo) y los avisos se oscurecen hasta AA.
   ----------------------------------------------------------------------- */
.theme-sun,
[data-theme="sun"] {
  --color-background:     var(--color-brand);                                          /* SET · rIL */
  --color-background-alt: color-mix(in srgb, var(--color-brand) 80%, var(--ril-color-white)); /* SET · rIL · sin referencia en Figma (la Home no tiene bloques sol alternos) */
  --color-surface:        var(--color-light);                                          /* SET · rIL */
  --color-text:           var(--color-dark);                                           /* SET · rIL · 10,4:1 */
  --color-heading:        var(--color-text);                                           /* SET · rIL */
  --color-primary:        var(--color-light);                                          /* SET · rIL */
  --color-on-primary:     var(--color-dark);                                           /* SET · rIL */
  --color-link:           var(--color-text);                                           /* SET · rIL */
  --color-focus:          var(--color-text);                                           /* SET · rIL */

  --color-success: #104C21;           /* PENDIENTE DE REVISIÓN · 5,1:1 sobre amarillo */
  --color-error:   #871A26;           /* PENDIENTE DE REVISIÓN · 4,8:1 sobre amarillo */
  --color-warning: #762E0B;           /* PENDIENTE DE REVISIÓN · 4,9:1 sobre amarillo */
  --color-info:    var(--color-text); /* PENDIENTE DE REVISIÓN */

  /* Cristal: misma receta que el tema claro, recalculada con el fondo amarillo */
  --glass-bg:        color-mix(in srgb, var(--color-background) 60%, transparent);
  --glass-bg-strong: color-mix(in srgb, var(--color-background) 82%, transparent);
  --glass-border:    color-mix(in srgb, var(--color-text) 12%, transparent);
  --glass-shadow:    var(--shadow-sm);

  color-scheme: light;
  background-color: var(--color-background);
  color: var(--color-text);
}


/* ==========================================================================
   3. TOKENS · TIPOGRAFÍA
   ========================================================================== */
:root {

  /* ---- 3.1 FAMILIAS -----------------------------------------------------
     NOMBRE --font-{rol}   roles: heading, body, mono
     VALOR  "Nombre real", fallback de sistema. Siempre con fallback.
     CARGA  fuentes-ril.css (Mona Sans 2.000 variable: ejes wdth 75-125 y wght 200-900; sin opsz).
     rIL    Mona Sans para todo. El ancho (Condensed / Expanded) no es otra
            familia: es el eje wdth, que se controla con font-stretch
            (ver --ril-stretch-* en VARIABLES PROPIAS).
            Onest Bold solo se usa en el descriptor del logotipo, que va como
            imagen (SVG): no se carga en la web.
     ------------------------------------------------------------------- */
  --font-heading: "Mona Sans", "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;  /* SET · rIL */
  --font-body:    "Mona Sans", "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;  /* SET · rIL */
  --font-mono:    ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;                /* DEF */

  /* ---- 3.2 PESOS --------------------------------------------------------
     NOMBRE --fw-{nombre}   escala estándar: light regular medium semibold bold
     VALOR  numérico CSS (100-900).
     REGLA  solo se USAN los pesos que existen en el archivo de fuente cargado.
     rIL    fuente variable (200-900): todos disponibles. Los titulares usan
            850, que no está en la escala: --ril-fw-black (VARIABLES PROPIAS).
     ------------------------------------------------------------------- */
  --fw-light:    300;  /* DEF */
  --fw-regular:  400;  /* DEF */
  --fw-medium:   500;  /* DEF */
  --fw-semibold: 600;  /* DEF · botones */
  --fw-bold:     700;  /* DEF · negritas en texto, precios y cifras pequeñas */

  /* ---- 3.3 INTERLINEADO -------------------------------------------------
     NOMBRE --lh-{nombre}    escala: tight snug normal relaxed
     VALOR  sin unidad.
     El nombre NO dice para qué elemento sirve; la asignación se hace por
     las normas de 3.7.
     ------------------------------------------------------------------- */
  --lh-display: 0.88;  /* SET · rIL · titulares gigantes (Figma: hero 0,88; «360°» 0,88) */
  --lh-tight:   0.9;   /* DEF · rIL · titulares en mayúsculas condensadas (0,86-0,95 en el Presupuestador) */
  --lh-heading: 0.95;  /* SET · rIL · titulares de sección (Figma: 0,95 en h1 y «El 95 %») */
  --lh-label:   1.2;   /* SET · rIL · antetítulos, navegación y «VER MÁS» (Figma: 1,2) */
  --lh-snug:    1.25;  /* DEF */
  --lh-normal:  1.4;   /* SET · rIL · 1,4 en móvil; 1,5 desde 64em (ver al final de 3.5) */
  --lh-relaxed: 1.7;   /* DEF */

  /* ---- 3.4 TRACKING (espaciado entre letras) ----------------------------
     NOMBRE --ls-{nombre}    escala: tight normal wide wider
     VALOR  en em (se escala con el tamaño de letra; nunca px ni rem).
     rIL    los titulares van condensados al 77 %: apretarlos más pega las
            letras. Las etiquetas en mayúsculas llevan muy poco tracking.
     ------------------------------------------------------------------- */
  --ls-tight:   0em;      /* DEF · rIL · titulares sin tracking negativo     */
  --ls-normal:  0em;      /* DEF                                              */
  --ls-wide:    0.02em;   /* DEF · rIL · botones (Presupuestador: 0,02em)    */
  --ls-wider:   0.02em;   /* SET · rIL · a confirmar · eyebrow y etiquetas en
                             mayúsculas. Igual que --ls-wide, como en Figma
                             (0,02em en todos los textos en mayúsculas); antes
                             0,04em. Se mantiene el token por si se separan */

  /* ---- 3.5 TAMAÑOS (fluidos) --------------------------------------------
     NOMBRE  --fs-{nombre}        nombres: display h1 h2 h3 h4 lead body small
     ENTRADA --fs-{nombre}-min    px sin unidad, modo Móvil    (ancho --vp-min)
             --fs-{nombre}-max    px sin unidad, modo Escritorio (ancho --vp-max)
     SALIDA  --fs-{nombre}        clamp() en rem (respeta el zoom de texto).
     Se edita solo -min / -max. El resto es mecánico.

     rIL     estilos fijos, como en el Presupuestador: los ocho de la norma
             más tamaños propios (plantilla de abajo):
               display-xl  titulares gigantes: «el equipo», «Así trabajamos»,
                           lista de servicios (DISEÑO, AUDIOVISUAL…)
               h5          etiquetas pequeñas
               stat        cifras grandes: «360°», «+10 años», «50 %»
               btn-*       texto de botones y enlaces (ver más abajo)
             Valores cerrados con Figma (lienzo «Home») el 09/10/2026. Figma
             dibuja a 402 y 1728 px; la escala fluye de 390 a 1920.
             Roles: display portada · h1 título de sección · h2 título de
             bloque · h3 título de punto o tarjeta · h4 etiqueta de grupo
             y subtotal · h5 etiqueta pequeña · small textos legales.

     PLANTILLA para un tamaño nuevo (copiar y cambiar "x"):
       --fs-x-min: 18;  --fs-x-max: 22;
       --fs-x: clamp(calc(var(--fs-x-min) * 1rem / 16), calc(var(--fs-x-min) * 1rem / 16 + (var(--fs-x-max) - var(--fs-x-min)) * var(--fluid)), calc(var(--fs-x-max) * 1rem / 16));
     ------------------------------------------------------------------- */
  --vp-min: 402;    /* SET · rIL · ancho (px) del frame móvil de Figma: la escala parte de aquí     */
  --vp-max: 1728;   /* SET · rIL · ancho (px) del frame de escritorio de Figma: la escala llega aquí
                                   a su máximo (v1.5; antes 390 / 1920). Así los dos frames
                                   salen exactos y los extremos se quedan en su valor */
  --fluid:  calc((100vw - var(--vp-min) * 1px) / (var(--vp-max) - var(--vp-min)));  /* DEF · mecánico, no usar suelto */
  /* Fluido acotado: 0 px en el frame móvil, 1 px en el de escritorio, y quieto
     fuera. Para una medida de composición de Figma (m en móvil, d en escritorio)
     que no es un token de escala:   calc(m * 1rem / 16 + (d - m) * var(--fluid-c))
     Se usa en sections/ para huecos y posiciones; nunca para tipografía. */
  --fluid-c: clamp(0px, var(--fluid), 1px);                                          /* SET · rIL · mecánico */

  /* Valores = Figma «📱 Home» (402) / «Propuesta home» (1728), medidos el 11/10/2026.
     Un -min mayor que el -max es válido: el tamaño DECRECE con el ancho («360°»). */
  --fs-display-2xl-min: 200; --fs-display-2xl-max: 296;   /* SET · rIL · cinta «PROYECTOS» */
  --fs-display-xl-min:   68; --fs-display-xl-max:  207;   /* SET · rIL · «EL EQUIPO» */
  --fs-display-lg-min:   77; --fs-display-lg-max:  200;   /* SET · rIL · «ASÍ TRABAJAMOS EN rIL» */
  --fs-display-min:      68; --fs-display-max:     200;   /* SET · rIL · titular del hero */
  --fs-menu-min:         74; --fs-menu-max:        189;   /* SET · rIL · palabras del menú de servicios */
  --fs-cta-min:          54; --fs-cta-max:         108;   /* SET · rIL · cierre «IMPULSAREMOS…» */
  --fs-closing-min:      40; --fs-closing-max:     108;   /* SET · rIL · cierre del pie en móvil, más ligero (12/10/2026; antes 54 = --fs-cta) */
  --fs-h1-lg-min:        44; --fs-h1-lg-max:        86;   /* SET · rIL · «EL 95 % DE NUESTROS CLIENTES…» */
  --fs-h1-min:      44; --fs-h1-max:       74;   /* SET · rIL */
  --fs-title-min:   60; --fs-title-max:    74;   /* SET · rIL · títulos de servicio (Servicios, 13/10/2026) */
  --fs-list-min:    28; --fs-list-max:     32;   /* SET · rIL · listas de subservicios y títulos de paso (Servicios) */
  --fs-lead-lg-min: 20; --fs-lead-lg-max:  22;   /* SET · rIL · texto de servicio (Servicios) */
  --fs-h2-min:      34; --fs-h2-max:       48;   /* SET · rIL */
  --fs-h3-min:      20; --fs-h3-max:       24;   /* SET · rIL */
  --fs-h4-min:      16; --fs-h4-max:       18;   /* SET · rIL */
  --fs-h5-min:      12; --fs-h5-max:       14;   /* SET · rIL · tamaño nuevo rIL */
  --fs-lead-min:    18; --fs-lead-max:     22;   /* SET · rIL */
  --fs-body-min:    12; --fs-body-max:     18;   /* SET · rIL · párrafo: 12 en móvil (petición del 12/10/2026; Figma: 18) y 18 en escritorio */
  --fs-body-lg-min: 14; --fs-body-lg-max:  19;   /* SET · rIL · enlaces y datos del pie (móvil 14: pie en una pantalla) */
  --fs-small-min:   12; --fs-small-max:    18;   /* SET · rIL · textos legales (móvil 12: pie en una pantalla) */
  --fs-subp-min:    11; --fs-subp-max:     16;   /* SET · rIL · subpárrafo (.u-subp): amplía un párrafo anterior,
                                                  un paso por debajo del cuerpo (texto del desplegable de herramientas) */
  --fs-stat-min: 198.5; --fs-stat-max:     84;   /* SET · rIL · «360°»: protagonista en móvil, a todo el ancho
                                                  (Figma: 198,5 en la caja de 373; la capa de 160 estaba oculta
                                                  debajo), cifra junto al antetítulo en escritorio (84). Decrece.
                                                  En móvil la sección la ajusta al ancho real (split-media.css) */
  /* Etiquetas en mayúsculas (Mona Sans semibold, ancho 84 %) */
  --fs-eyebrow-min:    20; --fs-eyebrow-max:    24;   /* SET · rIL · antetítulo (bloque «360°») */
  --fs-eyebrow-sm-min: 20; --fs-eyebrow-sm-max: 18;   /* SET · rIL · antetítulo del hero */
  --fs-eyebrow-lg-min: 20; --fs-eyebrow-lg-max: 32;   /* SET · rIL · «EL ORIGEN DE NUESTRA LUZ» */
  --fs-label-min:      20; --fs-label-max:      20;   /* SET · rIL · títulos de columna del pie */
  --fs-nav-min:        15; --fs-nav-max:        15;   /* SET · rIL · navegación de la cabecera */

  /* Botones y enlaces (los lee --btn-fs y los componentes de navegación)
       btn-small    CTA en texto: «Ver más», «Conócenos»
       btn-cta      «CONTACTA» de la cabecera
       btn-menu     entradas del menú móvil (y su «CONTACTA»)
       btn-large    enlace con forma de titular: «OPAL DENTAL STUDIO»
       btn-closing  «TARIFAS», «CONTÁCTANOS» del pie
       btn-tag      botón con forma de etiqueta amarilla («VER MÁS» del menú de servicios) */
  --fs-btn-small-min:   20; --fs-btn-small-max:   20;  /* SET · rIL */
  --fs-btn-cta-min:     28; --fs-btn-cta-max:     28;  /* SET · rIL */
  --fs-btn-menu-min:    46; --fs-btn-menu-max:    46;  /* SET · rIL · menú móvil (Figma: 68; más sutil por petición del 12/10/2026) */
  --fs-btn-large-min:   34; --fs-btn-large-max:   48;  /* SET · rIL */
  --fs-btn-closing-min: 22; --fs-btn-closing-max: 48;  /* SET · rIL · móvil 22 (antes 29) */
  --fs-btn-tag-min:     24; --fs-btn-tag-max:     24;  /* SET · rIL · botón amarillo «VER MÁS» del menú de servicios (móvil) */

  /* SALIDA (mecánica). min()/max() en los extremos: admite escalas que decrecen. */
  --fs-display-2xl: clamp(calc(min(var(--fs-display-2xl-min), var(--fs-display-2xl-max)) * 1rem / 16), calc(var(--fs-display-2xl-min) * 1rem / 16 + (var(--fs-display-2xl-max) - var(--fs-display-2xl-min)) * var(--fluid)), calc(max(var(--fs-display-2xl-min), var(--fs-display-2xl-max)) * 1rem / 16));
  --fs-display-xl:  clamp(calc(min(var(--fs-display-xl-min), var(--fs-display-xl-max)) * 1rem / 16), calc(var(--fs-display-xl-min) * 1rem / 16 + (var(--fs-display-xl-max) - var(--fs-display-xl-min)) * var(--fluid)), calc(max(var(--fs-display-xl-min), var(--fs-display-xl-max)) * 1rem / 16));
  --fs-display-lg:  clamp(calc(min(var(--fs-display-lg-min), var(--fs-display-lg-max)) * 1rem / 16), calc(var(--fs-display-lg-min) * 1rem / 16 + (var(--fs-display-lg-max) - var(--fs-display-lg-min)) * var(--fluid)), calc(max(var(--fs-display-lg-min), var(--fs-display-lg-max)) * 1rem / 16));
  --fs-display:     clamp(calc(min(var(--fs-display-min), var(--fs-display-max)) * 1rem / 16), calc(var(--fs-display-min) * 1rem / 16 + (var(--fs-display-max) - var(--fs-display-min)) * var(--fluid)), calc(max(var(--fs-display-min), var(--fs-display-max)) * 1rem / 16));
  --fs-menu:        clamp(calc(min(var(--fs-menu-min), var(--fs-menu-max)) * 1rem / 16), calc(var(--fs-menu-min) * 1rem / 16 + (var(--fs-menu-max) - var(--fs-menu-min)) * var(--fluid)), calc(max(var(--fs-menu-min), var(--fs-menu-max)) * 1rem / 16));
  --fs-cta:         clamp(calc(min(var(--fs-cta-min), var(--fs-cta-max)) * 1rem / 16), calc(var(--fs-cta-min) * 1rem / 16 + (var(--fs-cta-max) - var(--fs-cta-min)) * var(--fluid)), calc(max(var(--fs-cta-min), var(--fs-cta-max)) * 1rem / 16));
  --fs-closing:     clamp(calc(min(var(--fs-closing-min), var(--fs-closing-max)) * 1rem / 16), calc(var(--fs-closing-min) * 1rem / 16 + (var(--fs-closing-max) - var(--fs-closing-min)) * var(--fluid)), calc(max(var(--fs-closing-min), var(--fs-closing-max)) * 1rem / 16));
  --fs-h1-lg:       clamp(calc(min(var(--fs-h1-lg-min), var(--fs-h1-lg-max)) * 1rem / 16), calc(var(--fs-h1-lg-min) * 1rem / 16 + (var(--fs-h1-lg-max) - var(--fs-h1-lg-min)) * var(--fluid)), calc(max(var(--fs-h1-lg-min), var(--fs-h1-lg-max)) * 1rem / 16));
  --fs-h1:          clamp(calc(min(var(--fs-h1-min), var(--fs-h1-max)) * 1rem / 16), calc(var(--fs-h1-min) * 1rem / 16 + (var(--fs-h1-max) - var(--fs-h1-min)) * var(--fluid)), calc(max(var(--fs-h1-min), var(--fs-h1-max)) * 1rem / 16));
  --fs-title:          clamp(calc(min(var(--fs-title-min), var(--fs-title-max)) * 1rem / 16), calc(var(--fs-title-min) * 1rem / 16 + (var(--fs-title-max) - var(--fs-title-min)) * var(--fluid)), calc(max(var(--fs-title-min), var(--fs-title-max)) * 1rem / 16));
  --fs-list:          clamp(calc(min(var(--fs-list-min), var(--fs-list-max)) * 1rem / 16), calc(var(--fs-list-min) * 1rem / 16 + (var(--fs-list-max) - var(--fs-list-min)) * var(--fluid)), calc(max(var(--fs-list-min), var(--fs-list-max)) * 1rem / 16));
  --fs-lead-lg:          clamp(calc(min(var(--fs-lead-lg-min), var(--fs-lead-lg-max)) * 1rem / 16), calc(var(--fs-lead-lg-min) * 1rem / 16 + (var(--fs-lead-lg-max) - var(--fs-lead-lg-min)) * var(--fluid)), calc(max(var(--fs-lead-lg-min), var(--fs-lead-lg-max)) * 1rem / 16));
  --fs-h2:          clamp(calc(min(var(--fs-h2-min), var(--fs-h2-max)) * 1rem / 16), calc(var(--fs-h2-min) * 1rem / 16 + (var(--fs-h2-max) - var(--fs-h2-min)) * var(--fluid)), calc(max(var(--fs-h2-min), var(--fs-h2-max)) * 1rem / 16));
  --fs-h3:          clamp(calc(min(var(--fs-h3-min), var(--fs-h3-max)) * 1rem / 16), calc(var(--fs-h3-min) * 1rem / 16 + (var(--fs-h3-max) - var(--fs-h3-min)) * var(--fluid)), calc(max(var(--fs-h3-min), var(--fs-h3-max)) * 1rem / 16));
  --fs-h4:          clamp(calc(min(var(--fs-h4-min), var(--fs-h4-max)) * 1rem / 16), calc(var(--fs-h4-min) * 1rem / 16 + (var(--fs-h4-max) - var(--fs-h4-min)) * var(--fluid)), calc(max(var(--fs-h4-min), var(--fs-h4-max)) * 1rem / 16));
  --fs-h5:          clamp(calc(min(var(--fs-h5-min), var(--fs-h5-max)) * 1rem / 16), calc(var(--fs-h5-min) * 1rem / 16 + (var(--fs-h5-max) - var(--fs-h5-min)) * var(--fluid)), calc(max(var(--fs-h5-min), var(--fs-h5-max)) * 1rem / 16));
  --fs-lead:        clamp(calc(min(var(--fs-lead-min), var(--fs-lead-max)) * 1rem / 16), calc(var(--fs-lead-min) * 1rem / 16 + (var(--fs-lead-max) - var(--fs-lead-min)) * var(--fluid)), calc(max(var(--fs-lead-min), var(--fs-lead-max)) * 1rem / 16));
  --fs-body:        clamp(calc(min(var(--fs-body-min), var(--fs-body-max)) * 1rem / 16), calc(var(--fs-body-min) * 1rem / 16 + (var(--fs-body-max) - var(--fs-body-min)) * var(--fluid)), calc(max(var(--fs-body-min), var(--fs-body-max)) * 1rem / 16));
  --fs-body-lg:     clamp(calc(min(var(--fs-body-lg-min), var(--fs-body-lg-max)) * 1rem / 16), calc(var(--fs-body-lg-min) * 1rem / 16 + (var(--fs-body-lg-max) - var(--fs-body-lg-min)) * var(--fluid)), calc(max(var(--fs-body-lg-min), var(--fs-body-lg-max)) * 1rem / 16));
  --fs-small:       clamp(calc(min(var(--fs-small-min), var(--fs-small-max)) * 1rem / 16), calc(var(--fs-small-min) * 1rem / 16 + (var(--fs-small-max) - var(--fs-small-min)) * var(--fluid)), calc(max(var(--fs-small-min), var(--fs-small-max)) * 1rem / 16));
  --fs-subp:        clamp(calc(min(var(--fs-subp-min), var(--fs-subp-max)) * 1rem / 16), calc(var(--fs-subp-min) * 1rem / 16 + (var(--fs-subp-max) - var(--fs-subp-min)) * var(--fluid)), calc(max(var(--fs-subp-min), var(--fs-subp-max)) * 1rem / 16));
  --fs-stat:        clamp(calc(min(var(--fs-stat-min), var(--fs-stat-max)) * 1rem / 16), calc(var(--fs-stat-min) * 1rem / 16 + (var(--fs-stat-max) - var(--fs-stat-min)) * var(--fluid)), calc(max(var(--fs-stat-min), var(--fs-stat-max)) * 1rem / 16));
  --fs-eyebrow:     clamp(calc(min(var(--fs-eyebrow-min), var(--fs-eyebrow-max)) * 1rem / 16), calc(var(--fs-eyebrow-min) * 1rem / 16 + (var(--fs-eyebrow-max) - var(--fs-eyebrow-min)) * var(--fluid)), calc(max(var(--fs-eyebrow-min), var(--fs-eyebrow-max)) * 1rem / 16));
  --fs-eyebrow-sm:  clamp(calc(min(var(--fs-eyebrow-sm-min), var(--fs-eyebrow-sm-max)) * 1rem / 16), calc(var(--fs-eyebrow-sm-min) * 1rem / 16 + (var(--fs-eyebrow-sm-max) - var(--fs-eyebrow-sm-min)) * var(--fluid)), calc(max(var(--fs-eyebrow-sm-min), var(--fs-eyebrow-sm-max)) * 1rem / 16));
  --fs-eyebrow-lg:  clamp(calc(min(var(--fs-eyebrow-lg-min), var(--fs-eyebrow-lg-max)) * 1rem / 16), calc(var(--fs-eyebrow-lg-min) * 1rem / 16 + (var(--fs-eyebrow-lg-max) - var(--fs-eyebrow-lg-min)) * var(--fluid)), calc(max(var(--fs-eyebrow-lg-min), var(--fs-eyebrow-lg-max)) * 1rem / 16));
  --fs-label:       clamp(calc(min(var(--fs-label-min), var(--fs-label-max)) * 1rem / 16), calc(var(--fs-label-min) * 1rem / 16 + (var(--fs-label-max) - var(--fs-label-min)) * var(--fluid)), calc(max(var(--fs-label-min), var(--fs-label-max)) * 1rem / 16));
  --fs-nav:         clamp(calc(min(var(--fs-nav-min), var(--fs-nav-max)) * 1rem / 16), calc(var(--fs-nav-min) * 1rem / 16 + (var(--fs-nav-max) - var(--fs-nav-min)) * var(--fluid)), calc(max(var(--fs-nav-min), var(--fs-nav-max)) * 1rem / 16));

  --fs-btn-small:   clamp(calc(min(var(--fs-btn-small-min), var(--fs-btn-small-max)) * 1rem / 16), calc(var(--fs-btn-small-min) * 1rem / 16 + (var(--fs-btn-small-max) - var(--fs-btn-small-min)) * var(--fluid)), calc(max(var(--fs-btn-small-min), var(--fs-btn-small-max)) * 1rem / 16));
  --fs-btn-cta:     clamp(calc(min(var(--fs-btn-cta-min), var(--fs-btn-cta-max)) * 1rem / 16), calc(var(--fs-btn-cta-min) * 1rem / 16 + (var(--fs-btn-cta-max) - var(--fs-btn-cta-min)) * var(--fluid)), calc(max(var(--fs-btn-cta-min), var(--fs-btn-cta-max)) * 1rem / 16));
  --fs-btn-menu:    clamp(calc(min(var(--fs-btn-menu-min), var(--fs-btn-menu-max)) * 1rem / 16), calc(var(--fs-btn-menu-min) * 1rem / 16 + (var(--fs-btn-menu-max) - var(--fs-btn-menu-min)) * var(--fluid)), calc(max(var(--fs-btn-menu-min), var(--fs-btn-menu-max)) * 1rem / 16));
  --fs-btn-large:   clamp(calc(min(var(--fs-btn-large-min), var(--fs-btn-large-max)) * 1rem / 16), calc(var(--fs-btn-large-min) * 1rem / 16 + (var(--fs-btn-large-max) - var(--fs-btn-large-min)) * var(--fluid)), calc(max(var(--fs-btn-large-min), var(--fs-btn-large-max)) * 1rem / 16));
  --fs-btn-closing: clamp(calc(min(var(--fs-btn-closing-min), var(--fs-btn-closing-max)) * 1rem / 16), calc(var(--fs-btn-closing-min) * 1rem / 16 + (var(--fs-btn-closing-max) - var(--fs-btn-closing-min)) * var(--fluid)), calc(max(var(--fs-btn-closing-min), var(--fs-btn-closing-max)) * 1rem / 16));
  --fs-btn-tag:     clamp(calc(min(var(--fs-btn-tag-min), var(--fs-btn-tag-max)) * 1rem / 16), calc(var(--fs-btn-tag-min) * 1rem / 16 + (var(--fs-btn-tag-max) - var(--fs-btn-tag-min)) * var(--fluid)), calc(max(var(--fs-btn-tag-min), var(--fs-btn-tag-max)) * 1rem / 16));
}

/* Interlineado normal: 1,4 en móvil y 1,5 desde 64em (breakpoint lg de
   base.css). Escalón, no fluido: un interlineado sin unidad no se puede
   interpolar con el ancho de pantalla. */
@media (width >= 64em) {
  :root { --lh-normal: 1.5; }   /* SET · rIL */
}

/* ---- 3.7 NORMAS DE ASIGNACIÓN (qué token usa cada tipo de texto) ---------
   Las variables no llevan el nombre del elemento; esta tabla es la que
   asocia. base.css (sección 7) implementa la tabla de la norma y
   marca-ril.css aplica las diferencias de rIL (marcadas con *).

     texto                tamaño        interlineado   tracking     peso        ancho / caja
     ------------------   -----------   ------------   ----------   ---------   -------------------
     display-xl*          --fs-display-xl* --lh-tight  --ls-tight   black*      condensed*, MAYÚSC.*
     display              --fs-display  --lh-tight     --ls-tight   black*      condensed*, MAYÚSC.*
     h1                   --fs-h1       --lh-tight     --ls-tight   black*      condensed*, MAYÚSC.*
     h2                   --fs-h2       --lh-tight*    --ls-tight   black*      condensed*, MAYÚSC.*
     h3                   --fs-h3       --lh-tight*    --ls-normal  black*      condensed*, MAYÚSC.*
     h4                   --fs-h4       --lh-snug      --ls-normal  black*      condensed*, MAYÚSC.*
     h5 / etiqueta*       --fs-h5*      --lh-tight     --ls-wider   regular*    condensed*, MAYÚSC.*
     cifra (stat)*        --fs-stat*    --lh-tight     --ls-tight   black*      condensed*
     lead                 --fs-lead     --lh-normal*   --ls-normal  regular
     cuerpo               --fs-body     --lh-normal    --ls-normal  regular
     lectura larga        --fs-body     --lh-relaxed   --ls-normal  regular
     small / legales      --fs-small    --lh-normal    --ls-normal  regular
     eyebrow (mayúsc.)    --fs-eyebrow* --lh-label*    --ls-wider   regular*    ancho 84 %*
     botón / CTA texto*   --fs-btn-small* --lh-label*  --ls-wide*   regular*    ancho 87 %*, MAYÚSC.*
     navegación*          --fs-nav*     --lh-label*    --ls-wide*   medium*     ancho 84 %*, MAYÚSC.*
     CONTACTA / menú*     --fs-btn-cta* / --fs-btn-menu*  --lh-snug  black*  condensed*, MAYÚSC.*
     enlace-titular*      --fs-btn-large* --lh-tight   --ls-tight   black*      condensed*, MAYÚSC.*
   ------------------------------------------------------------------------ */


/* ==========================================================================
   4. TOKENS · MEDIDAS
   ========================================================================== */
:root {

  /* ---- 4.1 ESPACIADO ----------------------------------------------------
     NOMBRE --space-{talla}   escala: 3xs 2xs xs sm md lg xl 2xl 3xl
     REGLA  de 3xs a lg: fijos, para el interior de componentes.
            de xl a 3xl: fluidos (mismo mecanismo que 3.5), para huecos
            entre bloques y secciones.
     rIL    --space-md (24 px) es la separación del contenido respecto a las
            líneas de la retícula en escritorio.
     ------------------------------------------------------------------- */
  --space-3xs: 0.25rem;   /* DEF ·  4 */
  --space-2xs: 0.5rem;    /* DEF ·  8 */
  --space-xs:  0.75rem;   /* DEF · 12 */
  --space-sm:  1rem;      /* DEF · 16 */
  --space-md:  1.5rem;    /* DEF · 24 */
  --space-lg:  2rem;      /* DEF · 32 */

  --space-xl-min:  40; --space-xl-max:   56;   /* SET · rIL · hueco bajo entradillas y cabeceras de bloque */
  --space-2xl-min: 56; --space-2xl-max:  88;   /* SET · rIL · hueco entre bloques */
  --space-3xl-min: 88; --space-3xl-max: 144;   /* SET · rIL · padding vertical de sección */
  --space-xl:  clamp(calc(var(--space-xl-min) * 1rem / 16),  calc(var(--space-xl-min) * 1rem / 16  + (var(--space-xl-max) - var(--space-xl-min)) * var(--fluid)),   calc(var(--space-xl-max) * 1rem / 16));
  --space-2xl: clamp(calc(var(--space-2xl-min) * 1rem / 16), calc(var(--space-2xl-min) * 1rem / 16 + (var(--space-2xl-max) - var(--space-2xl-min)) * var(--fluid)), calc(var(--space-2xl-max) * 1rem / 16));
  --space-3xl: clamp(calc(var(--space-3xl-min) * 1rem / 16), calc(var(--space-3xl-min) * 1rem / 16 + (var(--space-3xl-max) - var(--space-3xl-min)) * var(--fluid)), calc(var(--space-3xl-max) * 1rem / 16));

  /* ---- 4.2 LAYOUT -------------------------------------------------------
     NOMBRE --container-{variante}, --section-y, --header-height
     rIL    la retícula de 12 columnas y sus líneas usan --ril-grid-*
            (VARIABLES PROPIAS).
     ------------------------------------------------------------------- */
  --container-max:    120rem;                      /* SET · rIL · 1920 px */
  --container-narrow: 48rem;                       /* DEF */
  --container-pad-min: 14; --container-pad-max: 40;   /* SET · rIL · margen exterior de la retícula (Figma: 14 y 40) */
  --container-pad:    clamp(calc(var(--container-pad-min) * 1rem / 16), calc(var(--container-pad-min) * 1rem / 16 + (var(--container-pad-max) - var(--container-pad-min)) * var(--fluid)), calc(var(--container-pad-max) * 1rem / 16));
  --section-y:        var(--space-2xl);            /* DEF · rIL lo cambia a 3xl en OVERRIDES */
  --header-height-min: 56; --header-height-max: 60;   /* SET · rIL · barra fija, más baja que Figma (77 / 71) por petición del 12/10/2026; el logo escala con ella (41,5 %) */
  --header-height:    clamp(calc(var(--header-height-min) * 1rem / 16), calc(var(--header-height-min) * 1rem / 16 + (var(--header-height-max) - var(--header-height-min)) * var(--fluid)), calc(var(--header-height-max) * 1rem / 16));
  --control-height:   3rem;                        /* DEF · campos de formulario */

  /* ---- 4.3 RADIOS -------------------------------------------------------
     NOMBRE --radius-{talla}   escala: none xs sm md lg xl full
     VALOR  rem; full = 9999px (píldora y círculo).
     REGLA  qué radio usa cada componente se decide por el token de
            componente (--btn-radius, --card-radius...), no por la escala.
     rIL    radios pequeños: 8 px en imágenes, fichas, etiquetas y botones;
            14 px en el hover de imágenes. Los nombres de rIL son
            --radius-small y --radius-large; --radius-sm y --radius-lg se
            mantienen como alias porque base.css los lee (.u-skip-link,
            fallbacks de .card y .glass).
     ------------------------------------------------------------------- */
  --radius-small: 0.5rem;     /* SET · rIL ·  8 · imágenes, fichas, etiquetas, botones */
  --radius-large: 0.875rem;   /* SET · rIL · 14 · imágenes al pasar por encima */
  --radius-none: 0;           /* DEF */
  --radius-xs:   0.125rem;    /* DEF ·  2 */
  --radius-sm:   var(--radius-small);   /* SET · rIL · alias para base.css (antes 6 px) */
  --radius-md:   0.5rem;      /* DEF ·  8 · campos */
  --radius-lg:   var(--radius-large);   /* SET · rIL · alias para base.css */
  --radius-xl:   1.5rem;      /* DEF · 24 */
  --radius-full: 9999px;      /* DEF · botones, círculos */

  /* ---- 4.4 BORDES Y FOCO ------------------------------------------------ */
  --border-width: 1px;        /* DEF · también el grosor de las líneas de la retícula */
  --focus-width:  2px;        /* DEF */
  --focus-offset: 2px;        /* DEF */

  /* ---- 4.5 SOMBRAS ------------------------------------------------------
     (los valores están en 2.3: allí se evalúan con el --shadow-color de cada tema)
     rIL    la marca casi no usa sombras: solo las fichas flotantes.
     ------------------------------------------------------------------- */

  /* ---- 4.6 MOVIMIENTO ---------------------------------------------------
     NOMBRE --dur-{nombre}   fast base slow      --ease-{nombre}   standard in-out
     USO    transition: {propiedad} var(--dur-base) var(--ease-standard);
            Animaciones decorativas largas se declaran en su componente.
     rIL    movimiento suave y algo más lento que la plantilla. Nada rebota
            y ningún hover desplaza textos. Precios y porcentajes nunca se
            animan. Curvas del Presupuestador: standard = hover, in-out =
            entradas y salidas (idéntica a la plantilla).
     ------------------------------------------------------------------- */
  --dur-fast: 250ms;                               /* DEF · rIL · cambios de color en hover */
  --dur-base: 400ms;                               /* DEF · rIL · iconos, flechas, desplegables */
  --dur-slow: 800ms;                               /* DEF · rIL · cambios de tema, imágenes */
  --ease-standard: cubic-bezier(0.22, 1, 0.36, 1); /* DEF · rIL · salida suave sin rebote */
  --ease-in-out:   cubic-bezier(0.65, 0, 0.35, 1); /* DEF */

  /* ---- 4.7 CAPAS Z -------------------------------------------------------
     NOMBRE --z-{nombre}   Nunca z-index numérico suelto.
     ------------------------------------------------------------------- */
  --z-base: 0;  --z-dropdown: 100;  --z-sticky: 200;   /* DEF */
  --z-overlay: 300;  --z-modal: 400;  --z-toast: 500;  /* DEF */
}


/* ==========================================================================
   5. TOKENS · EFECTOS
   ========================================================================== */
:root {

  /* ---- 5.1 DEGRADADOS ---------------------------------------------------
     NOMBRE  --gradient-{nombre}
     COMPOSICIÓN  siempre desde dos paradas + ángulo.
     rIL     Figma define un degradado de texto: crema → Amarillo Solar, de
             arriba abajo, que llega al amarillo al 32 % de la altura
             («95%» en «El 95 % de nuestros clientes…», sobre negro). Se
             usa con .text-gradient. Los otros degradados de la marca son
             "soles" (ver --ril-sun-*). .btn--gradient no se usa: Figma no
             tiene botones con degradado.
             Crema y amarillo se leen como primitivos (no como text/primary)
             porque se resuelven en :root, fuera de cualquier tema.
     ------------------------------------------------------------------- */
  --gradient-from:  var(--color-light);       /* SET · rIL */
  --gradient-to:    var(--color-brand);       /* SET · rIL */
  --gradient-angle: 180deg;                   /* SET · rIL · de arriba abajo */
  --gradient-primary: linear-gradient(var(--gradient-angle), var(--gradient-from), var(--gradient-to) 32%);  /* DEF · rIL · parada final al 32 %, como en Figma */

  /* ---- 5.2 CRISTAL ------------------------------------------------------
     rIL     solo en la barra fija sobre contenido (desenfoque de 12 px en el
             Presupuestador).
     ------------------------------------------------------------------- */
  --glass-blur: 12px;   /* DEF · rIL */

  /* ---- 5.3 CHAFLÁN ------------------------------------------------------- */
  --chamfer-size: 0px;   /* SET · rIL · la marca no usa chaflán: .chamfer no hace nada */
  --chamfer-line: 1px;   /* DEF */
}


/* ==========================================================================
   OVERRIDES DE MARCA (rIL)
   Solo reasignar tokens de componente o de tema. Nunca editar base.css.

   OJO CON EL ALCANCE. Un token que se reasigna con var() en :root se
   resuelve en :root y los hijos heredan el valor ya calculado: un
   "--btn-bg: var(--color-text)" en :root daría negro también dentro de
   .theme-space. Por eso:
     A. tokens que NO dependen del tema   →  :root
     B. tokens que SÍ dependen del tema   →  en todos los selectores de tema
        (misma solución que 2.3), o con currentColor, que se resuelve donde
        se usa.
   ========================================================================== */

/* ---- A. Independientes del tema ------------------------------------------ */
:root {
  /* layout */
  --section-y: var(--space-3xl);          /* secciones amplias, como el Presupuestador */

  /* botón: radio de 8 px, mayúsculas, sin sombra (marca-ril.css pone las mayúsculas) */
  --btn-radius:       var(--radius-small);
  --btn-fs:           var(--fs-btn-small);
  --btn-fw:           var(--fw-semibold);
  --btn-ls:           var(--ls-wide);
  --btn-min-h:        2.5rem;             /* 40 px de alto, como en el Presupuestador y en Figma */
  --btn-shadow-hover: none;

  /* etiquetas: toman el color del texto que las rodea */
  --eyebrow-fg: currentColor;
  --pill-fg:    currentColor;

  /* eyebrow: antetítulo en mayúsculas, peso normal y ancho 84 % (Figma) */
  --eyebrow-fs:      var(--fs-eyebrow);
  --eyebrow-fw:      var(--fw-regular);
  --eyebrow-stretch: var(--ril-stretch-label);

  /* tarjeta: radio de las fichas */
  --card-radius: var(--radius-md);
}

/* ---- B. Dependientes del tema: semánticos ---------------------------------- */
:root,
.theme-light {
  --color-background:     var(--color-light);                                         /* crema */
  --color-background-alt: color-mix(in srgb, var(--color-dark) 6%, var(--color-light)); /* SET · rIL · ≈ #ECEAE5; Figma no tiene fondo alterno */
  --color-on-primary:     var(--color-dark);                                          /* negro sobre amarillo: 10,4:1 */
  --color-link:           var(--color-text);                                          /* los enlaces se marcan con flecha o subrayado, no con color */
  --color-focus:          var(--color-text);
}
.theme-space {
  --color-text:           var(--color-light);                                         /* crema sobre negro: 20,0:1 */
  --color-primary:        var(--color-brand);                                         /* por si el bloque oscuro va dentro de .theme-sun */
}

/* ---- B. Dependientes del tema: componentes -------------------------------
   Botón de rIL: relleno del color del texto (negro sobre crema, crema sobre
   negro) y, al pasar por encima, Amarillo Solar con texto negro. En .theme-sun
   el hover pasa a crema. Las variantes (.btn--secondary...) siguen ganando
   porque se declaran en el propio elemento.
   ------------------------------------------------------------------------ */
:root,
.theme-light,
.theme-space,
.theme-sun,
[data-theme="sun"] {
  --btn-bg:       var(--color-text);
  --btn-fg:       var(--color-background);
  --btn-bg-hover: var(--color-primary);
  --btn-fg-hover: var(--color-on-primary);

  /* líneas de la retícula: negras en claro y en sol, crema al 30 % en oscuro */
  --ril-grid-line-color: var(--color-text);
}
.theme-space {
  --ril-grid-line-color: color-mix(in srgb, var(--color-text) 30%, transparent);
}


/* ==========================================================================
   LEGACY · alias de transición (nombre antiguo → token estándar)
   Solo para CSS de rIL aún sin migrar. Retirar el bloque cuando no quede
   ningún consumidor.   Retirada prevista: no aplica (web nueva, sin consumidores)

   Si se porta un componente del Presupuestador, se traduce con esta tabla
   en lugar de activar alias:
     --k  → --color-dark        --cr → --color-light       --sun → --color-brand
     --or → --color-accent      --t2 → --color-text-muted  --g2  → --color-background-alt
     --bg / --fg      → --color-background / --color-text
     --gut            → --container-pad                    --maxw → --container-max
     --io             → --ease-in-out                      --hv   → --ease-standard
     --out            → --ril-ease-out
     --fs-cifra       → --fs-stat         (el resto de --fs-* se llaman igual)
     data-theme=dark  → .theme-space       data-theme=sun  → se mantiene (o .theme-sun)
   ========================================================================== */
:root {
  /* sin alias activos */
}


/* ==========================================================================
   VARIABLES PROPIAS DE rIL (sin equivalente en la norma)
   Prefijo --ril-*. Si otra marca repite una, se promueve a la plantilla.
   ========================================================================== */
:root {

  /* ---- Tipografía -------------------------------------------------------
     Mona Sans con los juegos estilísticos ss03, ss05 y ss06 y el eje de
     tamaño óptico fijo en 28, como en el Presupuestador. */
  --ril-font-features:   "ss03" 1, "ss05" 1, "ss06" 1;   /* SET · rIL */
  --ril-font-variations: "opsz" 28;                      /* SET · rIL · sin efecto con Mona Sans 2.000 (no tiene eje opsz); se mantiene por el Presupuestador */
  --ril-fw-black:        850;                            /* SET · rIL · titulares y cifras */

  /* Ancho (eje wdth, vía font-stretch). Titulares condensados al 77 %.
     Letras anchas (Expanded): una por palabra y dos como máximo por
     titular, preferiblemente E, R, D, F o N, nunca la primera ni la
     última. Su animación solo estira de 75 % a 110 %, en dos fotogramas,
     sin gris ni transparencia. */
  --ril-stretch-display:       75%;    /* SET · rIL · titulares gigantes (Figma: wdth 75) */
  --ril-stretch-hero:          81%;    /* SET · rIL · titular del hero en escritorio. La capa de Figma
                                          dice wdth 75, pero se ve a ≈81 (medido: «QUE BUSCAN
                                          CRECER» 1628 px a 200 px; el resto de textos de 75 sí
                                          miden 75). Manda lo que se ve */
  --ril-stretch-hero-sm:       79%;    /* SET · rIL · ídem en móvil («PARA MARCAS» 374 px a 68 px) */
  --ril-stretch-condensed:     77%;    /* SET · rIL */
  --ril-stretch-label:         84%;    /* SET · rIL · antetítulos y navegación (Figma: wdth 84) */
  --ril-stretch-cta:           87%;    /* SET · rIL · «VER MÁS», «CONÓCENOS», títulos del pie (Figma: wdth 87) */
  --ril-stretch-expanded:      110%;   /* SET · rIL · estado final de la letra ancha */
  --ril-stretch-expanded-from: 75%;    /* SET · rIL · estado inicial de su animación */

  /* ---- Retícula ---------------------------------------------------------
     12 columnas sin hueco entre ellas; las líneas verticales marcan sus
     bordes y el contenido se separa de ellas con --ril-grid-inset.
     Los bloques solo se parten en las columnas 4 y 8; el contenido empieza
     en la 1, la 5 o la 9. Las líneas no cruzan ningún texto ni filete.
     Un grupo de exactamente tres elementos va en tercios. */
  --ril-grid-columns:    12;                       /* SET · rIL */
  --ril-grid-line-width: var(--border-width);      /* SET · rIL */
  /* --ril-grid-line-color: por tema, en OVERRIDES (B) */
  --ril-grid-inset-min: 10; --ril-grid-inset-max: 24;   /* SET · rIL · 10 px en móvil, 24 px en escritorio.
                                                           Figma dibuja canales entre columnas (10 y 24, y 6
                                                           columnas en móvil); el código mantiene 12 columnas
                                                           sin canal y con inset (decisión del 09/10/2026) */
  --ril-grid-inset: clamp(calc(var(--ril-grid-inset-min) * 1rem / 16), calc(var(--ril-grid-inset-min) * 1rem / 16 + (var(--ril-grid-inset-max) - var(--ril-grid-inset-min)) * var(--fluid)), calc(var(--ril-grid-inset-max) * 1rem / 16));

  /* ---- Sol (degradados de marca) ----------------------------------------
     Manchas de Amarillo Solar muy desenfocadas, con formas orgánicas, que
     se funden con el fondo y se mueven con el scroll. Las dibuja cada
     componente; aquí solo el color y el desenfoque. */
  --ril-sun-color:      var(--color-brand);                                       /* SET · rIL · a confirmar · centro del sol (Figma: amarillo al 100 %; antes 90 %) */
  --ril-sun-color-soft: color-mix(in srgb, var(--color-brand) 10%, transparent);  /* SET · rIL · a confirmar · borde del sol (Figma: amarillo al 10 %; antes 55 %) */
  /* desenfoque fluido en px (no en rem: no debe crecer con el zoom de texto) */
  --ril-sun-blur-min: 90; --ril-sun-blur-max: 180;                                /* SET · rIL · Figma: 90-190 en móvil, 200 en escritorio */
  --ril-sun-blur:       clamp(calc(var(--ril-sun-blur-min) * 1px), calc(var(--ril-sun-blur-min) * 1px + (var(--ril-sun-blur-max) - var(--ril-sun-blur-min)) * var(--fluid)), calc(var(--ril-sun-blur-max) * 1px));

  /* Brasa: paleta de los degradados de luz del Presupuestador (rIL 1.0):
     pie que se destapa, tarjeta oscura con arco de luz y sol que sigue el
     scroll. Del oro al negro pasando por naranja, rojo vino y noche. */
  --ril-glow-gold:   #FFC21A;   /* SET · rIL · Presupuestador */
  --ril-glow-amber:  #FFAE00;   /* SET · rIL · Presupuestador */
  --ril-glow-orange: #FF8A00;   /* SET · rIL · Presupuestador */
  --ril-glow-ember:  #E8610F;   /* SET · rIL · Presupuestador */
  --ril-glow-wine:   #782D28;   /* SET · rIL · Presupuestador */
  --ril-glow-night:  #301626;   /* SET · rIL · Presupuestador */
  --ril-glow-shadow: #1E0E1A;   /* SET · rIL · Presupuestador */
  --ril-glow-cream:  #FFD678;   /* SET · rIL · Presupuestador (rgba 255 214 120) */

  /* ---- Movimiento -------------------------------------------------------- */
  --ril-ease-out:       cubic-bezier(0.22, 0.8, 0.3, 1);  /* SET · rIL · salidas largas (fondos, soles) */
  --ril-reveal-dur:     1.2s;                             /* SET · rIL · aparición de bloques al hacer scroll */
  --ril-reveal-dist:    2.25rem;                          /* SET · rIL · 36 px de desplazamiento al aparecer */
  --ril-reveal-stagger: 70ms;                             /* SET · rIL · retraso entre elementos de una lista */
  /* Muelle «Quick» de Figma (Smart Animate del menú de servicios): masa 1,
     rigidez 300, amortiguación 20 (ζ ≈ 0,58, rebote del 11 %), 0,744 s.
     Muestreado en 40 pasos con linear(). */
  --ril-dur-quick:  744ms;                                /* SET · rIL */
  --ril-ease-quick: linear(0, 0.046, 0.159, 0.31, 0.473, 0.63, 0.771, 0.887, 0.977, 1.041, 1.082, 1.103, 1.108, 1.103, 1.09, 1.074, 1.056, 1.039, 1.024, 1.012, 1.002, 0.995, 0.991, 0.989, 0.988, 0.989, 0.99, 0.992, 0.994, 0.996, 0.997, 0.999, 1, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1);   /* SET · rIL */
}

} /* fin de @layer tokens */


/* ───── ril/fuentes-ril.css ───── */
/* ==========================================================================
   fuentes-ril.css  —  carga de Mona Sans · v1.0 · 09/10/2026
   Solo @font-face. Tamaños y pesos de uso: tokens-ril.css (3.1-3.5).

   ARCHIVOS  Mona Sans 2.000 variable (licencia OFL, ver OFL.txt):
               ejes wdth 75-125 (font-stretch) y wght 200-900.
               Sin eje opsz: --ril-font-variations ("opsz" 28) no tiene efecto.
             Servidos:  public/fonts/mona-sans/*.woff2  (subconjunto latino)
             Fuente:    resources/fonts/mona-sans/*.ttf (originales, no se sirven)
   SUBCONJUNTO  latín básico y Latin-1 (español completo), puntuación
             tipográfica (« » — ’ “ ”), €, ™, flechas ← ↑ → ↓ y todas las
             funciones OpenType (ss03, ss05, ss06…). Para regenerarlo:
               pyftsubset "MonaSans-VariableFont_wdth,wght.ttf"
                 --unicodes="U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2190-2193,U+2212,U+2215,U+FEFF,U+FFFD"
                 --layout-features='*' --flavor=woff2
                 --output-file=mona-sans-variable.woff2
             (pyftsubset es de fonttools: pip install fonttools brotli)
   CARGA     la redonda se precarga en el layout; la cursiva solo se
             descarga si algún texto la usa.
   ========================================================================== */

@font-face {
  font-family: "Mona Sans";
  src: url("/home-nueva/fonts/mona-sans/mona-sans-variable.woff2") format("woff2");
  font-weight: 200 900;
  font-stretch: 75% 125%;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Mona Sans";
  src: url("/home-nueva/fonts/mona-sans/mona-sans-variable-italic.woff2") format("woff2");
  font-weight: 200 900;
  font-stretch: 75% 125%;
  font-style: italic;
  font-display: swap;
}


/* ───── ril/base.css ───── */
/* ==========================================================================
   rIL · BASE  —  v3.3 · 09/10/2026
   v3.3  capa "tokens" (la primera): los temas pierden frente a cualquier capa;
         el tema oscuro se llama .theme-space; .eyebrow amplía su API
         (--eyebrow-fs -fw -ls -stretch).
   BASE FIJA: capas, reset, tipografía base, layout, componentes y utilidades.

   Es IGUAL para todas las marcas y para rIL. No se edita por proyecto: se
   personaliza reasignando tokens (ver 1.7) en el CSS de la marca o del proyecto.
   Solo lee tokens definidos en tokens.css; no contiene hex, rgb() ni valores
   de marca. Si falta un token, el componente cae a su valor por defecto.

   Requiere:  tokens.css cargado ANTES, abierto con la misma sentencia @layer
              que este archivo (ver más abajo) y con todo su contenido dentro
              de @layer tokens.
   La norma general (idioma, unidades, breakpoints, capas, prohibiciones) está
   en tokens.css, secciones 0 y 1.

   ÍNDICE
     1.  NORMA DE COMPONENTES   nombrado, estados, tokens de componente, variantes
     7.  @layer reset + base
     8.  @layer layout + components
     9.  @layer utilities + accesibilidad
     A.  APÉNDICE               mapa de nombres antiguos → nuevos
   ========================================================================== */


/* ==========================================================================
   1. NORMA DE COMPONENTES
   ========================================================================== 
   1.6 COMPONENTES
         Bloque      .btn
         Elemento    .btn__icon
         Variante    .btn--secondary    (modificador: cambia aspecto)
         Talla       .btn--sm .btn--lg  (modificador: cambia medidas)
         Estado      pseudo-clase nativa o ARIA:  :hover  :focus-visible
                     :disabled  [aria-disabled="true"]  [aria-invalid="true"]
                     [aria-expanded="true"]  [data-state="..."] si lo cambia JS.
                     Nunca clases .is-active / .active.
         Utilidad    .u-{nombre}   (una sola cosa, sin lógica)
         Tema        .theme-{nombre}

   1.7 TOKENS DE COMPONENTE (la forma de declarar variantes)
         Nombre:  --{bloque}-{propiedad}[-{estado}]     ej. --btn-bg, --btn-bg-hover
         Lectura: el componente lee su token con fallback a un token global:
                     background-color: var(--btn-bg, var(--color-primary));
                  El fallback ES el valor por defecto.
         Variante: una variante SOLO reasigna tokens de componente; no
                  declara propiedades CSS. Una variante nueva son 3-5 líneas:
                     .btn--danger { --btn-bg: var(--color-error); --btn-bg-hover: ... }
         Marca: para cambiar un componente en todo el proyecto basta
                  reasignar su token en :root  (ej. :root { --btn-radius: var(--radius-full); }).
         Alcance: un token de componente se asigna en el propio elemento o en
                  :root, nunca en un contenedor intermedio (se heredaría).
         API: cada componente documenta en su cabecera la lista de sus tokens
                  y el valor de fallback de cada uno.
         Excepción: una variante estructural (ej. .btn--block, .chamfer) puede
                  declarar propiedades; se documenta como "estructural".
   ========================================================================== */

/* Orden de capas. Manda la PRIMERA vez que se declara, por eso tokens.css
   (que se carga antes) repite esta misma línea: si no, "tokens" quedaría
   delante y el resto en el orden en que aparecieran.
     tokens      variables y temas: lo más débil, cualquier capa los pisa
                 (un .section--alt gana al fondo de un .theme-*)
     reset · base · layout · components · utilities
   El CSS sin capa (si lo hubiera) gana a todas: evitarlo. */
@layer tokens, reset, base, layout, components, utilities;


/* ==========================================================================
   7. @layer reset + base
   ========================================================================== */
@layer reset {
  *, *::before, *::after { box-sizing: border-box; }

  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    tab-size: 4;
    scroll-padding-top: calc(var(--header-height) + var(--space-sm));
  }
  @media (prefers-reduced-motion: no-preference) {
    html { scroll-behavior: smooth; }
  }

  body { margin: 0; }
  h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
  fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
  hr { border: 0; border-top: var(--border-width) solid var(--color-border); margin-block: var(--space-lg); }

  img, picture, video, canvas, svg { max-width: 100%; }
  img, video { height: auto; }
  button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
  button, [role="button"], summary { cursor: pointer; }
}

@layer base {
  :root { accent-color: var(--color-primary); }

  body {
    font-family: var(--font-body);
    font-size: var(--fs-body);
    font-weight: var(--fw-regular);
    line-height: var(--lh-normal);
    letter-spacing: var(--ls-normal);
    color: var(--color-text);
    background-color: var(--color-background);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-wrap: break-word;
  }

  /* Titulares: ver tokens.css, tabla 3.7 */
  h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-heading);
    font-weight: var(--fw-bold);
    color: var(--color-heading);
    line-height: var(--lh-snug);
    text-wrap: balance;
  }
  h1 { font-size: var(--fs-h1); line-height: var(--lh-tight); letter-spacing: var(--ls-tight); }
  h2 { font-size: var(--fs-h2); letter-spacing: var(--ls-tight); }
  h3 { font-size: var(--fs-h3); }
  h4 { font-size: var(--fs-h4); }
  h5, h6 { font-size: var(--fs-body); }

  p, li, figcaption { text-wrap: pretty; }
  small { font-size: var(--fs-small); }
  strong, b { font-weight: var(--fw-bold); }
  code, kbd, samp, pre { font-family: var(--font-mono); font-size: 0.95em; }

  a {
    color: var(--color-link);
    text-decoration-thickness: from-font;
    text-underline-offset: 0.2em;
    transition: color var(--dur-fast) var(--ease-standard);
  }
  a:hover { color: var(--color-link-hover); }

  /* Foco: único estilo de foco de todo el sitio */
  :focus-visible {
    outline: var(--focus-width) solid var(--color-focus);
    outline-offset: var(--focus-offset);
  }
  ::selection { background: color-mix(in srgb, var(--color-primary) 25%, transparent); }
}


/* ==========================================================================
   8. @layer layout + components
   ========================================================================== */
@layer layout {

  /* .container  ancho máximo y gutter.  Variante: --narrow */
  .ril-container {
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--container-pad);
  }
  .container--narrow { max-width: var(--container-narrow); }

  /* .section  bloque vertical de página.
     Tokens: --section-y (global).  Variantes: --sm --lg --alt
     Tema oscuro: <section class="section theme-space"> */
  .ril-section { padding-block: var(--section-y); }
  .section--sm  { --section-y: var(--space-xl); }
  .section--lg  { --section-y: var(--space-3xl); }
  .section--alt { background-color: var(--color-background-alt); }

  /* .flow  separa verticalmente los hijos directos.  Token: --flow-space */
  .flow > * + * { margin-top: var(--flow-space, var(--space-sm)); }
  .flow > :is(h2, h3, h4) { margin-top: var(--space-lg); }

  /* .cluster  fila que salta de línea.  Token: --cluster-gap */
  .cluster {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cluster-gap, var(--space-sm));
  }
}

@layer components {

  /* ------------------------------------------------------------------------
     COMPONENTE: .btn                                    (ejemplo de referencia)
     Elementos:  .btn__icon
     Variantes:  --secondary --ghost --inverse --glass --gradient
     Tallas:     --sm --lg        Estructurales: --block --caps
     API (token · fallback):
       --btn-bg       · var(--color-primary)        --btn-bg-hover     · var(--color-primary-hover)
       --btn-fg       · var(--color-on-primary)     --btn-fg-hover     · = --btn-fg
       --btn-border   · transparent                 --btn-border-hover · = --btn-border
       --btn-radius   · var(--radius-md)            --btn-shadow-hover · var(--shadow-md)
       --btn-pad-y    · var(--space-xs)             --btn-pad-x        · var(--space-md)
       --btn-fs       · var(--fs-body)              --btn-fw           · var(--fw-medium)
       --btn-ls       · var(--ls-normal)            --btn-min-h        · var(--control-height)
     ------------------------------------------------------------------------ */
  .ril-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2xs);
    min-height: var(--btn-min-h, var(--control-height));
    padding: var(--btn-pad-y, var(--space-xs)) var(--btn-pad-x, var(--space-md));
    font-family: var(--font-body);
    font-size: var(--btn-fs, var(--fs-body));
    font-weight: var(--btn-fw, var(--fw-medium));
    line-height: var(--lh-tight);
    letter-spacing: var(--btn-ls, var(--ls-normal));
    text-decoration: none;
    white-space: nowrap;
    color: var(--btn-fg, var(--color-on-primary));
    background-color: var(--btn-bg, var(--color-primary));
    border: var(--border-width) solid var(--btn-border, transparent);
    border-radius: var(--btn-radius, var(--radius-md));
    transition:
      color var(--dur-base) var(--ease-standard),
      background-color var(--dur-base) var(--ease-standard),
      border-color var(--dur-base) var(--ease-standard),
      box-shadow var(--dur-base) var(--ease-standard),
      transform var(--dur-base) var(--ease-standard);
  }
  .ril-btn:hover {
    color: var(--btn-fg-hover, var(--btn-fg, var(--color-on-primary)));
    background-color: var(--btn-bg-hover, var(--color-primary-hover));
    border-color: var(--btn-border-hover, var(--btn-border, transparent));
    box-shadow: var(--btn-shadow-hover, var(--shadow-md));
  }
  .ril-btn:active { transform: translateY(1px); box-shadow: var(--shadow-sm); }

  .btn--secondary {
    --btn-bg: transparent;           --btn-bg-hover: var(--color-primary-soft);
    --btn-fg: var(--color-primary);
    --btn-border: var(--color-primary);
    --btn-shadow-hover: none;
  }
  .btn--ghost {
    --btn-bg: transparent;           --btn-bg-hover: var(--color-primary-soft);
    --btn-fg: var(--color-link);
    --btn-shadow-hover: none;
  }
  /* inverso del contexto: fondo claro sobre tema oscuro y viceversa */
  .btn--inverse {
    --btn-bg: var(--color-text);     --btn-bg-hover: color-mix(in srgb, var(--color-text) 88%, transparent);
    --btn-fg: var(--color-background);
  }
  .btn--glass {
    --btn-bg: var(--glass-bg);       --btn-bg-hover: var(--glass-bg-strong);
    --btn-fg: var(--color-text);
    --btn-border: var(--glass-border);
    --btn-shadow-hover: none;
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));      /* estructural */
  }
  /* estructural: degradado animado con las mismas dos paradas */
  .btn--gradient {
    --btn-bg: transparent;           --btn-bg-hover: transparent;
    background-image: linear-gradient(var(--gradient-angle), var(--gradient-from), var(--gradient-to), var(--gradient-from));
    background-size: 200% 100%;
    background-position: 0 0;
    transition-property: background-position, box-shadow, transform;
  }
  .btn--gradient:hover { background-position: 100% 0; }

  .btn--sm { --btn-min-h: 2.25rem; --btn-pad-y: var(--space-2xs); --btn-pad-x: var(--space-sm); --btn-fs: var(--fs-small); }
  .btn--lg { --btn-min-h: 3.5rem;  --btn-pad-y: var(--space-sm);  --btn-pad-x: var(--space-lg); --btn-fs: var(--fs-lead); }
  .btn--block { display: flex; width: 100%; }                                           /* estructural */
  .btn--caps  { --btn-fs: var(--fs-small); --btn-ls: var(--ls-wide); text-transform: uppercase; } /* estructural; tokens.css 3.7 */

  .ril-btn:disabled,
  .ril-btn[aria-disabled="true"] {
    color: var(--color-disabled-text);
    background-color: var(--color-disabled-bg);
    background-image: none;
    border-color: transparent;
    box-shadow: none;
    cursor: not-allowed;
    pointer-events: none;
  }

  /* ------------------------------------------------------------------------
     .link-arrow   enlace con flecha.   Tokens: --link-arrow-gap · var(--space-2xs)
     ------------------------------------------------------------------------ */
  .link-arrow {
    display: inline-flex;
    align-items: center;
    gap: var(--link-arrow-gap, var(--space-2xs));
    font-weight: var(--fw-medium);
    text-decoration: none;
  }
  .link-arrow::after {
    content: "\2192";
    content: "\2192" / "";            /* texto alternativo vacío: no se lee la flecha */
    transition: transform var(--dur-base) var(--ease-standard);
  }
  .link-arrow:hover::after { transform: translateX(0.25em); }

  /* ------------------------------------------------------------------------
     .pill   etiqueta redondeada.   Variantes: --outline
     Tokens: --pill-bg · var(--color-primary-soft)   --pill-fg · var(--color-primary)
             --pill-border · transparent
     ------------------------------------------------------------------------ */
  .pill {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3xs);
    padding: var(--space-3xs) var(--space-xs);
    font-size: var(--fs-small);
    font-weight: var(--fw-medium);
    line-height: var(--lh-tight);
    color: var(--pill-fg, var(--color-primary));
    background-color: var(--pill-bg, var(--color-primary-soft));
    border: var(--border-width) solid var(--pill-border, transparent);
    border-radius: var(--radius-full);
  }
  .pill--outline { --pill-bg: transparent; --pill-fg: var(--color-text-muted); --pill-border: var(--color-border); }

  /* ------------------------------------------------------------------------
     .eyebrow   antetítulo en mayúsculas (tokens.css, tabla 3.7).
     API (token · fallback):
       --eyebrow-fg      · var(--color-primary)   --eyebrow-fs · var(--fs-small)
       --eyebrow-fw      · var(--fw-medium)       --eyebrow-ls · var(--ls-wider)
       --eyebrow-stretch · normal                 (ancho de la fuente variable)
     ------------------------------------------------------------------------ */
  .eyebrow {
    display: block;
    font-size: var(--eyebrow-fs, var(--fs-small));
    font-weight: var(--eyebrow-fw, var(--fw-medium));
    font-stretch: var(--eyebrow-stretch, normal);
    line-height: var(--lh-tight);
    letter-spacing: var(--eyebrow-ls, var(--ls-wider));
    text-transform: uppercase;
    color: var(--eyebrow-fg, var(--color-primary));
  }

  /* ------------------------------------------------------------------------
     .text-gradient   texto con degradado de marca (estructural).
     ------------------------------------------------------------------------ */
  .text-gradient {
    color: var(--color-primary);              /* fallback si no hay background-clip */
    background-image: var(--gradient-primary);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
  }

  /* ------------------------------------------------------------------------
     .card   contenedor elevado.   Variantes: --interactive
     Tokens: --card-bg · var(--color-surface)   --card-radius · var(--radius-lg)
             --card-pad · var(--space-md)       --card-shadow · var(--shadow-sm)
             --card-shadow-hover · var(--shadow-md)
     ------------------------------------------------------------------------ */
  .card {
    padding: var(--card-pad, var(--space-md));
    color: var(--color-text);
    background-color: var(--card-bg, var(--color-surface));
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--card-radius, var(--radius-lg));
    box-shadow: var(--card-shadow, var(--shadow-sm));
  }
  .card--interactive {
    transition: box-shadow var(--dur-base) var(--ease-standard), transform var(--dur-base) var(--ease-standard);
  }
  .card--interactive:hover { box-shadow: var(--card-shadow-hover, var(--shadow-md)); transform: translateY(-2px); }

  /* ------------------------------------------------------------------------
     .glass   superficie de cristal.   Variantes: --strong
     Tokens: --glass-radius · var(--radius-lg)
     Funciona en tema claro y oscuro (los tokens --glass-* cambian por tema, ver 5.2).
     ------------------------------------------------------------------------ */
  .glass {
    background-color: var(--glass-bg);
    border: var(--border-width) solid var(--glass-border);
    border-radius: var(--glass-radius, var(--radius-lg));
    box-shadow: var(--glass-shadow);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
  }
  .glass--strong { background-color: var(--glass-bg-strong); }

  /* ------------------------------------------------------------------------
     .chamfer   esquina cortada (estructural; superior-derecha e inferior-izquierda).
     Variantes (solo reasignan --chamfer-size): --sm --lg
     No dibuja línea: border no sigue a clip-path. Un componente concreto que
     necesite contorno lo resuelve en su propia clase con --chamfer-line.
     Con --chamfer-size: 0px no tiene efecto.
     ------------------------------------------------------------------------ */
  .chamfer {
    clip-path: polygon(
      0 0,
      calc(100% - var(--chamfer-size)) 0,
      100% var(--chamfer-size),
      100% 100%,
      var(--chamfer-size) 100%,
      0 calc(100% - var(--chamfer-size))
    );
  }
  .chamfer--sm { --chamfer-size: var(--space-sm); }
  .chamfer--lg { --chamfer-size: var(--space-lg); }

  /* ------------------------------------------------------------------------
     Formularios.   .field (bloque) · .field__label .field__help .field__error
                    .input (control: input, select, textarea)
     Tokens: --input-radius · var(--radius-md)   --input-bg · var(--color-surface)
     Estados: :hover :focus-visible :disabled [aria-invalid="true"]
     ------------------------------------------------------------------------ */
  .field { display: flex; flex-direction: column; gap: var(--space-2xs); }
  .field__label { font-size: var(--fs-small); font-weight: var(--fw-medium); color: var(--color-text); }
  .field__help  { font-size: var(--fs-small); color: var(--color-text-muted); }
  .field__error { font-size: var(--fs-small); color: var(--color-error); }

  .input {
    width: 100%;
    min-height: var(--control-height);
    padding: var(--space-2xs) var(--space-sm);
    color: var(--color-text);
    background-color: var(--input-bg, var(--color-surface));
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--input-radius, var(--radius-md));
    transition: border-color var(--dur-fast) var(--ease-standard), box-shadow var(--dur-fast) var(--ease-standard);
  }
  textarea.input { min-height: 8rem; resize: vertical; }
  .input::placeholder { color: var(--color-text-muted); opacity: 1; }
  .input:hover { border-color: var(--color-border-strong); }
  .input:focus-visible {
    outline: none;
    border-color: var(--color-focus);
    box-shadow: 0 0 0 var(--focus-width) color-mix(in srgb, var(--color-focus) 35%, transparent);
  }
  .input[aria-invalid="true"] { border-color: var(--color-error); }
  .input[aria-invalid="true"]:focus-visible {
    box-shadow: 0 0 0 var(--focus-width) color-mix(in srgb, var(--color-error) 35%, transparent);
  }
  .input:disabled {
    color: var(--color-disabled-text);
    background-color: var(--color-disabled-bg);
    cursor: not-allowed;
  }

  /* ------------------------------------------------------------------------
     PLANTILLA PARA UN COMPONENTE NUEVO (copiar, renombrar, borrar lo que sobre)
       .alert {
         padding: var(--alert-pad, var(--space-sm));
         color: var(--alert-fg, var(--color-text));
         background-color: var(--alert-bg, var(--color-info-soft));
         border: var(--border-width) solid var(--alert-border, var(--color-info));
         border-radius: var(--alert-radius, var(--radius-md));
       }
       .alert--error { --alert-bg: var(--color-error-soft); --alert-border: var(--color-error); }
     ------------------------------------------------------------------------ */
}


/* ==========================================================================
   9. @layer utilities + accesibilidad
   ========================================================================== */
@layer utilities {
  .u-visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
  .u-skip-link {
    position: absolute; left: var(--space-sm); top: -4rem; z-index: var(--z-toast);
    padding: var(--space-2xs) var(--space-sm);
    color: var(--color-on-primary); background: var(--color-primary);
    border-radius: var(--radius-sm);
  }
  .u-skip-link:focus { top: var(--space-sm); }

  .u-text-center { text-align: center; }
  .u-text-muted  { color: var(--color-text-muted); }
  .u-small       { font-size: var(--fs-small); }
  .u-lead        { font-size: var(--fs-lead); line-height: var(--lh-snug); }
  .u-display     { font-size: var(--fs-display); line-height: var(--lh-tight); letter-spacing: var(--ls-tight); }
  .u-prose       { line-height: var(--lh-relaxed); }
  .u-caps        { text-transform: uppercase; letter-spacing: var(--ls-wider); }

  /* Visibilidad por breakpoint (0.4) */
  @media (width < 48em)  { .u-hide-below-md { display: none; } }
  @media (width >= 48em) { .u-hide-from-md  { display: none; } }
  @media (width < 64em)  { .u-hide-below-lg { display: none; } }
  @media (width >= 64em) { .u-hide-from-lg  { display: none; } }
}

/* ---- 9.2 MOVIMIENTO REDUCIDO -------------------------------------------
   SIEMPRE activo: forma parte de la base y no se puede quitar del import.
   Va en la primera capa y con !important para ganar a cualquier CSS del
   proyecto (es la única excepción permitida de !important, ver 0.5).
   Los carruseles o rotadores controlados por JS deben comprobar además
   window.matchMedia("(prefers-reduced-motion: reduce)").matches.
   ----------------------------------------------------------------------- */
@layer reset {
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }
}


/* ==========================================================================
   A. APÉNDICE · MAPA DE NOMBRES ANTIGUOS → NUEVOS (migración)
   ==========================================================================
     --color-oscuro / -marca / -blanco / -claro / -acento
                                   → --color-dark / -brand / -white / -light / -accent
     --color-marca-suave           → --color-primary-soft (derivado)
     --color-oscuro-transparente,
     --color-marca-rgb             → color-mix(in srgb, var(--color-X) N%, transparent)
     --color-fondo / -fondo-alt    → --color-background / --color-background-alt
     --color-texto / -titulo       → --color-text / --color-heading
     --color-enlace / -borde       → --color-link / --color-border
     --color-text-on-dark          → (eliminado) --color-text dentro de .theme-space
     --color-text-muted-on-dark    → (eliminado) --color-text-muted dentro de .theme-space
     --font-weight-* / --peso-*    → --fw-*
     --lh-heading / --lh-body      → --lh-snug / --lh-normal
     --ls-caps / --ls-heading      → --ls-wider / --ls-tight
     --radius-pill                 → --radius-full
     --gradient-text               → (eliminado) --gradient-primary
     --ease                        → --ease-standard
     --chaflan / --btn-chaflan     → --chamfer-size
     --chaflan-grosor / --btn-linea-grosor → --chamfer-line
     .txt-blanco / .theme-dark     → .theme-space    (v3.3)
   ========================================================================== */


/* ───── ril/marca-ril.css ───── */
/* ==========================================================================
   marca-ril.css  —  capa de marca rIL · v1.6 · 11/10/2026
   v1.6  .u-subp (subpárrafo); <main> tapa el pie (que se destapa al final);
         sin línea clara entre dos bloques oscuros seguidos.
   v1.5  .eyebrow con interlineado 1,2; saltos y contenido de un solo frame
         (.u-br-mobile/-desktop, .u-only-mobile/-desktop); .u-expanded lee
         --u-expanded-stretch (la sección decide su ancho en reposo).
   v1.4  .text-gradient--x (degradado horizontal de «360°» y «BRILLAR»).
   v1.3  botón con radio de 8 px y tallas con --fs-btn-* (tokens-ril.css
         v1.3); .alert lee --radius-small. Los colores de marca (Figma:
         #F6A700, #FBF9F4) solo viven en tokens-ril.css: aquí no hay hex.
   v1.2  tallas del botón con la escala de rIL; .eyebrow pasa a tokens
         (tokens-ril.css, OVERRIDES A); .alert lee --color-*-fill y
         --alert-glyph-size.
   v1.1  propuesta de .alert (PENDIENTE DE REVISIÓN).
   Base de marca: común a todos los proyectos de rIL (web, Presupuestador).
   Va justo DESPUÉS de base.css y ANTES de components/.

   PARA QUÉ   lo que la marca necesita y no se puede expresar solo con tokens:
              mayúsculas y ancho condensado de los titulares, juegos
              estilísticos de Mona Sans. Solo ajusta elementos y componentes
              que ya existen en base.css; los componentes nuevos van en
              components/ (.alert se mueve allí cuando se apruebe).
   CÓMO       sin capas nuevas: añade reglas a las capas que declara base.css
              (base, components, utilities). Como se carga después, a igual
              especificidad gana a base.css, y el CSS de componentes y de
              página sigue pudiendo sobrescribirlo todo.
   REGLA      no lleva valores sueltos: solo lee tokens de tokens-ril.css
              (salvo los glifos SVG y los fallbacks de tamaño de .alert).
   PENDIENTE  el bloque final (.alert) es una propuesta sin aprobar.
   ========================================================================== */


/* ---- base: tipografía de rIL (tokens-ril.css, tabla 3.7) ---------------- */
@layer base {

  body {
    font-feature-settings: var(--ril-font-features);
    font-variation-settings: var(--ril-font-variations);
    font-synthesis: none;            /* fuente variable: nunca negritas ni cursivas falsas */
  }
  /* los controles no siempre heredan los ajustes de la fuente */
  button, input, select, textarea {
    font-feature-settings: inherit;
    font-variation-settings: inherit;
  }

  /* titulares: 850, condensados al 77 % y en mayúsculas */
  h1, h2, h3, h4 {
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    text-transform: uppercase;
  }
  h2, h3 { line-height: var(--lh-tight); }

  /* anclas sin JS: el destino no queda bajo la cabecera fija (con JS lo
     resuelve smooth-scroll.js) */
  [id] { scroll-margin-top: var(--header-height); }

  /* dos bloques oscuros seguidos: el borde entre ambos cae en medio píxel
     (alturas fluidas) y el navegador deja ver una línea del fondo claro de
     la página. El segundo extiende su fondo 1 px hacia arriba, por debajo
     del primero, y la tapa. */
  .theme-space + .theme-space { box-shadow: 0 -1px 0 0 var(--color-background); }

  /* el contenido tapa el pie: el pie está siempre detrás (site-footer.css)
     y el último bloque lo destapa al subir. main lleva fondo propio y
     recorta lo que sobresale por abajo (soles), que si no flotaría sobre el pie */
  #contenido {
    position: relative;
    z-index: 1;
    /* fondo claro salvo los 2 últimos px, que pone el último bloque con su
       propio fondo: el borde inferior cae en medio píxel y, si no, se
       vería una línea clara sobre el pie */
    background: linear-gradient(var(--color-background), var(--color-background)) top / 100% calc(100% - 2px) no-repeat;
    overflow-y: clip;
    /* también por debajo de la cabecera (que no tiene fondo): si no, en lo
       alto de la página se vería el pie a través de ella */
    margin-top: calc(-1 * var(--header-height));
    padding-top: var(--header-height);
  }
  #contenido > :last-child { background-color: var(--color-background); }
  /* los bloques se pintan sobre el sol de fondo (.aura, fijo): los claros lo
     dejan ver (sin fondo); los oscuros lo tapan con el suyo */
  #contenido > :not(.aura) { position: relative; }

  /* h5 y h6: etiqueta pequeña en mayúsculas (rol h5 del Presupuestador) */
  h5, h6 {
    font-size: var(--fs-h5);
    font-weight: var(--fw-regular);
    font-stretch: var(--ril-stretch-condensed);
    line-height: var(--lh-tight);
    letter-spacing: var(--ls-wider);
    text-transform: uppercase;
  }
}


/* ---- components: ajustes de marca de los componentes de base.css ------- */
@layer components {

  /* .btn  radio de 8 px y mayúsculas (tokens en tokens-ril.css, OVERRIDES).
     El círculo amarillo con flecha del Presupuestador será .btn__icon,
     cuando se defina el componente con Figma. */
  .ril-btn { text-transform: uppercase; }

  /* .eyebrow  interlineado de Figma (1,2) y color del texto */
  .eyebrow { line-height: var(--lh-label); }

  /* .btn--secondary  contorno del color del texto; al pasar por encima se
     rellena de amarillo, como el botón principal. */
  .btn--secondary {
    --btn-bg:           transparent;
    --btn-fg:           var(--color-text);
    --btn-border:       var(--color-text);
    --btn-bg-hover:     var(--color-primary);
    --btn-fg-hover:     var(--color-on-primary);
    --btn-border-hover: var(--color-primary);
  }

  /* tallas: base.css las calcula con su propia escala (--fs-small,
     --fs-lead); rIL usa los tamaños de botón de tokens-ril.css (3.5):
       normal  --fs-btn-small (= h4): «Ver más», «Conócenos»
       sm      misma letra, menos alto (36 px) y menos aire
       lg      un paso más: --fs-btn-cta (= h3), 56 px de alto · revisar con Figma
     El enlace con forma de titular («OPAL DENTAL STUDIO», --fs-btn-large)
     no es un .btn: lo resuelve su componente.
     .btn--caps no hace falta en rIL (todos los botones van en mayúsculas):
     se neutraliza para que no cambie el tamaño. */
  .btn--sm   { --btn-fs: var(--fs-btn-small); }
  .btn--lg   { --btn-fs: var(--fs-btn-cta); }
  .btn--caps { --btn-fs: var(--fs-btn-small); }
}


/* ---- utilities: estilos de texto de rIL sin elemento propio ------------ */
@layer utilities {

  /* .u-display  titular de portada (completa la utilidad de base.css) */
  .u-display {
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    text-transform: uppercase;
  }

  /* .u-stat  cifra grande: «+10 años», «50 %». Nunca se anima si es un
     precio o un porcentaje. */
  .u-stat {
    font-size: var(--fs-stat);
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    line-height: var(--lh-tight);
    letter-spacing: var(--ls-tight);
    font-variant-numeric: lining-nums;
  }

  /* .u-lead  entradilla: en rIL respira más que en la plantilla */
  .u-lead { line-height: var(--lh-normal); }

  /* .u-brand  el nombre «rIL» tal cual (r minúscula, IL mayúsculas), también
     dentro de titulares en mayúsculas. Lo pone el filtro marks */
  .u-brand { text-transform: none; }

  /* .u-subp  subpárrafo: texto secundario que amplía un párrafo anterior
     (p. ej. el desplegable de herramientas bajo su intro). Un paso menor
     que el cuerpo (--fs-subp: 15 en móvil, 16 en escritorio) y en el color
     del texto al 72 % (pesa menos). */
  .u-subp { font-size: var(--fs-subp); line-height: var(--lh-normal); color: color-mix(in srgb, currentColor 72%, transparent); }

  /* .u-expanded  letra ancha dentro de un titular (una por palabra, dos
     como máximo). Como en el Presupuestador: en reposo está ancha (110 %);
     donde se anima, parte estrecha (75 %) y se ensancha en 1,8 s cuando su
     bloque entra en pantalla, desplazando el resto de la línea. La dispara
     un ancestro: .u-expanded--play (al cargar) o [data-reveal="in"]
     (reveal.js, al entrar en pantalla). */
  .u-expanded { font-stretch: var(--u-expanded-stretch, var(--ril-stretch-expanded)); }
  :is(.u-expanded--play, [data-reveal]) .u-expanded { font-stretch: var(--u-expanded-from, var(--ril-stretch-expanded-from)); }
  :is(.u-expanded--play, [data-reveal="in"]) .u-expanded {
    animation: u-expanded-stretch var(--u-expanded-dur, 1.8s) var(--ease-in-out) var(--u-expanded-delay, 0.25s) forwards;
  }
  @keyframes u-expanded-stretch {
    from { font-stretch: var(--u-expanded-from, var(--ril-stretch-expanded-from)); }
    to   { font-stretch: var(--u-expanded-stretch, var(--ril-stretch-expanded)); }
  }
  @media (prefers-reduced-motion: reduce) {
    :is(.u-expanded--play, [data-reveal]) .u-expanded { animation: none; font-stretch: var(--u-expanded-stretch, var(--ril-stretch-expanded)); }
  }

  /* saltos de línea de un solo frame (marcas | y ^ en los datos) */
  @media (width >= 48em) { .u-br-mobile  { display: none; } }
  @media (width < 48em)  { .u-br-desktop { display: none; } }
  /* contenido de un solo frame (Figma cambia textos entre móvil y escritorio) */
  @media (width >= 48em) { .u-only-mobile  { display: none; } }
  @media (width < 48em)  { .u-only-desktop { display: none; } }
}


/* ---- components: variantes de marca de componentes de base.css --------- */
@layer components {

  /* .text-gradient--x  degradado de marca en horizontal (Figma: «360°» y
     «BRILLAR», de un amarillo muy claro a Amarillo Solar). Reasigna el token
     en el propio elemento. La primera parada mezcla un 25 % de amarillo en
     la crema para que se lea también sobre fondo crema. */
  .text-gradient--x {
    --gradient-primary: linear-gradient(90deg, color-mix(in srgb, var(--gradient-to) 25%, var(--gradient-from)), var(--gradient-to));
  }
}


/* ==========================================================================
   PENDIENTE DE REVISIÓN · propuesta del 09/10/2026
   Estados de feedback: correcto, aviso, error e información.
   No está aprobado: no usar en producción hasta que el equipo lo valide.
   ========================================================================== */
@layer components {

  /* ------------------------------------------------------------------------
     COMPONENTE: .alert                               PENDIENTE DE REVISIÓN
     Mensaje de estado. Sigue la marca aprobada:
       - caja sobria: superficie del tema, filete de 1 px y radio de 8 px,
         sin fondos tintados ni sombras;
       - el estado lo marca un círculo de 30 px con su glifo, el mismo
         recurso que el círculo amarillo de los botones;
       - título como los de la marca (850, condensado, mayúsculas) en el
         color de texto del estado; el texto sigue en el color del texto;
       - el color nunca es la única pista: cada estado tiene su glifo
         (✓ correcto, ! aviso, × error, i información) y su título.
       - el naranja solo aparece en los avisos y el amarillo, en la
         información.
     Elementos:  .alert__icon  .alert__body  .alert__title  .alert__text
     Variantes:  --success --warning --error --info
     Estructural: --inline  (sin caja, icono pequeño; mensajes bajo un campo)
     API (token · fallback):
       --alert-bg        · var(--color-surface)      --alert-border   · var(--color-border)
       --alert-radius    · var(--radius-small)       --alert-pad      · var(--space-md)
       --alert-icon-size · 1.875rem                  --alert-title    · var(--color-text)
       --alert-glyph-size · 55%                      glifo dentro del círculo
       --alert-accent    · var(--color-text)         relleno del círculo
       --alert-on-accent · var(--color-background)   color del glifo
       --alert-glyph     · glifo «i»                 máscara SVG del glifo
     Contraste: títulos ≥ 4,5:1 sobre la superficie de los tres temas;
       glifos ≥ 4,7:1 sobre su círculo. El círculo amarillo de información
       no llega a 3:1 sobre blanco: lo sostiene el glifo negro (10,4:1).
     Accesibilidad: role="status" para correcto e información; role="alert"
       solo para errores o avisos que interrumpen. Icono con aria-hidden="true".
     HTML:
       <div class="alert alert--warning" role="status">
         <span class="alert__icon" aria-hidden="true"></span>
         <div class="alert__body">
           <p class="alert__title">Falta un dato</p>
           <p class="alert__text">Indicad la fecha del evento para cerrar el presupuesto.</p>
         </div>
       </div>
     ------------------------------------------------------------------------ */
  .ril-alert {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: var(--space-sm);
    align-items: start;
    padding: var(--alert-pad, var(--space-md));
    color: var(--color-text);
    background-color: var(--alert-bg, var(--color-surface));
    border: var(--border-width) solid var(--alert-border, var(--color-border));
    border-radius: var(--alert-radius, var(--radius-small));
  }

  .alert__icon {
    display: grid;
    place-items: center;
    width: var(--alert-icon-size, 1.875rem);
    aspect-ratio: 1;
    border-radius: var(--radius-full);
    background-color: var(--alert-accent, var(--color-text));
  }
  .alert__icon::before {
    content: "";
    width: var(--alert-glyph-size, 55%);
    aspect-ratio: 1;
    background-color: var(--alert-on-accent, var(--color-background));
    -webkit-mask: var(--alert-glyph, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='8' cy='3.6' r='1.1' fill='black' stroke='none'/%3E%3Cpath d='M8 6.8v6'/%3E%3C/svg%3E")) center / contain no-repeat;
    mask: var(--alert-glyph, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='8' cy='3.6' r='1.1' fill='black' stroke='none'/%3E%3Cpath d='M8 6.8v6'/%3E%3C/svg%3E")) center / contain no-repeat;
  }

  /* el título se centra con el círculo */
  .alert__body { padding-top: calc((var(--alert-icon-size, 1.875rem) - var(--fs-h4) * var(--lh-tight)) / 2); }
  .alert__title {
    font-size: var(--fs-h4);
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    line-height: var(--lh-tight);
    text-transform: uppercase;
    color: var(--alert-title, var(--color-text));
  }
  .alert__text { font-size: var(--fs-small); line-height: var(--lh-normal); }
  .alert__title + .alert__text { margin-top: var(--space-2xs); }

  .alert--success {
    --alert-accent: var(--color-success-fill);  --alert-on-accent: var(--color-surface);
    --alert-title:  var(--color-success);
    --alert-glyph:  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E");
  }
  .alert--warning {
    --alert-accent: var(--color-warning-fill);  --alert-on-accent: var(--color-dark);
    --alert-title:  var(--color-warning);
    --alert-glyph:  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 3.2v6'/%3E%3Ccircle cx='8' cy='12.4' r='1.1' fill='black' stroke='none'/%3E%3C/svg%3E");
  }
  .alert--error {
    --alert-accent: var(--color-error-fill);    --alert-on-accent: var(--color-surface);
    --alert-title:  var(--color-error);
    --alert-glyph:  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 4.5l7 7M11.5 4.5l-7 7'/%3E%3C/svg%3E");
  }
  .alert--info {
    --alert-accent: var(--color-info-fill);     --alert-on-accent: var(--color-dark);
    --alert-title:  var(--color-text);
    --alert-glyph:  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='8' cy='3.6' r='1.1' fill='black' stroke='none'/%3E%3Cpath d='M8 6.8v6'/%3E%3C/svg%3E");
  }

  /* estructural: sin caja, icono de 20 px y texto alineado con él */
  .alert--inline {
    --alert-bg: transparent;  --alert-border: transparent;  --alert-pad: 0;
    --alert-icon-size: 1.25rem;
    column-gap: var(--space-2xs);
    align-items: center;
  }
  .alert--inline .alert__body { padding-top: 0; }
}


/* proyecto */

/* ───── components/_index.css ───── */
/* ==========================================================================
   components/  —  un archivo por componente nuevo · @layer components
   Qué es un componente: un bloque BEM que se pinta igual esté donde esté.
   No lleva márgenes externos ni posición en la retícula (eso es de sections/).
   Plantilla: _plantilla.css (copiar, renombrar, sumar aquí una línea).
   Los componentes que ya da base.css (.btn, .card, .pill, .eyebrow…) NO
   se repiten aquí: se ajustan con tokens o en marca-ril.css.
   ========================================================================== */


/* ───── components/icon.css ───── */
/* ==========================================================================
   COMPONENTES: .icon · .logo                             v1.0 · 09/10/2026
   .icon   icono de 1em; los de línea (flechas) usan trazo en currentColor.
           API: --icon-size · 1em    --icon-stroke · 2.5 (unidades del viewBox de 24)
   .logo   logotipo de rIL; letras en currentColor, punto en --color-brand.
           API: --logo-h · 1em (alto; el ancho sale de la proporción 2:1)
   Vistas: components/ril/icon.njk · components/ril/logo.njk
   ========================================================================== */
@layer components {

  .icon {
    display: inline-block;
    flex: none;
    width: var(--icon-size, 1em);
    height: var(--icon-size, 1em);
    fill: currentColor;
    vertical-align: middle;
  }
  .icon--line {
    fill: none;
    stroke: currentColor;
    stroke-width: var(--icon-stroke, 2.5);
    stroke-linejoin: round;
  }

  .logo {
    display: block;
    height: var(--logo-h, 1em);
    width: auto;
    aspect-ratio: 2 / 1;
  }
  .logo__dot { fill: var(--color-brand); }

}


/* ───── components/tag.css ───── */
/* ==========================================================================
   COMPONENTE: .tag                                       v1.0 · 09/10/2026
   Figma:      «Frame 274…299» dentro de menu-servicios (6281:2145); también
               en el hero (FOTOGRAFÍA, VÍDEO…) y en los proyectos.
   Qué hace:   etiqueta amarilla con texto de titular (850, condensado,
               mayúsculas). Distinta de .pill (base.css), que es texto normal
               sobre tinte suave.
   API (token · fallback):
     --tag-bg      · var(--color-primary)       --tag-fg     · var(--color-on-primary)
     --tag-fs      · var(--fs-h3)               --tag-radius · var(--radius-small)
     --tag-pad-y   · var(--space-3xs)           --tag-pad-x  · var(--space-sm)
   Vista:      resources/views/components/ril/tag.njk (o la clase en un <li>)
   ========================================================================== */
@layer components {

  .tag {
    display: inline-block;
    padding: var(--tag-pad-y, var(--space-3xs)) var(--tag-pad-x, var(--space-sm));
    font-size: var(--tag-fs, var(--fs-h3));
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    line-height: var(--lh-tight);
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--tag-fg, var(--color-on-primary));
    background-color: var(--tag-bg, var(--color-primary));
    border-radius: var(--tag-radius, var(--radius-small));
  }

}


/* ───── components/link-more.css ───── */
/* ==========================================================================
   COMPONENTE: .link-more                                 v1.1 · 11/10/2026
   Figma:      «Frame 205» (VER MÁS) y «Frame 305» (CONÓCENOS).
   Qué hace:   enlace de llamada en mayúsculas con flecha y filete inferior.
               Al pasar el puntero, la flecha avanza, el filete se alarga y
               aparece una etiqueta amarilla ladeada (opcional) encima.
   Elementos:  __label  __icon  __tag (usa .tag)
   API (token · fallback):
     --link-more-fs  · var(--fs-btn-small)     --link-more-gap · 0.92em (Figma: 18,4 a 20 px)
     --link-more-line · 1.5px (Figma: trazo de 1,5 bajo texto y flecha, 8 px por debajo)
     --link-more-tag-gap · var(--space-2xs) (separación de la etiqueta amarilla sobre el enlace)
   Estados:    :hover :focus-visible
   Vista:      components/ril/link-more.njk
   ========================================================================== */
@layer components {

  .link-more {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--link-more-gap, 0.92em);
    padding-bottom: 0.4em;
    font-size: var(--link-more-fs, var(--fs-btn-small));
    font-weight: var(--fw-regular);
    font-stretch: var(--ril-stretch-cta);
    line-height: var(--lh-label);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    text-decoration: none;
    color: inherit;
    background: linear-gradient(currentColor, currentColor) left bottom / 100% var(--link-more-line, 1.5px) no-repeat;
    transition: background-size var(--dur-base) var(--ease-standard);
  }
  .link-more__icon {
    --icon-size: 0.875em;
    transition: transform var(--dur-base) var(--ease-standard);
  }
  .link-more__tag {
    position: absolute;
    left: -2.5em;
    bottom: 100%;
    margin-bottom: var(--link-more-tag-gap, var(--space-2xs));
    opacity: 0;
    transform: rotate(-8deg) scale(0.6);
    transform-origin: bottom left;
    pointer-events: none;
    transition: opacity var(--dur-base) var(--ease-standard), transform var(--dur-base) var(--ease-standard);
  }

  .link-more:is(:hover, :focus-visible) { background-size: 100% var(--link-more-line, 1.5px); }
  .link-more:is(:hover, :focus-visible) .link-more__icon { transform: translateX(0.4em); }
  .link-more:is(:hover, :focus-visible) .link-more__tag { opacity: 1; transform: rotate(-8deg) scale(1); }

  @media (prefers-reduced-motion: reduce) {
    .link-more, .link-more__icon, .link-more__tag { transition-property: opacity; }
    .link-more:is(:hover, :focus-visible) .link-more__icon { transform: none; }
  }

}


/* ───── components/media.css ───── */
/* ==========================================================================
   COMPONENTE: .media                                     v1.0 · 09/10/2026
   Figma:      «rIL web [desktop] 1» (hero) y «[desktop] 2» (Así trabajamos):
               vídeos. Hasta recibirlos, se muestra su fotograma de Figma.
   Qué hace:   imagen o vídeo (autoplay, muted, loop, playsinline) con
               proporción fija (sin saltos de maquetación) y radio.
   Variantes:  --bleed   sin radio (a sangre)
   API (token · fallback):
     --media-ratio  · proporción de los datos (width/height → --media-ratio-data) · 16 / 9
                      (una sección la cambia por frame: Figma usa otra proporción en móvil)
     --media-radius · var(--radius-small)
   Vista:      components/ril/media.njk
   ========================================================================== */
@layer components {

  .ril-media {
    position: relative;
    margin: 0;
    aspect-ratio: var(--media-ratio, var(--media-ratio-data, 16 / 9));
    overflow: hidden;
    border-radius: var(--media-radius, var(--radius-small));
    background-color: var(--color-background-alt);
  }
  .media__el {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  .media--bleed { --media-radius: 0; }

}


/* ───── components/carousel-fade.css ───── */
/* ==========================================================================
   COMPONENTE: .carousel-fade                             v1.0 · 09/10/2026
   Figma:      «Frame 315» y «Frame 316» del hero: tres imágenes que se
               suceden solas con fundido (2 s visibles + 0,83 s de fundido).
   Qué hace:   pila de imágenes del mismo tamaño; el módulo JS
               (data-module="carousel-fade") marca la visible con
               data-state="active". Sin JS o con reduced motion: solo la primera.
   API (token · fallback):
     --carousel-w      · 16rem            ancho (el alto sale de --carousel-ratio)
     --carousel-ratio  · 253 / 156        proporción de Figma
     --carousel-radius · var(--radius-small)
   Vista:      components/ril/carousel-fade.njk · JS: modules/carousel-fade.js
   ========================================================================== */
@layer components {

  .carousel-fade {
    position: relative;
    display: inline-block;
    width: var(--carousel-w, 16rem);
    aspect-ratio: var(--carousel-ratio, 253 / 156);
    overflow: hidden;
    border-radius: var(--carousel-radius, var(--radius-small));
    vertical-align: middle;
  }
  .carousel-fade__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity var(--dur-slow) var(--ease-in-out);
  }
  .carousel-fade__img:first-child,
  .carousel-fade[data-state="ready"] .carousel-fade__img[data-state="active"] { opacity: 1; }
  .carousel-fade[data-state="ready"] .carousel-fade__img:not([data-state="active"]) { opacity: 0; }

}


/* ───── components/sun.css ───── */
/* ==========================================================================
   COMPONENTE: .sun                                       v1.0 · 09/10/2026
   Figma:      «Ellipse 1-4, 95, 96»: elipses con degradado de Amarillo Solar
               (100 % → 10 %) y desenfoque de capa de 200.
   Qué hace:   mancha de sol decorativa. Se coloca respecto a su sección
               (que debe ser position: relative y recortar con overflow: clip).
               Posición, tamaño y giro llegan como datos: --x --y --w --h
               (en % del ancho de la sección) y --r (grados de Figma).
   API (token · fallback):
     --sun-from · var(--ril-sun-color)    --sun-to · var(--ril-sun-color-soft)
     --sun-blur · var(--ril-sun-blur)    --sun-z · var(--z-base) (capa)
   Rendimiento: desenfoque costoso (ver memoria de accesibilidad/rendimiento):
               will-change y aislamiento; pendiente pasar a imagen pre-desenfocada.
   Vista:      components/ril/sun.njk
   ========================================================================== */
/* anfitrión: la sección que lleva soles (estructural). Los soles van
   primero en el HTML; el contenido, después y en position: relative,
   se pinta encima sin z-index. En la capa base y sin especificidad
   (:where) para que la sección pueda posicionar sus hijos a su manera. */
@layer base {
  :where(.sun-host) {
    position: relative;
    isolation: isolate;
    overflow-x: clip;
    container-type: inline-size;
  }
  :where(.sun-host) > :where(:not(.sun)) { position: relative; }
}

@layer components {

  .sun {
    position: absolute;
    left: calc(var(--x) * 1cqi);
    top: calc(var(--y) * 1cqi);
    width: calc(var(--w) * 1cqi);
    height: calc(var(--h) * 1cqi);
    z-index: var(--sun-z, var(--z-base));
    border-radius: 50%;
    background: linear-gradient(90deg, var(--sun-from, var(--ril-sun-color)), var(--sun-to, var(--ril-sun-color-soft)));
    filter: blur(var(--sun-blur, var(--ril-sun-blur)));
    transform: rotate(calc(var(--r, 0) * -1deg));
    pointer-events: none;
    will-change: transform;
  }
  /* soles propios de un frame (Figma dibuja soles distintos en móvil) */
  @media (width < 48em)  { .sun--desktop { display: none; } }
  @media (width >= 48em) { .sun--mobile  { display: none; } }

}


/* ───── components/aura.css ───── */
/* ==========================================================================
   COMPONENTE: .aura                                      v1.0 · 12/10/2026
   Origen:     el sol de fondo del Presupuestador (rIL 1.0): «sigue la
               sección, el scroll y el cursor, y cambia de forma».
   Qué hace:   tres manchas de luz amarilla, fijas a la pantalla, detrás del
               contenido. Recorren las secciones claras (cada una marca dos
               puntos de paso con data-aura="x y escala") y, con el scroll,
               giran y se deforman; siguen un poco al cursor. Los bloques
               oscuros las tapan (tienen fondo propio) y el pie no las ve
               (se recortan donde acaba <main>).
   Elementos:  .aura > b × 3 (grande, media, núcleo)
   API (token · fallback):
     --aura-color · var(--ril-sun-color)   --aura-light · var(--ril-glow-cream)
   Sin JS / reduced motion: quietas en el primer punto de paso.
   Vista:      layouts/app.njk (primer hijo de <main>) · JS: modules/aura.js
   ========================================================================== */
@layer components {

  .aura {
    position: fixed;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
  }
  .aura b {
    position: absolute;
    left: 0;
    top: 0;
    border-radius: 50%;
    will-change: transform;
    transform: translate3d(90vw, 30vh, 0);
  }
  .aura b:nth-child(1) {
    width: 76vmax; height: 76vmax; margin: -38vmax;
    background: radial-gradient(closest-side,
      color-mix(in srgb, var(--aura-color, var(--ril-sun-color)) 72%, transparent),
      color-mix(in srgb, var(--aura-color, var(--ril-sun-color)) 34%, transparent) 40%,
      color-mix(in srgb, var(--aura-color, var(--ril-sun-color)) 8%, transparent) 70%,
      transparent);
  }
  .aura b:nth-child(2) {
    width: 48vmax; height: 48vmax; margin: -24vmax;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--aura-light, var(--ril-glow-cream)) 62%, transparent), transparent);
  }
  .aura b:nth-child(3) {
    width: 26vmax; height: 26vmax; margin: -13vmax;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--aura-color, var(--ril-sun-color)) 45%, transparent), transparent);
  }

}


/* ───── components/marquee.css ───── */
/* ==========================================================================
   COMPONENTE: .marquee                                   v1.0 · 09/10/2026
   Figma:      «PROYECTOS PROYECTOS» y las dos filas de logos de clientes.
               Figma los dibuja quietos; el desplazamiento continuo es la
               propuesta aceptada.
   Qué hace:   cinta que se desplaza sin fin. La vista repite el contenido
               dos veces (la copia lleva aria-hidden) y la cinta se mueve la
               mitad de su ancho.
   Variantes:  --reverse   hacia la derecha
               --pausable  se detiene al pasar el puntero (logos de clientes);
                           sin ella, no se para nunca (cinta PROYECTOS)
   API (token · fallback):
     --marquee-dur · 40s          --marquee-gap · var(--space-lg)
   Movimiento: con reduced motion, quieta.
   Vista:      components/ril/marquee.njk
   ========================================================================== */
@layer components {

  .ril-marquee {
    overflow: hidden;
    /* sin máscara de color: los bordes los da la propia sección */
  }
  .marquee__track {
    display: flex;
    width: max-content;
    gap: var(--marquee-gap, var(--space-lg));
    animation: marquee var(--marquee-dur, 40s) linear infinite;
  }
  .marquee__group {
    display: flex;
    flex: none;
    align-items: center;
    gap: var(--marquee-gap, var(--space-lg));
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .marquee--reverse .marquee__track { animation-direction: reverse; }
  .marquee--pausable:hover .marquee__track { animation-play-state: paused; }

  @keyframes marquee {
    to { transform: translateX(calc(-50% - var(--marquee-gap, var(--space-lg)) / 2)); }
  }

  @media (prefers-reduced-motion: reduce) {
    .marquee__track { animation: none; }
  }

}


/* ───── components/menu-servicios.css ───── */
/* ==========================================================================
   COMPONENTE: .menu-servicios                            v1.3 · 11/10/2026
   Figma:      «servicios-component» (6281:2145, página FINAL): variante por
               defecto + una por palabra al pasar el ratón, con Smart Animate
               «Quick» (muelle, 0,744 s → --ril-dur-quick / --ril-ease-quick).
   Qué hace:   lista de servicios en palabras gigantes. Al activar una palabra
               aparecen, como en Figma:
                 · su rótulo (GRÁFICO, PRODUCCIÓN…): el texto sube desde abajo
                   dentro de su caja (GRÁFICO, además, sube 8 px);
                 · tres etiquetas: pasan de su posición de reposo a la final
                   girando, se despliegan de arriba abajo (11 → 47 px) y se
                   funden de 0 a 1;
                 · una imagen que se abre desde su línea central, a un lado
                   de la palabra y a una distancia propia de su letra más
                   próxima (datos: side, gap), para no pisarla nunca.
               El rótulo va junto a la palabra (a su izquierda o derecha) con
               la misma separación en los cuatro casos (0,5 em del rótulo).
   Escritorio: se activa al pasar el ratón o con el foco.
   Móvil:      se activa con el scroll (modules/menu-servicios.js), con una
               línea en la mitad de la pantalla:
               la palabra que la contiene está activa. Palabras inactivas al
               20 %; PRODUCCIÓN encima de AUDIOVISUAL y DIGITAL debajo de
               MARKETING, a su izquierda. Bajo las palabras, una imagen
               (__preview) que cambia con la palabra activa (se abre desde el
               centro sobre la anterior); antes de la primera, vacía; tras la
               última, la de reserva.
               «VER MÁS» (botón amarillo ladeado) al final del bloque.
   Elementos:  __stage  __item  __head  __word  __label  __label-text  __layer
               __tags  __tag  __media  __preview  __preview-img  __more-wrap  __more
   Variantes:  __label--left / --right · __label--m-above / --m-below (móvil)
               __media--left / --right · __preview-img--fallback
   API (token · fallback):
     --menu-servicios-fs · var(--fs-menu)   tamaño de las palabras
   ESCALA     Todo se mide respecto a las palabras: el escenario mide lo que
              el frame de Figma (910 px) en proporción a la letra de 189 px,
              y etiquetas e imágenes se colocan en unidades del escenario
              (cqi). Así, al escalar el token, escala el conjunto.
              Coordenadas: resources/data/home.json (datos, no estilo).
   Constantes de Figma (estructurales, no son de marca):
     --ms-frame 910 · --ms-word 189 · --ms-pad 70 · --ms-row 150 · --ms-gap 16
     rótulo 18 px · etiqueta 28 px (en móvil 18,81 a 73,7), 47 px de alto,
     plegada a 11 en reposo
   Estados:    escritorio :hover / :focus-within · móvil [data-active]
   Movimiento: con reduced motion solo cambia la opacidad.
   Vista:      resources/views/components/ril/menu-servicios.njk
   ========================================================================== */

@layer components {
  .ril-menu-servicios {
    --ms-frame: 1440;
    --ms-word: 189;
    --ms-pad: 70;
    --ms-row: 150;
    --ms-gap: 16;
    --ms-dur: var(--ril-dur-quick);
    --ms-ease: var(--ril-ease-quick);
    overflow-x: clip;                 /* las imágenes salen del escenario */
    font-size: var(--menu-servicios-fs, var(--fs-menu));
  }
  .menu-servicios__stage {
    container-type: inline-size;
    position: relative;
    isolation: isolate;
    display: grid;
    gap: calc(var(--ms-gap) / var(--ms-word) * 1em);
    width: calc(var(--ms-frame) / var(--ms-word) * 1em);
    max-width: 100%;
    margin: 0 auto;
    padding: calc(var(--ms-pad) / var(--ms-word) * 1em) 0 0;
    list-style: none;
    text-align: center;
    line-height: calc(var(--ms-row) / var(--ms-word));
  }
  .menu-servicios__item { position: relative; }
  .menu-servicios__head { position: relative; display: inline-block; }
  .menu-servicios__word {
    display: inline-block;
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    text-transform: uppercase;
    color: inherit;
    text-decoration: none;
    transition: color var(--ms-dur) var(--ms-ease);
  }

  /* rótulo: caja que recorta el texto; el texto sube desde abajo */
  .menu-servicios__label {
    position: absolute;
    top: calc(var(--y) * 100cqi / var(--ms-frame));
    overflow: hidden;
    font-size: calc(18 / var(--ms-word) * 1em);
    font-weight: var(--fw-regular);
    font-stretch: var(--ril-stretch-label);
    line-height: var(--lh-label);
    letter-spacing: var(--ls-wider);
    text-transform: uppercase;
    white-space: nowrap;
    pointer-events: none;
    translate: 0 calc(var(--from, 0) * 100cqi / var(--ms-frame));
    transition: translate var(--ms-dur) var(--ms-ease);
  }
  .menu-servicios__label--right { left: calc(100% + 0.5em); }
  .menu-servicios__label--left  { right: calc(100% + 0.5em); }
  .menu-servicios__label-text {
    display: block;
    translate: 0 105%;
    transition: translate var(--ms-dur) var(--ms-ease);
  }

  .menu-servicios__layer {
    position: absolute;
    inset-inline: 0;
    top: 0;
    text-align: start;
    line-height: var(--lh-normal);
  }
  .menu-servicios__tags { margin: 0; padding: 0; list-style: none; }
  .menu-servicios__tag { left: calc(var(--x) * 100cqi / var(--ms-frame)); }
  .menu-servicios__media--right { left: calc(100% + var(--gap) * 100cqi / var(--ms-frame)); }
  .menu-servicios__media--left  { right: calc(100% + var(--gap) * 100cqi / var(--ms-frame)); }
  .menu-servicios__tag,
  .menu-servicios__media {
    position: absolute;
    top: calc(var(--y) * 100cqi / var(--ms-frame));
    opacity: 0;
    pointer-events: none;
    transition:
      opacity var(--ms-dur) var(--ms-ease),
      transform var(--ms-dur) var(--ms-ease),
      clip-path var(--ms-dur) var(--ms-ease);
  }
  /* etiqueta en reposo: posición y giro de la variante Default de Figma,
     plegada a 11 de sus 47 px (se despliega de arriba abajo) */
  .menu-servicios__tag {
    --tag-fs: calc(28 / var(--ms-word) * 1em);
    --tag-pad-y: 0.24em;
    --tag-pad-x: 0.643em;
    font-size: var(--tag-fs);
    line-height: var(--lh-label);
    transform-origin: top left;
    transform:
      translate(calc(var(--fx) * 100cqi / var(--ms-frame)), calc(var(--fy) * 100cqi / var(--ms-frame)))
      rotate(calc(var(--fr) * -1deg));                      /* Figma gira al revés que CSS */
    clip-path: inset(0 0 76.6% 0);
  }
  .menu-servicios__media {
    width: calc(324 * 100cqi / var(--ms-frame));
    height: auto;
    aspect-ratio: 324 / 210;
    object-fit: cover;
    border-radius: var(--radius-small);
    clip-path: inset(50% 0 round var(--radius-small));      /* se abre desde la línea central */
  }
  .menu-servicios__preview,
  .menu-servicios__more-wrap { display: none; }

  /* ---- escritorio: activo al pasar el ratón o con el foco -------------- */
  @media (width >= 48em) {
    .menu-servicios__item:is([data-active], :focus-within, :has(.menu-servicios__word:hover, .menu-servicios__tag:hover, .menu-servicios__media:hover)) {
      z-index: var(--z-dropdown);
    }
    .menu-servicios__item:is([data-active], :focus-within, :has(.menu-servicios__word:hover, .menu-servicios__tag:hover, .menu-servicios__media:hover)) :is(.menu-servicios__tag, .menu-servicios__media) {
      opacity: 1;
      pointer-events: auto;
    }
    .menu-servicios__item:is([data-active], :focus-within, :has(.menu-servicios__word:hover, .menu-servicios__tag:hover, .menu-servicios__media:hover)) .menu-servicios__tag {
      transform: translate(0, 0) rotate(calc(var(--r) * -1deg));
      clip-path: inset(0);
    }
    .menu-servicios__item:is([data-active], :focus-within, :has(.menu-servicios__word:hover, .menu-servicios__tag:hover, .menu-servicios__media:hover)) .menu-servicios__media {
      clip-path: inset(0 round var(--radius-small));
    }
    .menu-servicios__item:is([data-active], :focus-within, :has(.menu-servicios__word:hover, .menu-servicios__tag:hover, .menu-servicios__media:hover)) :is(.menu-servicios__label, .menu-servicios__label-text) {
      translate: 0 0;
    }
  }

  /* ---- móvil: activo con el scroll ([data-active], JS) ----------------- */
  @media (width < 48em) {
    .menu-servicios__word { color: color-mix(in srgb, currentColor 20%, transparent); }
    .menu-servicios__media { display: none; }
    /* rótulos legibles (14 px a 74) y, si no caben al lado, encima o debajo */
    .menu-servicios__label { font-size: calc(14 / 73.7 * 1em); }
    .menu-servicios__label--m-above { top: auto; bottom: 100%; left: 0; right: auto; }
    .menu-servicios__label--m-below { top: 100%; left: 0; right: auto; }
    .menu-servicios__tag {
      --tag-fs: calc(18.81 / 73.7 * 1em);
      left: calc(var(--mx, var(--x)) * 100cqi / var(--ms-frame));
      top: calc(var(--my, var(--y)) * 100cqi / var(--ms-frame));
    }
    .menu-servicios__item[data-active] { z-index: var(--z-dropdown); }
    .menu-servicios__item[data-active] .menu-servicios__word { color: inherit; }
    .menu-servicios__item[data-active] .menu-servicios__tag {
      opacity: 1;
      transform: translate(0, 0) rotate(calc(var(--mr, var(--r)) * -1deg));
      clip-path: inset(0);
    }
    .menu-servicios__item[data-active] :is(.menu-servicios__label, .menu-servicios__label-text) { translate: 0 0; }

    /* imagen del servicio activo: la nueva se abre desde su línea central
       sobre la anterior, que se queda debajo hasta que la tapa */
    .menu-servicios__preview {
      display: grid;
      margin-top: var(--space-xl);
      font-size: 1rem;
      aspect-ratio: 648 / 420;
      overflow: hidden;
      border-radius: var(--radius-small);
    }
    .menu-servicios__preview-img {
      grid-area: 1 / 1;
      width: 100%;
      height: 100%;
      object-fit: cover;
      clip-path: inset(50% 0);
      transition: clip-path var(--ms-dur) var(--ms-ease);
    }
    .menu-servicios__preview-img[data-on] { z-index: 2; clip-path: inset(0); }
    .menu-servicios__preview-img[data-was] { z-index: 1; clip-path: inset(0); transition: none; }

    /* botón amarillo ladeado (-2°) al final del bloque */
    .menu-servicios__more-wrap {
      display: block;
      margin-top: var(--space-xl);
      font-size: 1rem;
      text-align: center;
    }
    .menu-servicios__more {
      --tag-fs: var(--fs-btn-tag);
      --tag-pad-y: 0.41em;               /* Figma: 41,5 px de alto con letra de 24 */
      --tag-pad-x: 1.17em;
      display: inline-flex;
      align-items: center;
      gap: 0.5em;
      rotate: -2deg;
      text-decoration: none;
    }
    .menu-servicios__more .icon { --icon-size: 0.8em; --icon-stroke: 3; }
  }

  @media (prefers-reduced-motion: reduce) {
    .menu-servicios__label,
    .menu-servicios__label-text,
    .menu-servicios__tag,
    .menu-servicios__media { transition: opacity var(--dur-fast) linear; }
    .menu-servicios__label, .menu-servicios__label-text { translate: none; }
    .menu-servicios__label-text { opacity: 0; }
    .menu-servicios__item:is([data-active], :focus-within, :hover) .menu-servicios__label-text { opacity: 1; }
    .menu-servicios__tag { transform: rotate(calc(var(--r) * -1deg)); clip-path: none; }
    .menu-servicios__media { clip-path: inset(0 round var(--radius-small)); }
    .menu-servicios__preview-img { transition: none; }
  }
}


/* ───── components/project-card.css ───── */
/* ==========================================================================
   COMPONENTE: .project-card                              v1.1 · 11/10/2026
   Figma:      «Component 13/14/15» (Opal, FLM, Hawaya), sobre fondo oscuro.
   Qué hace:   imagen + título-enlace con flecha + texto. Toda la tarjeta es
               clicable (el enlace del título se extiende con ::after).
               Al pasar el puntero: la imagen cambia (si hay imagen de hover)
               o se acerca y las etiquetas de
               servicio suben sobre la imagen; la flecha gira 45° (horaria) hasta
               quedar horizontal.
   Elementos:  __media  __img  __img--hover  __tags  __body  __title  __link  __icon  __text
   API (token · fallback):
     --project-ratio  · proporción de los datos (--project-ratio-data) · 812 / 513
                       (la sección la cambia por frame: en móvil, todas 812 / 513)
     --project-radius · var(--radius-small)
     --project-title-fs · var(--fs-btn-large)
     --project-text-w · 67.6%  (Figma: 549 de 812)
   Figma:      texto a 12 px de la imagen y 8 px a la derecha de su borde
               (0,99 %); título y flecha de 50 px con 22 de hueco (móvil:
               38 px y 10); texto de 18 px, en móvil crema al 80 %.
   Estados:    :hover :focus-within
   Vista:      components/ril/project-card.njk
   ========================================================================== */
@layer components {

  .project-card { position: relative; }

  .project-card__media {
    position: relative;
    aspect-ratio: var(--project-ratio, var(--project-ratio-data, 812 / 513));
    overflow: hidden;
    border-radius: var(--project-radius, var(--radius-small));
  }
  .project-card__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: opacity var(--dur-slow) var(--ease-standard), transform var(--dur-slow) var(--ease-standard);
  }
  .project-card__img--hover { opacity: 0; }

  .project-card__tags {
    position: absolute;
    left: var(--space-md);
    bottom: var(--space-md);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs);
    max-width: 60%;
    margin: 0;
    padding: 0;
    list-style: none;
    transform: translateY(calc(100% + var(--space-md) + var(--space-2xs)));
    transition: transform var(--dur-slow) var(--ease-standard);
    --tag-bg: var(--color-text);
    --tag-fg: var(--color-background);
  }
  .project-card__tag--off { opacity: 0.4; }

  .project-card__body { margin-top: calc(14 * 1rem / 16 - 2 * var(--fluid-c)); }   /* Figma: 14 en móvil, 12 en escritorio */
  .project-card__title {
    font-size: var(--project-title-fs, var(--fs-btn-large));
    line-height: var(--lh-label);
  }
  .project-card__link {
    display: inline-flex;
    align-items: center;
    gap: 0.29em;
    color: inherit;
    text-decoration: none;
  }
  .project-card__link::after { content: ""; position: absolute; inset: 0; }   /* tarjeta entera clicable */
  .project-card__icon {
    --icon-size: 1.12em;
    --icon-stroke: 3;
    transition: transform var(--dur-base) var(--ease-standard);
  }
  .project-card__text {
    margin-top: 0;
    color: color-mix(in srgb, currentColor 80%, transparent);
  }
  @media (width >= 48em) {
    .project-card__body { padding-inline-start: 0.99%; }
    .project-card__link { gap: 0.46em; }
    .project-card__icon { --icon-size: 1.04em; }
    .project-card__text { max-width: var(--project-text-w, 67.6%); margin-top: var(--space-3xs); color: inherit; }
  }

  .project-card:is(:hover, :focus-within) .project-card__img--hover { opacity: 1; }
  .project-card:is(:hover, :focus-within) .project-card__img:only-of-type { transform: scale(1.04); }
  .project-card:is(:hover, :focus-within) .project-card__tags { transform: none; }
  /* la flecha ↗ gira en sentido horario hasta quedar horizontal → */
  .project-card:is(:hover, :focus-within) .project-card__icon { transform: rotate(45deg); }

  @media (prefers-reduced-motion: reduce) {
    /* sin desplazamientos animados: la flecha cambia de golpe, la imagen no se acerca */
    .project-card__img, .project-card__tags { transition-property: opacity; }
    .project-card__icon { transition: none; }
    .project-card:is(:hover, :focus-within) .project-card__img:only-of-type { transform: none; }
  }

}


/* ───── components/client-logo.css ───── */
/* ==========================================================================
   COMPONENTE: .client-logo                               v1.1 · 11/10/2026
   Figma:      «Group 269-274» (filas de clientes): logo centrado en una caja
               con cuatro esquinas en ángulo (14 px, trazo de 1,5 px).
   Qué hace:   caja de logo con esquinas dibujadas con degradados (sin
               elementos extra); las esquinas usan currentColor.
   API (token · fallback):
     --client-w      · 253px × --client-ratio · 253 / 149
     --client-corner · 14px    --client-stroke · 1.5px
     --client-logo-scale · 1   escala del logo respecto a su ancho de Figma (--w en el img)
   Vista:      se pinta desde ril.proof (components/ril/proof.njk)
   ========================================================================== */
@layer components {

  .client-logo {
    --c: var(--client-corner, 14px);
    --s: var(--client-stroke, 1.5px);
    display: grid;
    place-items: center;
    width: var(--client-w, 253px);
    aspect-ratio: var(--client-ratio, 253 / 149);
    background:
      linear-gradient(currentColor, currentColor) top left / var(--c) var(--s),
      linear-gradient(currentColor, currentColor) top left / var(--s) var(--c),
      linear-gradient(currentColor, currentColor) top right / var(--c) var(--s),
      linear-gradient(currentColor, currentColor) top right / var(--s) var(--c),
      linear-gradient(currentColor, currentColor) bottom left / var(--c) var(--s),
      linear-gradient(currentColor, currentColor) bottom left / var(--s) var(--c),
      linear-gradient(currentColor, currentColor) bottom right / var(--c) var(--s),
      linear-gradient(currentColor, currentColor) bottom right / var(--s) var(--c);
    background-repeat: no-repeat;
  }
  /* logo a su ancho de Figma (--w, px, lo pone la vista), escalable */
  .client-logo__img {
    width: calc(var(--w, 160) * 1rem / 16 * var(--client-logo-scale, 1));
    max-width: 100%;
    height: auto;
  }

}


/* ───── components/site-header.css ───── */
/* ==========================================================================
   COMPONENTE: .site-header                               v1.2 · 11/10/2026
   Figma:      escritorio «Component 16» (barra de 77 px, sin filete): logo
               64 × 32 · navegación centrada (15 px, cajas de 72 px con 32 de
               separación) · CONTACTA (28 px) con flecha.
               Móvil «Frame 364»: logo 58 × 29 y dos barras; menú a pantalla
               completa «📱 Menu» (6766:7563): fondo negro, entradas de 68 px,
               redes, CONTACTA de 68 px, foto y sol abajo.
   Qué hace:   cabecera fija arriba, sin color de fondo: solo desenfoca lo que
               pasa por debajo. El módulo header mira qué sección hay detrás y
               pone data-tone="dark" sobre fondos oscuros (.theme-space o
               data-header-tone="dark"): entonces todo (textos, filetes,
               barras, flecha y letras del logo) pasa a crema. En móvil, el
               botón abre el menú (data-menu="open" en la cabecera).
   Elementos:  __bar  __logo  __nav  __list  __link  __cta  __toggle  __panel
               __panel-img  __panel-nav  __menu  __menu-link  __social
   Variantes:  __cta--menu (CONTACTA grande del menú móvil)
   API (token · fallback):
     --header-bg · transparent      --header-fg-dark · var(--color-light)
   Estados:    [data-tone="dark"]  [data-menu="open"]  [aria-expanded] en el botón
   Vista:      components/ril/site-header.njk · JS: modules/header.js
   ========================================================================== */
@layer components {

  .site-header {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
    color: var(--color-text);
    background-color: var(--header-bg, transparent);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
    transition: color var(--dur-base) var(--ease-standard);
  }
  /* sobre una sección oscura, todo en crema (el punto del logo sigue amarillo) */
  .site-header[data-tone="dark"] { color: var(--header-fg-dark, var(--color-light)); }

  /* barra: logo · navegación centrada · CONTACTA */
  .site-header__bar {
    position: relative;
    z-index: var(--z-overlay);
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: var(--space-md);
    min-height: var(--header-height);
  }
  /* logo: 41,5 % del alto de la barra (Figma: 32 px en 77); con 60, 25 px */
  .site-header__logo { --logo-h: calc(var(--header-height) * 0.415); justify-self: start; color: inherit; }
  /* zonas pulsables de al menos 44 × 44 sin cambiar el dibujo: un ::after
     invisible amplía el área de toque del logo y del botón de menú */
  .site-header__logo, .site-header__toggle { position: relative; }
  .site-header__logo::after, .site-header__toggle::after { content: ""; position: absolute; inset: -10px -12px; }

  .site-header__list {
    display: flex;
    gap: var(--space-lg);
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .site-header__link {
    display: block;
    min-width: 4.8em;                       /* cajas de 72 px a 15 px (Figma) */
    font-size: var(--fs-nav);
    font-weight: var(--fw-medium);
    font-stretch: var(--ril-stretch-label);
    line-height: var(--lh-label);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    text-decoration: none;
    color: inherit;
    background: linear-gradient(currentColor, currentColor) left bottom / 0 var(--border-width) no-repeat;
    transition: background-size var(--dur-base) var(--ease-standard);
  }
  .site-header__link:is(:hover, :focus-visible) { background-size: 100% var(--border-width); }

  .site-header__cta {
    justify-self: end;
    display: inline-flex;
    align-items: center;
    gap: 0.07em;
    font-size: var(--fs-btn-cta);
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    line-height: var(--lh-snug);
    text-transform: uppercase;
    text-decoration: none;
    color: inherit;
    background: linear-gradient(currentColor, currentColor) left bottom / 0 2px no-repeat;
    transition: background-size var(--dur-base) var(--ease-standard);
  }
  .site-header__cta:is(:hover, :focus-visible) { background-size: 100% 2px; }
  .site-header__cta .icon { --icon-size: 0.8em; --icon-stroke: 3; }
  /* la flecha ↗ gira hasta quedar horizontal → (como en las tarjetas de proyecto) */
  .site-header__cta .icon { transition: transform var(--dur-base) var(--ease-standard); }
  .site-header__cta:is(:hover, :focus-visible) .icon { transform: rotate(45deg); }
  @media (prefers-reduced-motion: reduce) { .site-header__cta .icon { transition: none; } }

  /* botón de menú (móvil): dos barras de 3,85 px; con el menú abierto, una X */
  .site-header__toggle {
    display: none;
    justify-self: end;
    flex-direction: column;
    justify-content: center;
    gap: 0.33rem;
    width: 1.8125rem;
    height: 1.5625rem;
    padding: 0;
    color: inherit;
    background: none;
    border: 0;
    cursor: pointer;
  }
  .site-header__toggle-bar {
    display: block;
    height: 0.24rem;
    background-color: currentColor;
    transition: transform var(--dur-base) var(--ease-standard);
  }

  /* menú móvil a pantalla completa
     Animación (con JS, [data-menu]): la cortina negra baja desde la barra
     (clip-path), el sol sube desde abajo y las entradas aparecen una a una
     subiendo y ensanchándose (de 62 % al condensado de marca, como la letra
     ancha); redes y CONTACTA, al final. Al cerrar, todo a la inversa y más
     rápido. Sin JS: [hidden]. */
  .site-header__panel[hidden] { display: none; }
  .site-header[data-menu] .site-header__panel {
    visibility: hidden;
    clip-path: inset(0 0 100% 0);
    transition: clip-path 0.55s var(--ease-in-out), visibility 0s linear 0.55s;
  }
  .site-header[data-menu="open"] .site-header__panel {
    visibility: visible;
    clip-path: inset(0);
    transition: clip-path 0.7s var(--ease-in-out), visibility 0s;
  }
  .site-header[data-menu] .site-header__panel :is(.sun, .site-header__panel-img) {
    translate: 0 25%;
    opacity: 0;
    transition: translate 0.5s var(--ease-in-out), opacity 0.4s var(--ease-in-out);
  }
  .site-header[data-menu="open"] .site-header__panel :is(.sun, .site-header__panel-img) {
    translate: 0 0;
    opacity: 1;
    transition: translate 1.2s var(--ease-standard) 0.25s, opacity 1s var(--ease-standard) 0.25s;
  }
  .site-header[data-menu] .site-header__menu li {
    opacity: 0;
    translate: 0 0.3em;
    font-stretch: 70%;
    transition: opacity 0.25s var(--ease-in-out), translate 0.3s var(--ease-in-out), font-stretch 0.3s var(--ease-in-out);
  }
  .site-header[data-menu="open"] .site-header__menu li {
    opacity: 1;
    translate: 0 0;
    font-stretch: var(--ril-stretch-condensed);
    transition:
      opacity 0.6s var(--ease-standard) calc(0.3s + var(--i, 0) * 70ms),
      translate 0.8s var(--ease-standard) calc(0.3s + var(--i, 0) * 70ms),
      font-stretch 0.9s var(--ease-in-out) calc(0.35s + var(--i, 0) * 70ms);
  }
  .site-header[data-menu] .site-header__panel :is(.site-header__social, .site-header__cta--menu) {
    opacity: 0;
    translate: 0 0.75rem;
    transition: opacity 0.2s var(--ease-in-out), translate 0.2s var(--ease-in-out);
  }
  .site-header[data-menu="open"] .site-header__panel :is(.site-header__social, .site-header__cta--menu) {
    opacity: 1;
    translate: 0 0;
    transition: opacity 0.6s var(--ease-standard) 0.7s, translate 0.7s var(--ease-standard) 0.7s;
  }
  .site-header__menu li { font-stretch: var(--ril-stretch-condensed); }   /* el enlace lo hereda (se anima en el <li>) */
  .site-header__panel {
    position: fixed;
    inset: 0;
    z-index: var(--z-base);
    isolation: isolate;
    container-type: inline-size;            /* anfitrión de su sol (ver sun.css) */
    overflow: clip;                         /* sol e imagen no alargan el panel: mide una pantalla */
  }
  .site-header__panel-nav { position: relative; }
  .site-header__panel-img {
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    width: 100%;
    height: auto;
    pointer-events: none;
  }
  .site-header__panel-nav {
    display: flex;
    flex-direction: column;
    height: 100dvh;
    overflow-y: auto;                       /* solo si no cabe (pantallas muy bajas) */
    padding-top: calc(var(--header-height) + 2.5rem);
    padding-bottom: var(--space-sm);
  }
  .site-header__menu { display: grid; gap: 1px; margin: 0; padding: 0; list-style: none; }
  .site-header__menu-link {
    font-size: var(--fs-btn-menu);
    font-weight: var(--ril-fw-black);
    font-stretch: inherit;
    line-height: 1.03;
    text-transform: uppercase;
    text-decoration: none;
    color: inherit;
  }
  .site-header__social {
    display: flex;
    align-items: center;
    gap: 0.92rem;
    margin: auto 0 0;
    padding: 0;
    list-style: none;
    --icon-size: 2.34rem;
  }
  .site-header__social a { color: inherit; }
  .site-header__cta--menu {
    justify-self: start;
    align-self: start;
    font-size: var(--fs-btn-menu);
    line-height: 1.35;
    background-size: 0 0.3rem;
  }
  .site-header__cta--menu:is(:hover, :focus-visible) { background-size: 100% 0.3rem; }
  .site-header__cta--menu .icon { --icon-size: 0.85em; }

  /* menú abierto: barra en crema sobre el negro, sin fondo */
  .site-header[data-menu="open"] { color: var(--color-light); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .site-header[data-menu="open"] .site-header__toggle-bar:first-child { transform: translateY(calc(0.165rem + 0.12rem)) rotate(45deg); }
  .site-header[data-menu="open"] .site-header__toggle-bar:last-child  { transform: translateY(calc(-0.165rem - 0.12rem)) rotate(-45deg); }

  @media (width < 48em) {
    .site-header__nav, .site-header__bar > .site-header__cta { display: none; }
    .site-header__bar { grid-template-columns: 1fr auto; }
    .site-header__toggle { display: inline-flex; }
  }
  @media (width >= 48em) {
    .site-header__panel { display: none; }
  }
  @media (prefers-reduced-motion: reduce) {
    .site-header__toggle-bar { transition: none; }
    .site-header[data-menu] .site-header__panel,
    .site-header[data-menu] .site-header__panel * { transition-duration: 0s !important; transition-delay: 0s !important; }
  }
}


/* ───── components/site-footer.css ───── */
/* ==========================================================================
   COMPONENTE: .site-footer                               v1.5 · 12/10/2026
   Figma:      zona negra final (desde «Rectangle 375»): cierre «Impulsaremos
               tu marca en la dirección correcta» (108 px, ancho 75 %) con
               flecha e imagen en línea + TARIFAS / CONTÁCTANOS (48 px);
               columnas agencia · servicios · contacto · síguenos (títulos de
               20 px al 70 %, enlaces de 19); logo de 255 × 127; copyright y
               legales (18 px).
               Móvil (v1.3, más ligero: cabe en una pantalla): el cierre
               (--fs-closing, 40 px) sobre una banda de foto fundida; debajo,
               CONTÁCTANOS (29 px) con teléfono, correo y dirección subrayados
               y las redes al 70 %; luego agencia y servicios en dos columnas;
               logo (186 × 92) y legales apilados a la derecha (16 px).
   Qué hace:   pie común a todas las páginas (tema oscuro), con la «brasa»
               del Presupuestador de fondo y la imagen del cierre que se
               abre al verse (v1.3). Está siempre
               detrás de la página (sticky abajo, bajo <main>) y el último
               bloque lo destapa al subir. Si es más alto que la pantalla, se
               queda pegado por arriba (--footer-h, lo mide site-footer.js):
               se destapa desde su primera línea.
   Elementos:  __photo  __closing  __closing-title  __closing-arrow  __closing-img
               __closing-links  __closing-link  __grid  __col  __label  __list
               __contact  __contact-cta  __follow  __social  __bottom  __logo  __legal
   Retícula:   escritorio: cierre en columnas 1-6 y enlaces en 8-12; columnas
               del pie en x 40 · 458 · 1017 · 1433 (columnas 1, 4, 8 y 11 más
               0, 6, 16 y 20 px).
   Vista:      components/ril/site-footer.njk
   ========================================================================== */
@layer components {
  .site-footer {
    position: sticky;
    bottom: min(0px, 100svh - var(--footer-h, 0px));
    z-index: 0;
    padding-block: max(calc(64 * 1rem / 16 - 25 * var(--fluid-c)), var(--header-height) + var(--space-md)) calc(32 * 1rem / 16 + 45 * var(--fluid-c));   /* v1.4: al destaparse entero, el cierre no queda bajo la cabecera */   /* móvil: cabe en una pantalla; escritorio: 39 arriba */
    display: flex;                          /* v1.4: una pantalla entera; se destapa completo con el scroll del bloque anterior */
    flex-direction: column;
    min-height: 100svh;
    overflow: clip;                         /* la brasa sobresale (inset −12 %): sin recorte alargaba la página bajo el pie */
  }
  /* el contenido se pinta por encima de la foto y de los soles que llegan
     del bloque anterior (que van en position: absolute) */
  .site-footer > .ril-container { position: relative; z-index: calc(var(--z-base) + 2); display: flex; flex: 1; flex-direction: column; justify-content: flex-end; }   /* el contenido, alineado abajo */   /* sobre los soles de .tools */

  /* brasa (Presupuestador): seis manchas de luz que derivan despacio. Mientras
     el pie se destapa, crecen y se enfocan (--glow-o opacidad, --glow-s escala,
     --glow-b desenfoque: los pone site-footer.js; sin JS, el estado final). */
  /* oculto mientras la página lo tapa del todo (site-footer.js pone
     [data-shown] cuando el final del contenido se acerca): así no cuenta como
     contenido que se mueve al cargar la tipografía (CLS) ni se pinta en balde */
  .site-footer[data-ready]:not([data-shown]) { visibility: hidden; }

  .site-footer__glow {
    position: absolute;
    inset: -12%;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
    opacity: calc(var(--glow-o, 1) * 0.8);
    transform: scale(var(--glow-s, 1));
    transform-origin: 50% 90%;
    filter: blur(var(--glow-b, 0px));
  }
  .site-footer__glow b { position: absolute; border-radius: 50%; will-change: transform; }
  .site-footer__glow-y { background: radial-gradient(closest-side, var(--ril-glow-gold) 0, var(--ril-glow-amber) 38%, var(--ril-glow-orange) 70%, var(--ril-glow-ember) 100%); }
  .site-footer__glow-o { background: radial-gradient(closest-side, var(--ril-glow-orange) 0, var(--ril-glow-ember) 55%, var(--ril-glow-wine) 85%, var(--ril-glow-night) 100%); }
  .site-footer__glow-k { background: radial-gradient(closest-side, var(--color-dark) 0, var(--color-dark) 55%, var(--ril-glow-shadow) 80%, var(--ril-glow-night) 100%); }
  .site-footer__glow b:nth-child(1) { left: 48%;  top: 58%; width: 64%; height: 62%; filter: blur(5.5vw); animation: glow-1 26s var(--ease-in-out) infinite alternate; }
  .site-footer__glow b:nth-child(2) { left: -18%; top: 30%; width: 50%; height: 95%; filter: blur(5.5vw); animation: glow-2 30s var(--ease-in-out) infinite alternate; }
  .site-footer__glow b:nth-child(3) { left: 18%;  top: 62%; width: 44%; height: 44%; filter: blur(6vw); opacity: 0.85; animation: glow-3 22s var(--ease-in-out) infinite alternate; }
  .site-footer__glow b:nth-child(4) { left: -34%; top: 80%; width: 92%; height: 58%; filter: blur(7vw); animation: glow-4 28s var(--ease-in-out) infinite alternate; }
  .site-footer__glow b:nth-child(5) { left: 34%;  top: 40%; width: 34%; height: 34%; filter: blur(5vw); animation: glow-5 24s var(--ease-in-out) infinite alternate; }
  .site-footer__glow b:nth-child(6) { left: 72%;  top: 88%; width: 40%; height: 30%; filter: blur(5vw); opacity: 0.9; animation: glow-3 32s var(--ease-in-out) infinite alternate-reverse; }
  @keyframes glow-1 { to { transform: translate(-6vw, -4vh) rotate(18deg) scale(1.08, 0.94); } }
  @keyframes glow-2 { to { transform: translate(5vw, -6vh) rotate(-14deg) scale(0.92, 1.1); } }
  @keyframes glow-3 { to { transform: translate(7vw, 3vh) rotate(25deg) scale(1.15, 0.9); } }
  @keyframes glow-4 { to { transform: translate(8vw, -5vh) rotate(-10deg) scale(1.1, 1); } }
  @keyframes glow-5 { to { transform: translate(-5vw, 6vh) rotate(30deg) scale(0.85, 1.2); } }
  @media (prefers-reduced-motion: reduce) {
    .site-footer__glow { opacity: 0.65; transform: none; filter: none; }
    .site-footer__glow b { animation: none; }
  }

  /* foto del cierre (móvil): Figma 1136 × 412 a 45 %, fundida en negro */
  .site-footer__photo {
    position: absolute;
    left: 50%;
    top: 0;
    width: 100%;
    height: calc(300 * 1rem / 16);
    object-fit: cover;
    translate: -50% 0;
    opacity: 0.5;
    -webkit-mask-image: linear-gradient(to bottom, var(--color-dark) 40%, transparent);
    mask-image: linear-gradient(to bottom, var(--color-dark) 40%, transparent);
    pointer-events: none;
  }

  /* cierre */
  .site-footer__closing { display: grid; gap: var(--space-xl); }
  .site-footer__closing-title {
    font-size: var(--fs-closing);
    font-stretch: var(--ril-stretch-display);
    line-height: 0.91;
  }
  /* flecha (1,05 em) e imagen (0,83 em) en línea, sin agrandar la línea:
     alineadas arriba y con márgenes negativos (Figma: flecha 9 px por encima
     de la línea, imagen 8 px por debajo de su borde superior) */
  .site-footer__closing-arrow {
    --icon-size: 1.05em;
    --icon-stroke: 3;
    margin: -0.07em 0 -0.25em -0.25em;
    vertical-align: top;
  }
  /* imagen en línea: se abre de 0 a su ancho cuando el pie está a la vista
     ([data-in], site-footer.js) y empuja «EN LA» */
  .site-footer__closing-img {
    --img-h: 0.83em;
    display: inline-block;
    height: var(--img-h);
    width: calc(var(--img-h) * 271 / 86);
    transition: width var(--u-expanded-dur, 1.1s) var(--ease-in-out);
    aspect-ratio: 271 / 86;
    object-fit: cover;
    border-radius: calc(4 * 1rem / 16);
    margin-top: 0.08em;
    vertical-align: top;
  }
  .site-footer[data-ready]:not([data-in]) .site-footer__closing-img { width: 0; }
  .site-footer__closing-links { display: none; margin: 0; padding: 0; list-style: none; }
  .site-footer__closing-link {
    display: inline-flex;
    align-items: center;
    gap: 0.086em;
    font-size: var(--fs-btn-closing);
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    line-height: var(--lh-label);
    text-transform: uppercase;
    text-decoration: none;
    color: inherit;
  }
  .site-footer__closing-link .icon { --icon-size: 1.04em; --icon-stroke: 3; transition: transform var(--dur-base) var(--ease-standard); }
  .site-footer__closing-link:is(:hover, :focus-visible) .icon { transform: rotate(45deg); }   /* ↗ → →, como todas las flechas */

  /* columnas (móvil: contacto y redes primero; agencia y servicios en dos columnas) */
  .site-footer__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: calc(32 * 1rem / 16) calc(10 * 1rem / 16);
    margin-top: calc(40 * 1rem / 16);
  }
  .site-footer__contact { grid-column: 1 / -1; order: -2; }
  .site-footer__follow  { grid-column: 1 / -1; order: -1; margin-top: calc(12 * 1rem / 16 - 32 * 1rem / 16); }
  .site-footer__label {
    --eyebrow-fs: var(--fs-label);
    --eyebrow-stretch: var(--ril-stretch-cta);
    --eyebrow-fg: color-mix(in srgb, var(--color-text) 70%, transparent);
    margin-bottom: calc(9 * 1rem / 16);
  }
  .site-footer__contact .site-footer__label,
  .site-footer__follow .site-footer__label { display: none; }
  .site-footer__contact-cta { margin-bottom: var(--space-3xs); }
  .site-footer__list { display: grid; gap: calc(3 * 1rem / 16); margin: 0; padding: 0; list-style: none; }
  .site-footer__list, .site-footer__contact { font-size: var(--fs-body-lg); line-height: var(--lh-normal); }
  .site-footer__list a, .site-footer__contact a { color: inherit; text-decoration: none; }
  .site-footer__list a:hover { text-decoration: underline; }
  .site-footer__contact p a { text-decoration: underline; text-decoration-thickness: 5%; text-underline-position: from-font; }
  .site-footer__contact address { margin-top: var(--space-3xs); font-style: normal; line-height: 1.32; }
  .site-footer__social {
    display: flex;
    align-items: center;
    gap: calc(15 * 1rem / 16);
    margin: 0;
    padding: 0;
    list-style: none;
    --icon-size: calc(26 * 1rem / 16);
  }
  .site-footer__social a { color: color-mix(in srgb, var(--color-text) 70%, transparent); }
  .site-footer__social a:hover { color: var(--color-text); }

  /* base: logo y legales */
  .site-footer__bottom {
    display: flex;
    align-items: end;
    justify-content: space-between;
    gap: 0;
    margin-top: calc(32 * 1rem / 16);
  }
  .site-footer__logo { --logo-h: calc((56 * 1rem / 16 + 71 * var(--fluid-c)) * 0.75); }   /* v1.4: 75 % (móvil 42, escritorio 95) */
  .site-footer__legal { font-size: var(--fs-small); font-weight: var(--fw-medium); line-height: var(--lh-normal); text-align: end; }
  .site-footer__legal p { font-weight: var(--fw-semibold); color: color-mix(in srgb, var(--color-text) 90%, transparent); }
  .site-footer__legal ul { display: grid; justify-items: end; margin: 0; padding: 0; list-style: none; color: color-mix(in srgb, var(--color-text) 60%, transparent); }
  .site-footer__legal a { color: inherit; text-decoration: none; }

  @media (width >= 48em) {
    .site-footer__photo, .site-footer__contact-cta { display: none; }
    .site-footer__closing { grid-template-columns: repeat(12, minmax(0, 1fr)); align-items: end; gap: 0; }
    .site-footer > .ril-container { container-type: inline-size; }
    .site-footer__closing-title { grid-column: 1 / 7; max-width: none; font-size: min(var(--fs-cta), 100cqi * 6 / 12 / 7.6, 11svh);   /* columnas 1-6: la línea más larga mide 7,5 em */ line-height: var(--lh-tight); white-space: nowrap; }
    .site-footer__closing-arrow { margin-top: -0.083em; }
    .site-footer__closing-img { --img-h: 0.8em; border-radius: var(--radius-small); }
    .site-footer__closing-links { display: flex; flex-wrap: wrap; gap: var(--space-xs) var(--space-md); grid-column: 8 / 13; justify-content: space-between; margin-left: calc(16 * 1rem / 16); }
    .site-footer__closing-link { gap: 0.46em; }
    .site-footer__grid { grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 0; margin-top: min(calc(79 * 1rem / 16), 7.9svh); }
    .site-footer__col--1 { grid-column: 1 / 4; }
    .site-footer__col--2 { grid-column: 4 / 8; margin-left: calc(6 * 1rem / 16); }
    .site-footer__contact { grid-column: 8 / 11; order: 0; margin-left: calc(16 * 1rem / 16); }
    .site-footer__follow  { grid-column: 11 / 13; order: 0; margin: 0 0 0 calc(20 * 1rem / 16); }
    .site-footer__label { margin-bottom: calc(14 * 1rem / 16); }
    .site-footer__contact .site-footer__label { display: block; }
    .site-footer__follow .site-footer__label { display: block; margin-bottom: calc(20 * 1rem / 16); }
    .site-footer__list { gap: calc(8 * 1rem / 16); }
    .site-footer__contact p + p, .site-footer__contact address { margin-top: calc(8 * 1rem / 16); }
    .site-footer__contact p a { text-decoration: none; }
    .site-footer__social { gap: calc(20 * 1rem / 16); --icon-size: calc(33.3 * 1rem / 16); }
    .site-footer__social a { color: inherit; }
    /* v1.5 · pantallas bajas: el pie sigue midiendo una pantalla; las medidas
       grandes tienen un tope proporcional al alto (en 1728 × 1000, las de Figma) */
    .site-footer { padding-bottom: min(calc(32 * 1rem / 16 + 45 * var(--fluid-c)), 7.7svh); }
    .site-footer__closing-link { font-size: min(var(--fs-btn-closing), 4.8svh); }
    .site-footer__logo { --logo-h: min(calc((56 * 1rem / 16 + 71 * var(--fluid-c)) * 0.75), 9.5svh); }
    .site-footer__bottom { gap: var(--space-lg); margin-top: min(calc(74 * 1rem / 16), 7.4svh); }   /* v1.4: 74 (antes 154) */
    .site-footer__legal p { font-weight: var(--fw-medium); }
    .site-footer__legal ul { display: flex; flex-wrap: wrap; justify-content: end; align-items: center; gap: calc(11 * 1rem / 16); }
    .site-footer__legal li + li::before {
      content: "";
      display: inline-block;
      width: 3px;
      height: 3px;
      margin-right: calc(11 * 1rem / 16);
      vertical-align: middle;
      border-radius: var(--radius-full);
      background-color: currentColor;
    }
  }
  /* tablet (48-64em): el cierre a todo el ancho y TARIFAS / CONTÁCTANOS debajo */
  @media (48em <= width < 64em) {
    .site-footer__closing { row-gap: var(--space-lg); }
    .site-footer__closing-title { grid-column: 1 / -1; font-size: min(var(--fs-cta), 100cqi / 7.8, 11svh); }
    .site-footer__closing-links { grid-column: 1 / -1; justify-content: flex-start; gap: var(--space-xs) var(--space-xl); margin-left: 0; }
  }

}


/* ───── components/reveal.css ───── */
/* ==========================================================================
   COMPORTAMIENTO: [data-reveal]                          v1.0 · 09/10/2026
   Lo pone el módulo JS reveal.js (no se escribe a mano): "out" oculto y
   desplazado; "in" visible. Sin JS el atributo no existe y todo se ve.
   Tokens: --ril-reveal-dur · --ril-reveal-dist · --ril-reveal-stagger ·
           --ril-ease-out. --reveal-i (orden dentro de su sección) lo pone el JS.
   ========================================================================== */
@layer components {

  [data-reveal] {
    transition:
      opacity var(--ril-reveal-dur) var(--ril-ease-out),
      translate var(--ril-reveal-dur) var(--ril-ease-out);
    transition-delay: calc(min(var(--reveal-i, 0), 6) * var(--ril-reveal-stagger));
  }
  [data-reveal="out"] { opacity: 0; translate: 0 var(--ril-reveal-dist); }

}



/* ───── sections/_index.css ───── */
/* ==========================================================================
   sections/  —  patrones de bloque · @layer layout
   Qué es una sección: la composición de un bloque de página (retícula,
   columna de inicio 1·5·9, corte 4·8, tema, ritmo vertical, sol, líneas).
   No pinta componentes: solo reasigna sus tokens en el propio elemento.
   Opciones admitidas: PLAN-DE-ACCION.md §3.3.
   Breakpoint de composición: 48em (escritorio = retícula de 12 columnas;
   por debajo, una columna como el frame móvil de Figma).
   ========================================================================== */


/* ───── sections/hero.css ───── */
/* ==========================================================================
   SECCIÓN: .hero                                         v1.3 · 12/10/2026
   Figma:      escritorio «Group 288» + «rIL web [desktop] 1» + soles
               «Ellipse 1-3»; móvil «📱 Home» (6647:5914).
   Composición escritorio: antetítulo · titular display en tres filas
               (1.ª a la izquierda con carrusel detrás; 2.ª a la derecha con
               carrusel delante; 3.ª a todo el ancho).
   Composición móvil: titular en cinco filas (LA · AGENCIA · PARA MARCAS ·
               QUE BUSCAN · CRECER) con los carruseles sueltos y girados
               (+3° y −3,3°): el de «LA AGENCIA» por detrás del texto, el
               otro por delante · antetítulo debajo.
   Vídeo (v1.2, petición del 11/10/2026): el texto empieza centrado en la
               pantalla y el vídeo asoma por debajo (--hero-peek, 100 px)
               del tamaño de los carruseles del titular (v1.3). Al bajar crece hasta ocupar toda la pantalla
               (ancho y alto completos, sin radio; en móvil, todo el ancho en
               4:3, sin fijarse) y en escritorio se queda fijo --hero-hold.
               Vídeo en autoplay (muted, loop, playsinline). modules/hero-video.js pone
               --hero-p (0 → 1) según el scroll; el resto es CSS.
               Con reduced motion: el vídeo a sangre, sin escena.
   Escala:     los carruseles miden en em del titular (Figma: 253 px con letra
               de 200 px; 168-172 px con letra de 68) → crecen con --fs-display.
               v1.3: un 50 % más anchos (misma altura) y se abren al cargar.
   Medidas:    las de composición (huecos, posiciones) son de Figma, móvil y
               escritorio, interpoladas con --fluid-c (tokens-ril.css).
   Letras anchas: las marcadas con [x] en los datos (.u-expanded) se
               ensanchan al cargar (75 % → ancho final en 1,8 s, como en el
               Presupuestador), a la vez que se abren los carruseles.
   Ancho:      Figma se ve a ≈81 % (79,5 % en móvil): --ril-stretch-hero(-sm).
   ========================================================================== */
@layer layout {

  .ril-hero {
    --hero-peek: calc(100 * 1rem / 16);
    --hero-hold: 150svh;                   /* pausa del vídeo a pantalla completa (escritorio): 50svh de pausa + una pantalla más para el texto de IA */
    padding-block: 0;                      /* el alto lo marcan el texto y la escena */
  }
  /* móvil: el bloque del titular, centrado en la pantalla al cargar; el
     vídeo asoma por debajo (--hero-peek-m) */
  .hero__inner {
    --hero-peek-m: calc(140 * 1rem / 16);
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: calc(100svh - var(--header-height) - var(--hero-peek-m));
    padding-block: var(--space-md);
  }
  /* escritorio: el texto, centrado en el hueco que deja el vídeo al asomar */
  @media (width >= 48em) {
    .hero__inner {
      justify-content: center;
      min-height: calc(100svh - var(--header-height) - var(--hero-peek));
      padding-block: var(--space-md);
    }
  }

  .hero__title {
    position: relative;
    isolation: isolate;                    /* el carrusel de detrás no baja del fondo de la sección */
    margin-right: calc(-8 * 1rem / 16);   /* móvil: Figma deja la caja en 382 px (8 px dentro del margen) */
    font-size: var(--fs-display);
    --hero-stretch: var(--ril-stretch-hero-sm);
    /* letra ancha (marca-ril.css): en móvil el titular va justo de ancho y la
       letra acaba en el ancho del diseño; en escritorio, ancha (110 %) */
    --u-expanded-stretch: var(--hero-stretch);
    --u-expanded-delay: var(--dur-base);
    font-stretch: var(--hero-stretch);
    line-height: var(--lh-tight);
  }
  /* las filas no se parten nunca (cada salto lo marcan los datos): el alto del
     titular no cambia cuando llega la tipografía (sin desplazamiento, CLS) */
  .hero__line { display: block; white-space: nowrap; }
  /* carruseles: 50 % más anchos que en Figma (misma altura) y, al cargar,
     se abren de 0 a su ancho a la vez que la letra ancha, empujando el texto
     (la caja crece; la imagen de dentro ya tiene su tamaño final) */
  .hero__carousel {
    flex: none;
    line-height: 0;
    overflow: clip;
    width: var(--carousel-w);
    --carousel-ratio: 379.5 / 156;
    animation: hero-carousel-in var(--u-expanded-dur, 1.8s) var(--ease-in-out) var(--u-expanded-delay, 0.25s) backwards;
  }
  @keyframes hero-carousel-in { from { width: 0; } }
  .hero__carousel .carousel-fade { flex: none; }   /* la imagen no encoge con la caja: la caja la recorta */

  /* móvil: el antetítulo va debajo del titular; los carruseles, sueltos */
  .hero__eyebrow { order: 1; margin-top: calc(102 * 1rem / 16); }
  .hero__carousel--a,
  .hero__carousel--b { position: absolute; z-index: var(--z-base); }
  .hero__carousel--a { z-index: -1; }     /* móvil: detrás de «LA AGENCIA» */
  /* móvil: ancho de Figma (más estrechas que en escritorio: no tapan el titular) */
  .hero__carousel--a,
  .hero__carousel--b { --carousel-ratio: 253 / 156; }
  .hero__carousel--a { --carousel-w: 2.475em; left: 1.22em; top: -0.515em; rotate: 3deg; }
  .hero__carousel--b { --carousel-w: 2.533em; left: 2.794em; top: 3.7em; rotate: -3.3deg; }

  @media (width >= 48em) {
    .hero__eyebrow { --eyebrow-fs: var(--fs-eyebrow-sm); order: 0; margin-top: 0; }
    /* las filas no se parten: entre los dos frames, la letra no pasa del ancho (8,45 em de la 3.ª fila, con su letra ancha) */
    .hero__inner { container-type: inline-size; }
    .hero__title { font-size: min(var(--fs-display), 100cqi / 8.45); margin-right: 0; margin-top: calc(22.4 * 1rem / 16); line-height: var(--lh-display); --hero-stretch: var(--ril-stretch-hero); --u-expanded-stretch: var(--ril-stretch-expanded); }
    /* imágenes alineadas a la letra: arriba con la altura de mayúsculas y
       abajo con la línea base (alto = 1cap; flex alineado a la base) */
    .hero__line { display: flex; align-items: baseline; gap: 0.16em; white-space: nowrap; }
    .hero__line--end { justify-content: flex-end; }
    .hero__carousel--a,
    .hero__carousel--b { position: static; --carousel-w: calc(1cap * 379.5 / 156); --carousel-ratio: 379.5 / 156; rotate: none;
      display: flex;   /* sin línea de texto dentro: su base es su borde inferior (si no, queda 16 px baja) */
    }
    .hero__carousel--a { z-index: auto; }
  }

  /* ---- escena del vídeo ------------------------------------------------
     Empieza del tamaño de los carruseles del titular (--hero-w0 / --hero-h0,
     los mide hero-video.js; sin JS, 3 columnas) y crece con el scroll:
       · escritorio: la pista mide una pantalla + la pausa; dentro, una caja
         fija (sticky) de una pantalla con el vídeo arriba. Al cargar la caja
         empieza a 100svh − peek (asoma 100 px) y, cuando llega arriba, el
         vídeo ocupa toda la pantalla;
       · móvil: sin caja fija. El vídeo va en el flujo, bajo el antetítulo,
         algo girado como los carruseles, y crece con el scroll hasta todo
         el ancho en 4:3 (su hueco ya tiene ese alto: nada salta) y se
         endereza; termina cuando su caja llega al centro de la pantalla. */
  .hero__scene {
    --hero-p: 0;
    --hero-cols: 6;                                         /* móvil: retícula de 6 */
    --hero-ratio: calc(253 / 156);                          /* ancho / alto de los carruseles */
    --hero-h1: calc(100cqi * 3 / 4);                        /* móvil: al final, todo el ancho en 4:3 */
    --hero-rot0: 4deg;                                      /* móvil: girado como los carruseles */
    position: relative;
  }
  .hero__sticky {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    height: var(--hero-h1);
  }
  .hero__frame {
    --w0: var(--hero-w0, calc((100cqi - 2 * var(--container-pad)) * 3 / var(--hero-cols)));
    --h0: var(--hero-h0, calc(var(--w0) / var(--hero-ratio)));
    width: calc(var(--w0) + (100cqi - var(--w0)) * var(--hero-p));
    height: calc(var(--h0) + (var(--hero-h1) - var(--h0)) * var(--hero-p));
    rotate: calc(var(--hero-rot0) * (1 - var(--hero-p)));
    will-change: width, height;
  }
  .hero__media {
    height: 100%;
    --media-ratio: auto;
    --media-radius: calc(var(--radius-small) * (1 - var(--hero-p)));
  }
  /* móvil: la caja sube mientras crece el vídeo (hero-video.js, v1.1) */
  @media (width < 48em) {
    .hero__sticky { translate: 0 calc(-1 * var(--hero-shift, 0px) * var(--hero-p)); }
  }
  @media (width >= 48em) {
    .hero__scene { --hero-cols: 12; --hero-h1: 100svh; --hero-rot0: 0deg; height: calc(100svh + var(--hero-hold)); }
    .hero__sticky { position: sticky; top: 0; height: 100svh; overflow: hidden; }
  }

  @media (prefers-reduced-motion: reduce) {
    .hero__carousel { animation: none; }
    /* sin escena: el vídeo, a sangre y de una pantalla */
    .hero__scene { --hero-p: 1; height: auto; }
    .hero__sticky { position: static; height: auto; }
    .hero__frame { rotate: none; }
  }

}


/* ───── sections/split-media.css ───── */
/* ==========================================================================
   SECCIÓN: .split-media                                  v1.1 · 11/10/2026
   Figma:      bloque «360°» («Frame 320», «Frame 300», «open-01 2»).
   Composición escritorio: texto en columnas 1-5 (antetítulo, cifra con
               degradado, titular a 79 px de la cifra, entradilla a 52 px) e
               imagen de 951 × 600 en 6-12, alineada arriba con el antetítulo.
   Composición móvil: antetítulo · cifra gigante centrada · imagen
               (373 × 274) que pisa la cifra 18 px · titular · entradilla.
   Opciones:   --media-first   la imagen a la izquierda (solo escritorio)
   Medidas:    de Figma (móvil/escritorio) con --fluid-c.
   ========================================================================== */
@layer layout {

  .split-media {
    padding-top: calc(143 * var(--fluid-c));
    padding-bottom: calc(50 * 1rem / 16 + 49 * var(--fluid-c));   /* móvil: desde la entradilla; escritorio: desde la imagen */
  }
  .split-media__grid { display: grid; grid-template-columns: minmax(0, 1fr); }
  .split-media__stat {
    margin-top: calc(-6 * 1rem / 16);
    font-size: var(--fs-stat);
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    line-height: var(--lh-display);
    text-align: center;
  }
  .split-media__stat .text-gradient { display: block; }
  /* móvil: «360°» siempre a todo el ancho del contenedor (Figma: 198,5 px
     en 373; el texto mide 1,849 em) — en 402 px coincide con --fs-stat */
  @media (width < 48em) {
    .split-media__stat { font-size: calc((100cqi - 2 * var(--container-pad)) / 1.849); }
  }
  .split-media__figure {
    position: relative;
    order: 1;
    margin-top: calc(-17.8 * 1rem / 16);
    --media-ratio: 373 / 274;
  }
  .split-media__title { order: 2; margin-top: calc(17 * 1rem / 16); font-size: var(--fs-h1); line-height: var(--lh-heading); }
  .split-media__lead { order: 3; margin-top: calc(18 * 1rem / 16); }   /* sin max-width: el párrafo ocupa el ancho del titular */

  @media (width >= 48em) {
    .split-media__grid { grid-template-columns: repeat(12, minmax(0, 1fr)); grid-template-rows: auto auto auto 1fr; align-items: start; }   /* la última fila (entradilla) absorbe el resto de la altura de la imagen */
    .split-media__grid > * { grid-column: 1 / 6; }
    .split-media__eyebrow { grid-row: 1; margin-top: calc(6 * 1rem / 16); }
    .split-media__stat { grid-row: 2; margin-top: -1px; text-align: start; }
    .split-media__stat .text-gradient { display: inline; }
    .split-media__title { grid-row: 3; margin-top: calc(39 * 1rem / 16); }   /* v1.2: antes 79; el texto termina a la altura de la imagen */
    .split-media__lead { grid-row: 4; margin-top: calc(52 * 1rem / 16); align-self: end; }   /* su última línea, a la altura del borde inferior de la imagen */
    .split-media__figure {
      grid-column: 6 / 13;
      grid-row: 1 / 5;
      margin: 0 0 0 calc(10 * 1rem / 16);
      --media-ratio: 951 / 600;
    }
    .split-media--media-first > .split-media__grid > * { grid-column: 8 / 13; }
    .split-media--media-first .split-media__figure { grid-column: 1 / 8; margin: 0 calc(10 * 1rem / 16) 0 0; }
  }

}


/* ───── sections/services.css ───── */
/* ==========================================================================
   SECCIÓN: .services                                     v1.1 · 11/10/2026
   Figma:      bloque del menú de servicios (entre «360°» y proyectos).
   Composición: solo ritmo vertical: el componente ril.menuServicios ocupa
               el contenedor. Huecos de Figma (móvil/escritorio):
               arriba 40 / 56 (sumados al final de «360°»: 90 / 169);
               abajo, en móvil, --section-y desde «VER MÁS» (v1.1: el bloque
               crece con la imagen del servicio activo).
   Escritorio: 120vh con el menú fijo y centrado (sticky) durante los 20vh
               de más; se ancla por el centro al hacer scroll.
   Uso:        {% call ril.section({ class: 'services', snap: true }) %}…{% endcall %}
   ========================================================================== */
@layer layout {

  /* móvil: palabras, imagen del servicio activo y VER MÁS al final; abajo,
     el padding de sección del sistema (--section-y) */
  .services {
    padding-top: calc(40 * 1rem / 16 + 16 * var(--fluid-c));
    padding-bottom: var(--section-y);
  }

  /* escritorio: bloque de 120vh. El contenedor es una caja fija (sticky) de
     una pantalla con el menú centrado: los 20vh de más son el recorrido en
     el que el menú se queda quieto. smooth-scroll.js ancla la sección por
     su centro (data-snap), que es justo cuando la caja está fija. */
  @media (width >= 48em) {
    .services {
      min-height: 120svh;
      padding-block: 0;
    }
    .services > .ril-container {
      position: sticky;
      top: 0;
      display: grid;
      align-content: center;
      height: 100svh;
      padding-block: var(--header-height);   /* centrado en la pantalla sin pisar la cabecera */
    }
    /* el componente lleva el aire de Figma solo arriba (70 de 189):
       el mismo abajo para que quede centrado de verdad */
    .services .ril-menu-servicios { padding-bottom: calc(70 / 189 * 1em); }
  }

}


/* ───── sections/showcase.css ───── */
/* ==========================================================================
   SECCIÓN: .showcase                                     v1.1 · 11/10/2026
   Figma:      proyectos sobre negro: titular centrado («Frame 322»), tres
               tarjetas escalonadas, cinta «PROYECTOS» y «VER MÁS» encima.
   Composición escritorio: cada tarjeta se coloca donde está en Figma
               (--x --y --w: px del frame de 1728, relativos a la primera
               tarjeta) en unidades del contenedor (cqi sobre 1648), así
               escala con el ancho:
                 Opal   x 0     y 0     w 812
                 FLM    x 1114  y 435   w 534
                 Hawaya x 139   y 1221  w 812
   Composición móvil: una columna de 376 px con 60 de hueco; todas las
               imágenes a 812 × 513.
   Cinta:      296 px (200 en móvil), ancho 75 %, crema que se funde hacia
               abajo (Figma: transparente al 22,8 % → crema al 10 % al 71,7 %;
               en móvil, 8,9 % → 20 %). «VER MÁS» centrado sobre ella.
   Medidas:    de Figma (móvil/escritorio) con --fluid-c.
   ========================================================================== */
/* recorte del titular: tamaño del brillo (animable) */
@property --title-glow { syntax: '<length>'; inherits: true; initial-value: 0px; }

@layer layout {

  .showcase {
    padding-top: calc(45 * 1rem / 16 + 88 * var(--fluid-c));
    padding-bottom: 0;
  }
  .showcase__title {
    max-width: 9em;
    margin-inline: auto;
    font-size: var(--fs-h1);
    line-height: var(--lh-heading);
    text-align: center;
  }
  /* el titular es un recorte en papel (con ratón; modules/title-glow.js pone
     [data-glow-ready]): sus letras dejan ver una brasa difuminada que sigue
     al ratón con inercia (--title-gx/gy; en «BRILLAR», --title-bx/by) y se
     abre al entrar en la sección (--title-glow). En las demás palabras la
     brasa llega suave, como bajo un velo crema del 80 %; en «BRILLAR», con
     toda su fuerza sobre su degradado. En táctil, el titular original. */
  .showcase__title[data-glow-ready] {
    color: transparent;
    background:
      radial-gradient(circle var(--title-glow) at var(--title-gx, 50%) var(--title-gy, 50%),
        color-mix(in srgb, var(--ril-glow-gold) 20%, var(--color-text)) 0,
        color-mix(in srgb, var(--ril-glow-amber) 20%, var(--color-text)) 25%,
        color-mix(in srgb, var(--ril-glow-orange) 20%, var(--color-text)) 50%,
        color-mix(in srgb, var(--ril-glow-ember) 12%, var(--color-text)) 75%,
        var(--color-text) 100%),
      linear-gradient(var(--color-text), var(--color-text));
    -webkit-background-clip: text;
    background-clip: text;
    transition: --title-glow 0.9s var(--ease-standard);
  }
  .showcase__title[data-glow-ready] .text-gradient {
    background-image:
      radial-gradient(circle var(--title-glow) at var(--title-bx, 50%) var(--title-by, 50%),
        var(--ril-glow-gold) 0, var(--ril-glow-amber) 22%, var(--ril-glow-orange) 42%, var(--ril-glow-ember) 62%, transparent 100%),
      var(--gradient-primary);
  }
  .showcase__title[data-glow] { --title-glow: max(18rem, 22vw); }
  @media (prefers-reduced-motion: reduce) {
    .showcase__title[data-glow-ready] { transition: none; }
  }
  .showcase__grid {
    display: grid;
    gap: calc(60 * 1rem / 16);
    margin: calc(97 * 1rem / 16) -1px 0;
  }
  .showcase__item { --project-ratio: 812 / 513; }

  @media (width >= 48em) {
    .showcase__title { max-width: 9.3em; }
    .showcase__grid {
      container-type: inline-size;
      gap: 0;
      margin: calc(141 * 1rem / 16) 0 0;
    }
    .showcase__item {
      --project-ratio: initial;
      grid-area: 1 / 1;
      align-self: start;
      width: calc(var(--w) * 100cqi / 1648);
      margin-left: calc(var(--x) * 100cqi / 1648);
      margin-top: calc(var(--y) * 100cqi / 1648);
    }
    .showcase__item:nth-child(2) { --project-text-w: 78.3%; }   /* Figma: 418 de 534 */
  }

  /* cinta + «VER MÁS» */
  .showcase__ribbon {
    position: relative;
    margin-top: calc(5 * 1rem / 16 + 72 * var(--fluid-c));
    --ribbon-from: 8.9%;
    --ribbon-alpha: 20%;
  }
  .showcase__marquee {
    --marquee-gap: 0.2em;
    font-size: var(--fs-display-2xl);
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-display);
    line-height: normal;
    text-transform: uppercase;
  }
  .showcase__marquee .marquee__group {
    color: transparent;
    background: linear-gradient(0deg, transparent var(--ribbon-from), color-mix(in srgb, var(--color-text) var(--ribbon-alpha), transparent) 71.7%);
    -webkit-background-clip: text;
    background-clip: text;
  }
  .showcase__more {
    position: absolute;
    left: 50%;
    top: 47%;
    translate: -50% 0;
  }
  @media (width >= 48em) {
    .showcase__ribbon { --ribbon-from: 22.8%; --ribbon-alpha: 10%; }
  }

}


/* ───── sections/proof.css ───── */
/* ==========================================================================
   SECCIÓN: .proof                                        v1.1 · 11/10/2026
   Figma:      «El 95% de nuestros clientes nos recomienda» + texto a la
               derecha + dos filas de logos de clientes.
   Composición escritorio: titular (86 px, ancho 75 %) en columnas 1-5 y
               texto (22 px, medio) en 9-12, alineados abajo; a 127 px, dos
               cintas de logos (cajas de 253 × 149, 36 de hueco, 54 entre
               filas) a sangre. Esquinas en crema al 50 %; logos al 100 %.
   Composición móvil: titular (44) con «95%» en degradado vertical, texto
               (18, crema al 80 %) a 18 px; logos a 67 px en cajas de
               163 × 96 con esquinas de 9 px al 80 %.
   Medidas:    de Figma (móvil/escritorio) con --fluid-c.
   ========================================================================== */
@layer layout {

  .proof {
    padding-top: calc(65 * 1rem / 16 + 49 * var(--fluid-c));
    padding-bottom: calc(127 * 1rem / 16 + 101 * var(--fluid-c));
  }
  .proof__head { display: grid; gap: calc(18 * 1rem / 16); }

  /* --strip (Servicios): solo una cinta, sobre crema, con los logos en negro */
  .proof--strip { padding-block: calc(24 * 1rem / 16 + 8 * var(--fluid-c)) calc(24 * 1rem / 16 + 40 * var(--fluid-c)); }
  .proof--strip .proof__logos { margin-top: 0; }
  .proof--strip .client-logo__img { filter: brightness(0); }
  .proof:not(.proof--strip) .client-logo__img { opacity: 0.7; }   /* logos blancos al 80 % sobre el fondo oscuro */
  .proof__title {
    font-size: var(--fs-h1-lg);
    font-stretch: var(--ril-stretch-display);
    line-height: var(--lh-heading);
  }
  .proof__lead { line-height: var(--lh-normal); color: color-mix(in srgb, currentColor 80%, transparent); }
  .proof__logos {
    display: grid;
    gap: calc(24.3 * 1rem / 16);
    margin-top: calc(67 * 1rem / 16);
    color: color-mix(in srgb, var(--color-text) 80%, transparent);
    --marquee-gap: calc(18 * 1rem / 16);
    --marquee-dur: 50s;
    --client-w: calc(162.6 * 1rem / 16);
    --client-corner: 9px;
    --client-logo-scale: 0.8;
  }

  @media (width >= 48em) {
    .proof__head { grid-template-columns: repeat(12, minmax(0, 1fr)); align-items: end; gap: 0; }
    .proof__title { grid-column: 1 / 7; max-width: 8.4em; }
    .proof__title .text-gradient { --gradient-primary: linear-gradient(var(--color-text), var(--color-text)); }   /* en escritorio, «95%» en crema */
    .proof__lead { grid-column: 9 / 13; max-width: 23.8em; margin-left: calc(11 * 1rem / 16); font-weight: var(--fw-medium); color: inherit; }
    .proof__logos {
      gap: calc(54 * 1rem / 16);
      margin-top: calc(127 * 1rem / 16);
      color: color-mix(in srgb, var(--color-text) 50%, transparent);
      --marquee-gap: calc(36 * 1rem / 16);
      --client-w: calc(253 * 1rem / 16);
      --client-corner: 14px;
      --client-logo-scale: 1;
    }
  }

}


/* ───── sections/team-orbit.css ───── */
/* ==========================================================================
   SECCIÓN: .team-orbit                                   v1.3 · 11/10/2026
   Figma:      escritorio «Group 252» (31 fotos circulares, algunas giradas),
               «Ellipse 94» (halo crema que aclara el centro) y «Group 286»
               (antetítulo, «EL EQUIPO», texto y CONÓCENOS) centrado.
               Móvil: disposición propia de 21 fotos (70-90 px) y halo de
               466 × 497.
   Escena:     tamaño del bloque de Figma (escritorio 1728 × 1610; móvil
               402 × 1000), escalado al ancho. Cada foto: --x --y (centro),
               --s (diámetro) en px del frame, --r (giro de Figma).
               --frame-w / --frame-h toman el frame según el ancho.
   Contenido:  centrado en el centro de las órbitas (--ocy / --ocy-m,
               datos orbit / orbitMobile), igual que el halo
               («team-orbit__halo» en Figma).
   Fotos:      decorativas (alt="").
   Órbita (v1.3): modules/team-orbit.js las hace girar por las órbitas
               del diseño: anillos por tamaño de foto (2 en escritorio, 3 en
               móvil; [data-ring] 1 = interior), cada uno con su elipse y su
               ritmo (hacia fuera, más rápido). El interior va desenfocado.
   ========================================================================== */
@layer layout {

  .team-orbit__stage {
    --frame-w: var(--stage-mw, var(--stage-w));
    --frame-h: var(--stage-mh, var(--stage-h));
    --frame-ocy: var(--ocy-m, var(--ocy, 434));             /* centro de las órbitas (texto y halo) */
    position: relative;
    container-type: inline-size;
    display: grid;
    justify-items: center;
    align-items: start;
    min-height: calc(var(--frame-h) * 100cqi / var(--frame-w));
    overflow: clip;
  }
  /* halo: crema opaca hasta el 52 % y transparente al 82 % (Figma) */
  .team-orbit__stage::before {
    content: "";
    position: absolute;
    left: 50%;
    top: calc(var(--frame-ocy) * 100cqi / var(--frame-w));
    width: calc(466 * 100cqi / var(--frame-w));
    aspect-ratio: 466 / 497;
    translate: -50% -50%;
    background: radial-gradient(closest-side, var(--color-background) 52%, transparent 82%);
    pointer-events: none;
  }
  .team-orbit__avatar {
    position: absolute;
    left: calc((var(--x) - var(--frame-ox, 0)) * 100cqi / var(--frame-w));
    top: calc(var(--y) * 100cqi / var(--frame-w));
    width: calc(var(--s) * var(--avatar-k, 1) * 100cqi / var(--frame-w));
    aspect-ratio: 1;
    translate: -50% -50%;
    rotate: calc(var(--r) * -1deg);
    border-radius: var(--radius-full);
  }
  /* anillos (team-orbit.js): el interior, al fondo y algo desenfocado */
  .team-orbit__avatar[data-ring="1"] { z-index: var(--z-base); filter: blur(1px); }
  .team-orbit__avatar[data-ring="2"] { z-index: calc(var(--z-base) + 1); }
  .team-orbit__avatar[data-ring="3"] { z-index: calc(var(--z-base) + 2); }
  .team-orbit__avatar--desktop { display: none; }
  /* con órbita (team-orbit.js), en móvil también las fotos de escritorio, a
     escala de móvil (113 → 70 px) */
  .team-orbit__stage[data-orbit-ready] { --avatar-k: 0.62; }
  .team-orbit__stage[data-orbit-ready] .team-orbit__avatar--desktop { display: block; }
  .team-orbit__stage[data-orbit-ready] .team-orbit__avatar--mobile { display: none; }
  .team-orbit__avatar--front { z-index: var(--z-base); }

  .team-orbit__content {
    position: relative;
    z-index: calc(var(--z-base) + 3);   /* el texto, siempre sobre las fotos (capas 0-2) */
    display: grid;
    justify-items: center;
    /* centrado en el centro de las órbitas: las fotos giran a su alrededor */
    align-self: start;
    margin-top: calc(var(--frame-ocy) * 100cqi / var(--frame-w));
    translate: 0 -50%;
    text-align: center;
  }
  .team-orbit__eyebrow { --eyebrow-fs: var(--fs-eyebrow-lg); }
  .team-orbit__title {
    margin-top: calc(1px + 3 * var(--fluid-c));
    font-size: var(--fs-display-xl);
    line-height: 1.03;
    white-space: nowrap;
  }
  .team-orbit__text { max-width: 19.7em; margin-top: calc(25 * 1rem / 16 - 4 * var(--fluid-c)); line-height: var(--lh-normal); }
  .team-orbit__more { margin-top: calc(27 * 1rem / 16 + 13 * var(--fluid-c)); --link-more-tag-gap: calc(var(--space-2xs) - 10px); }   /* la etiqueta EQUIPO, 10 px más abajo: no pisa el texto */

  @media (width >= 48em) {
    .team-orbit__stage, .team-orbit__stage[data-orbit-ready] { --frame-w: var(--stage-w); --frame-h: var(--stage-h); --frame-ocy: var(--ocy, 797); --avatar-k: 1; }
    .team-orbit__stage::before { width: calc(1080 * 100cqi / var(--frame-w)); aspect-ratio: 1; }
    .team-orbit__avatar--desktop { display: block; }
    .team-orbit__avatar--mobile { display: none; }
    .team-orbit__title { font-stretch: var(--ril-stretch-display); line-height: var(--lh-tight); }
    .team-orbit__text { max-width: 25.5em; }
  }

  /* tablet (48-64em): la escena de escritorio recortada por los lados (frame
     de 1300 de los 1728, centrado): fotos y anillos más grandes, alrededor
     del texto como en escritorio */
  @media (48em <= width < 64em) {
    .team-orbit__stage, .team-orbit__stage[data-orbit-ready] { --frame-w: 1300; --frame-ox: 214; }
    .team-orbit__text { max-width: 19em; }   /* el párrafo, dentro del anillo interior */
  }

}


/* ───── sections/media-title.css ───── */
/* ==========================================================================
   SECCIÓN: .media-title                                  v1.1 · 11/10/2026
   Figma escritorio: «rIL web [desktop] 2» (vídeo a sangre; aquí a 100vh, no 1152 px) con
               «Así trabajamos en rIL» (200 px, ancho 75 %, crema) a 39 px
               del borde inferior; pegado al bloque del equipo (11/10: sin los 38 px de Figma).
   Figma móvil: titular en negro sobre crema (77 px, tres filas) y el vídeo
               como tarjeta (160 × 232, radio 8,5, girada −2,75°) que lo pisa
               por la derecha; sol amarillo abajo a la derecha. El bloque
               negro siguiente empieza 514 px por debajo del titular.
   Medidas:    de Figma (móvil/escritorio) con --fluid-c.
   ========================================================================== */
@layer layout {

  .media-title {
    padding: calc(67 * 1rem / 16) var(--container-pad) 0;
    min-height: calc((67 + 514) * 1rem / 16);
  }
  .media-title__title {
    /* móvil: «TRABAJAMOS» (4,95 em con su letra ancha al 110 %) ocupa todo el ancho */
    font-size: calc(100cqi / 4.97);           /* cqi: el ancho de contenido de la sección (ya sin márgenes) */
    font-stretch: var(--ril-stretch-display);
    line-height: var(--lh-tight);
  }
  /* móvil: tarjeta girada (centro a 259 × 240 px del titular) */
  .media-title__media {
    position: absolute;
    z-index: calc(var(--z-base) + 1);      /* la tarjeta pisa el titular */
    left: calc(178.5 * 1rem / 16);
    top: calc((67 + 124) * 1rem / 16);
    width: calc(160.5 * 1rem / 16);
    rotate: -2.75deg;
    --media-ratio: 160.5 / 232.2;
    --media-radius: calc(8.55 * 1rem / 16);
  }

  @media (width >= 48em) {
    .media-title {
      padding: 0;                        /* el vídeo, pegado al bloque del equipo (Figma dejaba 38 px) */
      min-height: 0;
    }
    .media-title__media {
      position: relative;
      z-index: auto;
      left: auto;
      top: auto;
      width: auto;
      rotate: none;
      height: 100svh;                    /* vídeo corporativo a pantalla completa */
      --media-ratio: auto;
      --media-radius: 0;
    }
    .media-title__figure { height: 100%; }
    .media-title__title {
      font-size: min(var(--fs-display-lg), (100cqi - 2 * var(--container-pad)) / 8.35);   /* una sola línea (con su letra ancha): no pasa del ancho */
      position: absolute;
      z-index: calc(var(--z-base) + 1);
      inset-inline: 0;
      bottom: 0.195em;
      padding-inline: var(--container-pad);
      text-align: center;
      white-space: nowrap;
      color: var(--color-light);
    }
  }

}


/* ───── sections/tools.css ───── */
/* ==========================================================================
   SECCIÓN: .tools                                        v1.1 · 11/10/2026
   Figma escritorio: sobre negro, a continuación del vídeo: logos de
               herramientas («Group 285», 723 × 205) a la izquierda, sobre el
               sol; a la derecha, «+ EL ORIGEN DE NUESTRA LUZ» (32 px) y tres
               párrafos (18 px) en 671 px.
   Figma móvil: cinta de logos en una fila (a 43 px del borde), intro de
               18 px y desplegable «+ CÓMO HACEMOS QUE FUNCIONE» con filete.
   Composición: logos en columnas 1-6 (35 px dentro), texto en 8-12 (16 px
               dentro); móvil apilado.
   Medidas:    de Figma (móvil/escritorio) con --fluid-c.
   ========================================================================== */
@layer layout {

  /* soles compartidos con el bloque siguiente («¿Listo para brillar?»):
     ninguno de los dos se aísla, los soles de ambos van en z 1 (por encima
     de los dos fondos negros) y el contenido en z 2. Si no, el fondo de un
     bloque corta el degradado del otro y se ve una línea entre ambos. */
  .tools { isolation: auto; padding-block: calc(43 * 1rem / 16) 0; }
  .tools { --sun-z: calc(var(--z-base) + 1); }
  .tools > :not(.sun) { z-index: calc(var(--z-base) + 2); }

  /* móvil: cinta de logos (las dos filas de la imagen, una tras otra, al 81 %) */
  .tools__strip { margin-left: calc(-40 * 1rem / 16); }
  .tools__marquee { --marquee-gap: calc(12 * 1rem / 16); --marquee-dur: 30s; }
  .tools__row {
    width: calc(586 * 1rem / 16);
    height: calc(83 * 1rem / 16);
    overflow: hidden;
  }
  .tools__row img { display: block; width: 100%; height: auto; }
  .tools__row--2 img { margin-top: calc(-83 * 1rem / 16); }

  .tools__grid { display: grid; }
  .tools__logos, .tools__body { display: none; }
  .tools__intro { max-width: 18.8em; margin-top: calc(41 * 1rem / 16); line-height: var(--lh-normal); }
  .tools__details { margin-top: calc(26 * 1rem / 16); padding-bottom: calc(20 * 1rem / 16); border-bottom: var(--border-width) solid color-mix(in srgb, var(--color-text) 30%, transparent); }
  .tools__summary::after { content: ""; position: absolute; inset: -10px 0; }   /* área de toque de 44 px */
  .tools__summary {
    position: relative;
    display: flex;
    font-size: var(--fs-label);
    font-stretch: var(--ril-stretch-label);
    line-height: var(--lh-label);
    letter-spacing: var(--ls-wider);
    text-transform: uppercase;
    align-items: center;
    gap: calc(12 * 1rem / 16);
    list-style: none;
    cursor: pointer;
  }
  .tools__summary::-webkit-details-marker { display: none; }
  .tools__summary::before { content: "+"; font-size: 1.1em; transition: rotate var(--dur-base) var(--ease-standard); }
  .tools__details[open] .tools__summary::before { rotate: 45deg; }
  .tools__details .tools__text { margin-top: var(--space-md); }

  .tools__text p { line-height: var(--lh-normal); }
  .tools__text p + p { margin-top: calc(10 * 1rem / 16); }

  @media (width >= 48em) {
    .tools { padding-top: calc(72 * 1rem / 16); }
    .tools__strip, .tools__mobile { display: none; }
    .tools__grid { grid-template-columns: repeat(12, minmax(0, 1fr)); align-items: center; }   /* las dos columnas, centradas en vertical */
    .tools__logos { display: block; grid-column: 1 / 7; grid-row: 1; margin: 0 0 0 calc(35 * 1rem / 16); }
    .tools__logos img { width: 100%; max-width: calc(723 * 1rem / 16); height: auto; }
    /* logos sueltos (recortes de la misma imagen): al pasar por uno, crece
       un 1 % y los demás bajan al 50 % */
    ul.tools__logos {
      position: relative;
      max-width: calc(723 * 1rem / 16);
      aspect-ratio: var(--logos-w) / var(--logos-h);
      padding: 0;
      list-style: none;
    }
    .tools__logo {
      position: absolute;
      left: calc(var(--x) / var(--logos-w) * 100%);
      top: calc(var(--y) / var(--logos-h) * 100%);
      width: calc(var(--w) / var(--logos-w) * 100%);
      height: calc(var(--h) / var(--logos-h) * 100%);
      background: var(--logos) no-repeat;
      background-size: calc(var(--logos-w) / var(--w) * 100%) calc(var(--logos-h) / var(--h) * 100%);
      background-position: calc(var(--x) / (var(--logos-w) - var(--w)) * 100%) calc(var(--y) / (var(--logos-h) - var(--h)) * 100%);
      transition: opacity var(--dur-base) var(--ease-standard), scale var(--dur-base) var(--ease-standard);
    }
    .tools__logo:hover { scale: 1.01; }
    .tools__logos:has(.tools__logo:hover) .tools__logo:not(:hover) { opacity: 0.5; }
    .tools__body { display: block; grid-column: 8 / 13; grid-row: 1; margin-left: calc(16 * 1rem / 16); }
    .tools__eyebrow { --eyebrow-fs: var(--fs-eyebrow-lg); }
    .tools__body .tools__text { margin-top: calc(9.6 * 1rem / 16); }
  }

}


/* ───── sections/briefing.css ───── */
/* ==========================================================================
   SECCIÓN: .briefing                                     v1.3 · 11/10/2026
   Figma:      «Frame 352» (6573:5518, página FINAL), bloque de 1728 × 940
               sobre negro, antes del pie.
               · Portada: «DEFINAMOS TU PROYECTO JUNTOS» (24) · «¿LISTO PARA
                 BRILLAR?» (108, ancho 75 %, a la derecha, con un punto amarillo
                 de 76 px) · botón crema EMPIEZA YA (388 × 98) con brillo
                 amarillo abajo a la derecha que crece al pasar (0,3 s).
               · Al pulsar: seis tarjetas crema (533 × 463, radio 8) entran
                 desde la derecha; la actual queda en el centro, girada; las
                 respondidas se apilan debajo; la siguiente asoma por la derecha
                 y es el botón SIGUIENTE (etiqueta amarilla girada al pasar).
                 Smart Animate de 1 s ease-in-out.
               · Opciones: gris (crema + 14 % de negro), más oscuro al pasar
                 (0,2 s), amarillo al elegir. Última tarjeta: campos de contacto
                 y ENVIAR (crema, 48; al pasar la flecha gira a → y crece el
                 filete).
   Animación (v1.1): al llegar a pantalla ([data-in]) suben el antetítulo,
               el titular y EMPIEZA YA, y el punto sale como un sol (muelle
               Quick). La tarjeta que asoma se adelanta al pasar por
               SIGUIENTE; elegir una opción da un pequeño latido; EMPIEZA YA
               se hunde bajo la primera tarjeta. Al enviar, las tarjetas se
               recogen en el montón y aparece el agradecimiento.
   v1.2: EMPIEZA YA del tamaño de CONTACTA (cabecera), con su forma de
               pastilla; en escritorio el bloque mide 120vh y el escenario se
               queda fijo y centrado (sticky) como el menú de servicios; las
               capas del formulario ya no tapan el botón (pointer-events).
   Móvil (v1.1): como en escritorio, las tarjetas entran desde la derecha
               y tapan EMPIEZA YA (misma celda de rejilla).
   Estados:    [data-step] en la sección (0 = portada, 1-6 = tarjeta actual,
               done = enviado),
               [data-ready] cuando hay JS; data-pos en cada tarjeta
               (stack · current · next · queue). Sin JS el formulario se ve
               entero y se envía.
   Posiciones: datos (centro y giro de cada tarjeta en cada estado), en px del
               bloque de 1728 escalados al ancho (cqi); tarjetas de tamaño fijo.
   Medidas:    de Figma; móvil propio (Figma no tiene este bloque en móvil).
   ========================================================================== */
@layer layout {

  /* sin aislamiento propio: sus soles y los de .tools se mezclan sobre los
     dos fondos negros (si no, el borde entre bloques corta el degradado);
     el contenido va por encima de todos (escenario en z 2) */
  .briefing { isolation: auto; padding-bottom: var(--space-3xl); }   /* aire antes del pie */
  .briefing { --sun-z: calc(var(--z-base) + 1); }   /* con los de .tools (tools.css) */
  /* arco de luz (tarjeta C del Presupuestador): tres manchas que entran por
     arriba a la derecha, grano y un velo que oscurece hacia abajo. Llega
     desenfocado y se enfoca cuando el bloque está a la vista ([data-in]). */
  /* al 20 %: el degradado fuerte es el del pie, que viene después; y fundido
     arriba, para que no haya corte con el bloque de herramientas */
  .briefing__glow {
    position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
    opacity: 0.2;
    -webkit-mask-image: linear-gradient(to bottom, transparent, var(--color-dark) 35%);
    mask-image: linear-gradient(to bottom, transparent, var(--color-dark) 35%);
  }
  .briefing__glow-im { position: absolute; inset: 0; overflow: hidden; filter: blur(34px); transform: scale(1.2); transition: filter 1.6s var(--ease-in-out), transform 1.6s var(--ease-in-out); }
  .briefing[data-in] .briefing__glow-im { filter: blur(0); transform: none; }
  .briefing__glow b { position: absolute; display: block; border-radius: 50%; }
  .briefing__glow-1 {
    width: 190%; height: 78%; right: -70%; top: -38%; filter: blur(26px);
    background: radial-gradient(closest-side, var(--ril-glow-gold) 0, var(--ril-glow-amber) 30%, var(--ril-glow-orange) 52%, var(--ril-glow-ember) 66%, color-mix(in srgb, var(--ril-glow-wine) 85%, transparent) 80%, color-mix(in srgb, var(--ril-glow-night) 60%, transparent) 90%, transparent 100%);
  }
  .briefing__glow-2 {
    width: 120%; height: 46%; right: -48%; top: -14%; filter: blur(30px);
    background: radial-gradient(closest-side, color-mix(in srgb, var(--ril-glow-cream) 90%, transparent), color-mix(in srgb, var(--ril-glow-amber) 50%, transparent) 50%, transparent);
  }
  .briefing__glow-3 {
    width: 150%; height: 70%; left: -62%; top: 6%; filter: blur(22px);
    background: radial-gradient(closest-side, color-mix(in srgb, var(--color-dark) 75%, transparent) 0, color-mix(in srgb, var(--color-dark) 75%, transparent) 58%, color-mix(in srgb, var(--ril-glow-night) 60%, transparent) 74%, transparent 100%);
  }
  .briefing__glow-grain {
    inset: 0; border-radius: 0 !important; opacity: 0.22; mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  }
  .briefing__glow-scrim {
    inset: 0; border-radius: 0 !important;
    background: linear-gradient(180deg, transparent 0, transparent 30%, color-mix(in srgb, var(--color-dark) 40%, transparent) 48%, color-mix(in srgb, var(--color-dark) 60%, transparent) 66%, color-mix(in srgb, var(--color-dark) 60%, transparent) 100%);
  }
  @media (prefers-reduced-motion: reduce) { .briefing__glow-im { transition: none; } }

  .briefing__scene { display: contents; }   /* móvil: sin envoltorio; escritorio: escena escalable */
  .briefing__stage {
    position: relative;
    z-index: calc(var(--z-base) + 2);
    container-type: inline-size;
    padding: calc(60 * 1rem / 16) var(--container-pad) var(--space-2xl);
  }

  /* cabecera */
  .briefing__head {
    display: grid;
    justify-items: center;
    gap: calc(18 * 1rem / 16);
    width: min(100%, calc(474 * 1rem / 16 + 50 * var(--fluid-c)));
    margin-inline: auto;
    text-align: center;
  }
  .briefing__title {
    position: relative;
    font-size: var(--fs-cta);
    font-stretch: var(--ril-stretch-display);
    line-height: var(--lh-tight);
    text-align: end;
  }
  .briefing__dot {
    position: absolute;
    left: 0.287em;
    top: 1.03em;
    width: 0.704em;
    aspect-ratio: 1;
    border-radius: var(--radius-full);
    background-color: var(--color-brand);
  }

  /* EMPIEZA YA */
  .briefing__start {
    text-decoration: none;   /* en briefing-cta es un <a>: sin el subrayado del enlace */
    position: relative;
    isolation: isolate;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.07em;
    margin: var(--space-xl) auto 0;
    padding: 0.45em 0.8em 0.4em 0.9em;
    overflow: hidden;
    font: inherit;
    font-size: var(--fs-btn-cta);           /* como CONTACTA de la cabecera */
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    line-height: var(--lh-snug);
    text-transform: uppercase;
    color: var(--color-dark);
    background-color: var(--color-light);
    border: 0;
    border-radius: var(--radius-small);
    cursor: pointer;
  }
  .briefing__start::after {        /* brillo amarillo abajo a la derecha */
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: radial-gradient(60% 120% at 110% 140%, var(--color-brand), transparent);
    opacity: 0.45;
    transition: opacity var(--dur-fast) var(--ease-standard);
  }
  .briefing__start:is(:hover, :focus-visible)::after { opacity: 1; }
  .briefing__start .icon { --icon-size: 0.8em; --icon-stroke: 3; transition: transform var(--dur-base) var(--ease-standard); }
  .briefing__start:is(:hover, :focus-visible) .icon { transform: rotate(45deg); }
  /* el formulario está encima del botón (misma zona): solo reciben el
     puntero las tarjetas y los botones, no las capas que los contienen */
  .briefing[data-ready] :is(.briefing__form, .briefing__cards) { pointer-events: none; }
  .briefing[data-ready] :is(.briefing__card, .briefing__next, .briefing__prev, .briefing__submit, .briefing__thanks, .briefing__mail) { pointer-events: auto; }

  /* tarjetas */
  .briefing__cards { display: grid; gap: var(--space-lg); margin: var(--space-2xl) 0 0; padding: 0; list-style: none; }
  .briefing__card {
    display: flex;
    flex-direction: column;
    width: min(100%, calc(533 * 1rem / 16));
    min-height: calc(463 * 1rem / 16);
    margin-inline: auto;
    padding: calc(37 * 1rem / 16) calc(35 * 1rem / 16) calc(38 * 1rem / 16) calc(34.5 * 1rem / 16);
    color: var(--color-dark);
    background-color: var(--color-light);
    border-radius: var(--radius-small);
  }
  .briefing__fieldset { display: contents; }
  .briefing__question {
    float: left;                     /* la leyenda, como un bloque más */
    width: 100%;
    max-width: 7.9em;
    padding: 0;
    font-size: var(--fs-btn-large);
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    line-height: 1;
    text-transform: uppercase;
  }
  .briefing__count {
    position: absolute;
    top: calc(40 * 1rem / 16);
    right: calc(35 * 1rem / 16);
    font-size: var(--fs-label);
    font-stretch: var(--ril-stretch-cta);
    line-height: var(--lh-label);
    letter-spacing: var(--ls-wide);
  }
  .briefing__card { position: relative; }
  .briefing__text { clear: both; max-width: 24.4em; margin-top: calc(14 * 1rem / 16); line-height: var(--lh-normal); }
  .briefing__options {
    display: flex;
    flex-wrap: wrap;
    gap: calc(12 * 1rem / 16) calc(8 * 1rem / 16);
    max-width: calc(437 * 1rem / 16);
    margin-top: auto;
    padding-top: var(--space-lg);
  }
  .briefing__option { position: relative; cursor: pointer; }
  /* el área de toque (la casilla invisible) sobresale 7 px arriba y abajo: 44 px */
  .briefing__option input { position: absolute; inset: -7px 0; opacity: 0; margin: 0; cursor: pointer; }
  .briefing__option span {
    display: block;
    padding: calc(8 * 1rem / 16) calc(16 * 1rem / 16);
    font-size: var(--fs-body);
    font-stretch: var(--ril-stretch-cta);
    line-height: var(--lh-label);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    background-color: color-mix(in srgb, var(--color-dark) 14%, var(--color-light));
    border-radius: calc(6 * 1rem / 16);
    transition: background-color var(--dur-fast) var(--ease-standard);
  }
  .briefing__option:hover span { background-color: color-mix(in srgb, var(--color-dark) 26%, var(--color-light)); }
  .briefing__option input:checked + span { background-color: var(--color-brand); }
  .briefing__option input:focus-visible + span { outline: var(--focus-width) solid var(--color-dark); outline-offset: var(--focus-offset); }
  .briefing__fields { display: grid; gap: calc(14 * 1rem / 16); margin-top: auto; padding-top: var(--space-lg); }
  .briefing__field input {
    width: 100%;
    padding: calc(12 * 1rem / 16) calc(18 * 1rem / 16);
    font: inherit;
    font-size: max(1rem, var(--fs-body));   /* nunca por debajo de 16 px: iOS amplía la página al escribir */
    line-height: var(--lh-normal);
    color: var(--color-dark);
    background-color: color-mix(in srgb, var(--color-dark) 12%, var(--color-light));
    border: 0;
    border-radius: var(--radius-small);
  }
  .briefing__field input::placeholder { color: var(--color-dark); opacity: 1; }
  .briefing__field input:focus-visible { outline: var(--focus-width) solid var(--color-dark); outline-offset: var(--focus-offset); }
  .briefing__field input[aria-invalid="true"] { box-shadow: inset 0 0 0 2px var(--color-accent); }

  /* ANTERIOR y SIGUIENTE (con JS) y ENVIAR */
  .briefing__nav { display: contents; }
  .briefing__next, .briefing__prev { display: none; }
  .briefing[data-ready]:not([data-step="0"], [data-step="1"], [data-step="done"]) .briefing__prev {
    display: block;
    padding: 0;
    background: none;
    border: 0;
    cursor: pointer;
  }
  .briefing__prev-tag {
    --tag-fs: var(--fs-btn-cta);
    --tag-pad-x: 0.643em;
    --tag-bg: var(--color-light);
    --tag-fg: var(--color-dark);
    display: inline-flex;
    align-items: center;
    gap: 0.3em;
    line-height: var(--lh-label);
    rotate: -2deg;
    transition: translate var(--dur-fast) var(--ease-standard), rotate var(--dur-fast) var(--ease-standard);
  }
  .briefing__prev-tag .icon { --icon-size: 0.8em; --icon-stroke: 3; rotate: 180deg; }
  .briefing__prev:is(:hover, :focus-visible) .briefing__prev-tag { translate: -4px -6px; rotate: -5deg; }
  .briefing__next-tag {
    --tag-fs: var(--fs-btn-cta);
    --tag-pad-x: 0.643em;
    display: inline-flex;
    align-items: center;
    gap: 0.3em;
    line-height: var(--lh-label);
    transition: background-color var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard), translate var(--dur-fast) var(--ease-standard), rotate var(--dur-fast) var(--ease-standard);
  }
  /* desactivado hasta responder la tarjeta: se ve, pero apagado */
  .briefing__next:disabled { cursor: not-allowed; }
  .briefing__next-tag .icon { --icon-size: 0.8em; --icon-stroke: 3; }
  /* escritorio: sobre la tarjeta crema que asoma → gris */
  .briefing__next:disabled .briefing__next-tag {
    --tag-bg: color-mix(in srgb, var(--color-dark) 22%, var(--color-light));
    --tag-fg: color-mix(in srgb, var(--color-dark) 62%, var(--color-light));
  }
  .briefing__next:not(:disabled) .briefing__next-tag { animation: briefing-pop var(--dur-base) var(--ease-standard); }
  .briefing__submit {
    display: flex;
    align-items: center;
    gap: 0.4em;
    margin: var(--space-xl) auto 0;
    padding: 0 0 calc(4 * 1rem / 16);
    font: inherit;
    font-size: var(--fs-btn-large);
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    line-height: 1;
    text-transform: uppercase;
    color: inherit;
    background: linear-gradient(currentColor, currentColor) left bottom / 0 2px no-repeat;
    border: 0;
    cursor: pointer;
    transition: background-size var(--dur-base) var(--ease-standard);
  }
  .briefing__submit .icon { --icon-size: 0.62em; --icon-stroke: 3; transition: transform var(--dur-base) var(--ease-standard); }
  .briefing__submit:is(:hover, :focus-visible) { background-size: 100% 2px; }
  .briefing__submit:is(:hover, :focus-visible) .icon { transform: rotate(45deg); }

  /* ---- con JS: escena -------------------------------------------------- */
  .briefing[data-ready] .briefing__form { position: relative; }
  .briefing[data-ready] .briefing__card {
    position: absolute;
    z-index: var(--z, var(--i));   /* --z lo pone el JS: actual arriba, cola en orden de aparición */
    margin: 0;
    translate: -50% -50%;
    transition:
      left 1s var(--ease-in-out),
      top 1s var(--ease-in-out),
      rotate 1s var(--ease-in-out),
      translate var(--dur-base) var(--ease-standard);
  }
  .briefing[data-ready] .briefing__submit,
  .briefing[data-ready] .briefing__start { transition: opacity 1s var(--ease-in-out), visibility 0s linear; }
  .briefing[data-ready]:not([data-step="6"]) .briefing__submit { opacity: 0; visibility: hidden; transition-delay: 0s, 1s; }
  /* EMPIEZA YA se hunde (se encoge y baja) mientras la primera tarjeta
     llega por la derecha y lo tapa */
  .briefing[data-ready]:not([data-step="0"]) .briefing__start {
    visibility: hidden;
    opacity: 0;
    transform: translateY(0.3em) scale(0.86);
    transition: transform 0.45s var(--ease-standard), opacity 0.5s var(--ease-in-out) 0.45s, visibility 0s linear 1s;
  }

  /* ---- entrada del bloque ([data-in], la pone el JS al verse) ---------- */
  .briefing[data-ready]:not([data-in]) :is(.briefing__eyebrow, .briefing__title, .briefing__start) { opacity: 0; }
  .briefing[data-ready]:not([data-in]) .briefing__dot { transform: scale(0); }
  .briefing[data-in] .briefing__eyebrow { animation: briefing-rise var(--dur-slow) var(--ease-standard) backwards; }
  .briefing[data-in] .briefing__title   { animation: briefing-rise var(--dur-slow) var(--ease-standard) 120ms backwards; }
  .briefing[data-in] .briefing__dot     { animation: briefing-sun var(--ril-dur-quick) var(--ril-ease-quick) 520ms backwards; }
  .briefing[data-in] .briefing__start   { animation: briefing-rise var(--dur-slow) var(--ease-standard) 380ms backwards; }
  @keyframes briefing-rise {
    from { opacity: 0; transform: translateY(0.4em); }
  }
  @keyframes briefing-sun {        /* sale desde abajo, como un sol que amanece */
    from { transform: translateY(60%) scale(0); }
  }

  /* elegir una opción: latido */
  .briefing__option input:checked + span { animation: briefing-pop var(--dur-base) var(--ease-standard); }
  @keyframes briefing-pop { 40% { transform: scale(1.06); } }

  /* enviado: agradecimiento */
  .briefing__thanks {
    max-width: 22em;
    margin: var(--space-xl) auto 0;
    font-size: var(--fs-body-lg);
    font-weight: var(--fw-medium);
    line-height: var(--lh-normal);
    text-align: center;
    animation: briefing-rise var(--dur-slow) var(--ease-standard) 600ms backwards;
  }
  .briefing__thanks[hidden] { display: none; }

  /* vista previa del correo (TEMPORAL): tarjeta crema sobre velo negro */
  .briefing__mail {
    width: min(100% - 2 * var(--container-pad), calc(640 * 1rem / 16));
    max-height: min(85svh, calc(760 * 1rem / 16));
    padding: var(--space-lg);
    overflow: auto;
    color: var(--color-dark);
    background-color: var(--color-light);
    border: 0;
    border-radius: var(--radius-small);
  }
  .briefing__mail::backdrop { background: color-mix(in srgb, var(--color-dark) 70%, transparent); backdrop-filter: blur(6px); }
  .briefing__mail[open] { animation: briefing-rise var(--dur-slow) var(--ease-standard); }
  .briefing__mail-eyebrow { --eyebrow-fg: color-mix(in srgb, var(--color-dark) 60%, transparent); }
  .briefing__mail-subject {
    margin-top: var(--space-2xs);
    font-size: var(--fs-btn-large);
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    line-height: 1;
    text-transform: uppercase;
  }
  .briefing__mail-body {
    margin: var(--space-md) 0 0;
    padding: var(--space-md);
    font: inherit;
    font-size: var(--fs-small);
    line-height: var(--lh-normal);
    white-space: pre-wrap;
    background-color: color-mix(in srgb, var(--color-dark) 8%, var(--color-light));
    border-radius: var(--radius-small);
  }
  .briefing__mail-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs) var(--space-md); margin-top: var(--space-md); }
  .briefing__mail-open,
  .briefing__mail-copy,
  .briefing__mail-close {
    display: inline-flex;
    align-items: center;
    gap: 0.07em;
    padding: 0.35em 0.7em;
    font: inherit;
    font-size: var(--fs-btn-small);
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    line-height: var(--lh-snug);
    text-transform: uppercase;
    text-decoration: none;
    color: var(--color-dark);
    background: none;
    border: var(--border-width) solid currentColor;
    border-radius: var(--radius-small);
    cursor: pointer;
  }
  .briefing__mail-open { background-color: var(--color-brand); border-color: var(--color-brand); }
  .briefing__mail-open .icon { --icon-size: 0.8em; --icon-stroke: 3; }
  .briefing__mail-close { margin-left: auto; border-color: transparent; }

  /* escritorio: posiciones de Figma (px del bloque de 1728, escalados) */
  @media (width >= 64em) {
    /* v1.3 · escena de 800 (Figma: 940): al empezar, el titular se recoge
       arriba (al 62 %) y tarjetas y botones suben 140. En pantallas bajas la
       escena entera se escala (--stage-k, briefing.js) para caber siempre.
       120vh con el escenario fijo y centrado: los 20vh de más son el
       recorrido quieto; smooth-scroll.js la ancla por el centro (data-snap) */
    .briefing {
      --stage-h: calc(800 * 1rem / 16 * var(--stage-k, 1));
      --pin: max(var(--header-height), (100svh - var(--stage-h)) / 2);
      height: calc(max(120svh, var(--stage-h) + 2 * var(--pin) + 20svh) + var(--space-3xl));   /* + el aire antes del pie */
    }
    .briefing__stage {
      position: sticky;
      top: var(--pin);
      height: var(--stage-h);
      margin-top: var(--pin);
      padding: 0;
      overflow: clip;
      container-type: normal;
    }
    .briefing__scene {
      display: block;
      position: absolute;
      top: 0;
      left: 50%;
      width: calc(100% / var(--stage-k, 1));
      height: calc(800 * 1rem / 16);
      translate: -50% 0;
      scale: var(--stage-k, 1);
      transform-origin: top center;
      container-type: inline-size;
    }
    .briefing__head {
      position: absolute; left: 50%; top: calc(60 * 1rem / 16); translate: calc(-50% - 4px) 0; width: calc(474 * 1rem / 16);
      transform-origin: top center;
      transition: top 0.9s var(--ease-in-out), scale 0.9s var(--ease-in-out);
    }
    /* al empezar, el titular se recoge arriba y deja sitio a las tarjetas */
    .briefing[data-ready]:not([data-step="0"]) .briefing__head { top: calc(28 * 1rem / 16); scale: 0.62; }
    .briefing__start { position: absolute; left: 50%; top: calc(449 * 1rem / 16); translate: calc(-50% - 4px) -50%; margin: 0; }   /* centro donde Figma tiene el de 388 × 98 */
    .briefing[data-ready] .briefing__form { position: absolute; inset: 0; }
    .briefing[data-ready] .briefing__cards { position: absolute; inset: 0; margin: 0; display: block; translate: 0 calc(-140 * 1rem / 16); }   /* 140 más arriba que en Figma */
    .briefing[data-ready] .briefing__card {
      left: calc(100cqi + (var(--qx) - 1728) * 1rem / 16);   /* v1.4: en cola y la que asoma, ancladas al borde derecho */
      top: calc(var(--qy) * 1rem / 16);
      rotate: 0deg;
    }
    /* portada: todas fuera del bloque, a la derecha (Figma V1: x 1735) */
    .briefing[data-ready][data-step="0"] .briefing__card { left: calc(100cqi + 274 * 1rem / 16); }
    .briefing[data-ready] .briefing__card[data-pos="next"] {
      left: calc(100cqi + (var(--px) - 1728) * 1rem / 16);
      top: calc(var(--py) * 1rem / 16);
      rotate: calc(var(--pr) * 1deg);
    }
    .briefing[data-ready] .briefing__card:is([data-pos="current"], [data-pos="stack"]) {
      left: calc(50cqi + (var(--cx) - 864) * 1rem / 16);   /* la actual y el montón, al centro */
      top: calc(var(--cy) * 1rem / 16);
      rotate: calc(var(--r) * 1deg);
    }
    /* la tarjeta que asoma es el botón SIGUIENTE (310 × 524 a la derecha) */
    .briefing[data-ready] .briefing__next {
      position: absolute;
      right: 0;
      top: calc(191 * 1rem / 16);          /* Figma 331 − 140 */
      z-index: calc(var(--z-base) + 70);   /* sobre todas las tarjetas (--z de 1 a 60) */
      display: block;
      width: calc(310 * 1rem / 16);
      height: calc(524 * 1rem / 16);
      padding: 0;
      background: none;
      border: 0;
      cursor: pointer;
    }
    .briefing[data-ready]:is([data-step="0"], [data-step="6"], [data-step="done"]) .briefing__next { display: none; }
    /* al pasar por SIGUIENTE (activo), la tarjeta que asoma se adelanta un poco */
    .briefing__form:has(.briefing__next:not(:disabled):is(:hover, :focus-visible)) .briefing__card[data-pos="next"] { translate: calc(-50% - 1.5rem) -50%; }
    /* la etiqueta, siempre visible sobre la tarjeta que asoma (Figma la
       muestra al pasar el ratón: aquí se ve siempre, y al pasar sube y gira) */
    .briefing__next-tag {
      position: absolute;
      left: calc(59 * 1rem / 16);
      top: calc(290 * 1rem / 16);          /* en el hueco libre de la tarjeta que asoma (Figma: 218, sobre el texto) */
      rotate: 2deg;
    }
    .briefing__next:not(:disabled):is(:hover, :focus-visible) .briefing__next-tag { translate: 2px -11px; rotate: 5deg; }
    .briefing[data-ready] .briefing__submit { position: absolute; left: 50%; top: calc(720 * 1rem / 16); translate: -50% 0; margin: 0; }   /* Figma 860 − 140 */
    /* ANTERIOR: a la izquierda de la tarjeta actual (borde izquierdo de la
       tarjeta en Figma: 864 − 266 = 598; 24 px de aire) */
    .briefing[data-ready] .briefing__prev {
      position: absolute;
      right: calc(50cqi + 290 * 1rem / 16);
      top: calc(450 * 1rem / 16);
      z-index: calc(var(--z-base) + 70);
      translate: 0 -50%;
    }
    .briefing[data-ready] .briefing__thanks { position: absolute; left: 50%; top: calc(710 * 1rem / 16); translate: -50% 0; width: 100%; margin: 0; }

    /* briefing-cta (sin formulario): bloque normal, sin escena fija ni escalada */
    .briefing.briefing--cta { height: auto; }
    .briefing--cta .briefing__stage { position: relative; top: auto; height: auto; margin-top: 0; padding: calc(var(--space-2xl) + var(--space-3xl)) var(--container-pad) var(--space-2xl);   /* arriba el mismo aire que abajo (stage + .briefing) */ overflow: visible; container-type: inline-size; }
    .briefing--cta .briefing__scene { display: contents; }
    .briefing--cta .briefing__head { position: static; translate: none; width: min(100%, calc(474 * 1rem / 16 + 50 * var(--fluid-c))); }
    .briefing--cta .briefing__start { position: relative; top: auto; left: auto; translate: none; margin: var(--space-xl) auto 0; }
  }

  /* briefing-cta: EMPIEZA YA es un enlace */
  .briefing--cta .briefing__start { width: fit-content; text-decoration: none; }
  .briefing--cta .briefing__start:is(:hover, :focus-visible, :active, :visited) { text-decoration: none; }

  /* móvil: las tarjetas se suceden en el centro y, como en escritorio,
     entran tapando EMPIEZA YA (botón y tarjetas en la misma celda);
     SIGUIENTE, debajo */
  @media (width < 64em) {
    .briefing[data-ready] .briefing__stage { display: grid; grid-template-columns: minmax(0, 1fr); }
    .briefing[data-ready] .briefing__head { grid-area: 1 / 1; }
    /* sin EMPIEZA YA: la 1.ª tarjeta entra sola cuando el bloque cruza la
       mitad de la pantalla (briefing.js). El montón ya ocupa su sitio, así
       que el bloque no cambia de alto */
    .briefing[data-ready] .briefing__start { display: none; }
    .briefing[data-ready] .briefing__form { grid-area: 2 / 1; }
    .briefing[data-ready]:not([data-step="6"]) .briefing__submit { position: absolute; }
    /* todas en la misma celda: el montón mide lo que la tarjeta más alta */
    .briefing[data-ready] .briefing__cards { display: grid; margin-top: var(--space-xl); padding-block: var(--space-sm); overflow-x: clip; }
    .briefing[data-ready] .briefing__card {
      grid-area: 1 / 1;
      position: relative;
      width: min(100% - 2 * var(--space-xs), 560 * 1rem / 16);   /* v1.4 · tablet: ancho de tarjeta, no de pantalla */
      min-height: 0;
      margin-inline: auto;
      translate: 130% 0;
      rotate: 0deg;
      transition: translate 1s var(--ease-in-out), rotate 1s var(--ease-in-out);
    }
    .briefing[data-ready] .briefing__card:is([data-pos="current"], [data-pos="stack"]) { translate: 0 0; rotate: calc(var(--r) * 1deg); }
    /* el hueco de los botones está desde el principio: el bloque no cambia
       de alto cuando entra la primera tarjeta */
    .briefing[data-ready] .briefing__nav { display: flex; justify-content: center; align-items: center; gap: var(--space-sm); min-height: 2.2rem; margin-top: var(--space-md); }
    .briefing[data-ready][data-step="done"] .briefing__nav { display: none; }
    .briefing[data-ready]:not([data-step="0"], [data-step="6"], [data-step="done"]) .briefing__next {
      display: block;
      margin: 0;
      padding: 0;
      background: none;
      border: 0;
      cursor: pointer;
    }
    .briefing__next-tag { rotate: -2deg; }
    /* móvil: sobre el negro → crema apagada */
    .briefing__next:disabled .briefing__next-tag {
      rotate: 0deg;
      --tag-bg: color-mix(in srgb, var(--color-light) 18%, transparent);
      --tag-fg: color-mix(in srgb, var(--color-light) 60%, transparent);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .briefing[data-in] :is(.briefing__eyebrow, .briefing__title, .briefing__dot, .briefing__start, .briefing__thanks),
    .briefing__option input:checked + span { animation: none; }
    .briefing[data-ready] .briefing__card,
    .briefing__next-tag,
    .briefing__submit .icon { transition: none; }
  }

}


/* ───── sections/page-hero.css ───── */
/* ==========================================================================
   SECCIÓN: .page-hero                                    v1.0 · 13/10/2026
   Figma:      «servicios-claude» › hero: titular de 180 px (wdth 77) en dos
               filas centradas, con una imagen en línea en cada una
               (219 × 136, radio 8: alto de mayúsculas, alineada a la base).
   Qué hace:   titular de página interior. Las imágenes son los carruseles
               del hero de la Home y se abren de 0 a su ancho al cargar, a la
               vez que la letra ancha. Sin antetítulo.
   Móvil:      tres líneas a todo el ancho («ESPECIALISTAS / Y SERVICIOS /
               360°»), sin imágenes.
   Vista:      components/ril/page-hero.njk
   ========================================================================== */
@layer layout {

  .page-hero { padding-block: calc(40 * 1rem / 16 + 66 * var(--fluid-c)) calc(32 * 1rem / 16 + 74 * var(--fluid-c)); }
  .page-hero__inner { container-type: inline-size; }
  .page-hero__title {
    /* móvil: «ESPECIALISTAS» (5,9 em) llena el ancho; escritorio: la fila
       más larga («ESPECIALISTAS ▢ Y», 8,5 em) cabe en el contenedor */
    font-size: min(var(--fs-display), 100cqi / 5.95);
    font-stretch: var(--ril-stretch-condensed);
    line-height: var(--lh-display);
    --u-expanded-delay: var(--dur-base);
  }
  .page-hero__line { display: inline; }
  .page-hero__img { display: none; }

  @media (width >= 48em) {
    .page-hero__title { font-size: min(var(--fs-display), 100cqi / 9); text-align: center; }
    .page-hero__line { display: flex; justify-content: center; align-items: baseline; white-space: nowrap; }   /* sin gap: separaría la letra ancha del resto de la palabra */
    .page-hero__img {
      display: flex;                       /* sin línea de texto dentro: su base es su borde inferior */
      flex: none;
      overflow: clip;
      width: var(--carousel-w);
      --carousel-w: calc(1cap * 219 / 136);
      --carousel-ratio: 219 / 136;
      margin-inline: 0.16em;
      line-height: 0;
      animation: page-hero-img-in var(--u-expanded-dur, 1.8s) var(--ease-in-out) var(--u-expanded-delay, 0.25s) backwards;
    }
    .page-hero__img .carousel-fade { flex: none; }
  }
  @keyframes page-hero-img-in { from { width: 0; } }
  @media (prefers-reduced-motion: reduce) { .page-hero__img { animation: none; } }

}


/* ───── sections/media-text.css ───── */
/* ==========================================================================
   SECCIÓN: .media-text                                   v1.0 · 13/10/2026
   Figma:      «servicios-claude» › «split-media · intro + foto» (con --bleed)
               y «… una agencia que piensa antes de crear».
   Composición escritorio (retícula de 12 con 20 px de hueco):
               · --bleed: foto en 1-7 a sangre por la izquierda (995 × 612,
                 solo esquinas derechas redondeadas) y texto (22) en 8-12,
                 arriba; debajo de la foto, el claim (74) en 1-6 a 29 px.
               · normal: foto en 1-5 (675 × 411) centrada en vertical con el
                 texto; titular (74) y texto (22) en 7-12.
   Móvil:      foto a todo el ancho; titular; texto (12/18) a 20 px.
   Vista:      components/ril/media-text.njk
   ========================================================================== */
@layer layout {

  .media-text { padding-block: calc(16 * 1rem / 16 + 68 * var(--fluid-c)) calc(56 * 1rem / 16 + 30 * var(--fluid-c)); }
  .media-text--bleed { padding-block: 0 calc(40 * 1rem / 16 + 20 * var(--fluid-c)); }
  .media-text__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: calc(20 * 1rem / 16); }
  .media-text__figure { --media-ratio: 374 / 240; }
  .media-text:not(.media-text--bleed) .media-text__figure { order: 1; }
  .media-text__body { display: grid; gap: calc(20 * 1rem / 16); }
  .media-text__title, .media-text__claim { font-size: var(--fs-h1); line-height: var(--lh-heading); }
  .media-text__title { max-width: 9.4em; }   /* Figma: 696 px a 74 → tres líneas */
  .media-text__claim { font-size: calc(32 * 1rem / 16 + 42 * var(--fluid-c)); margin-top: calc(20 * 1rem / 16); }
  .media-text__text { display: grid; gap: 0.6em; font-size: var(--fs-body); line-height: var(--lh-normal); }

  @media (width >= 48em) {
    .media-text__grid { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: calc(20 * 1rem / 16); row-gap: 0; align-items: center; }
    .media-text__figure { grid-column: 1 / 6; --media-ratio: 675 / 411; }
    .media-text:not(.media-text--bleed) .media-text__figure { order: 0; }
    .media-text__body { grid-column: 7 / 13; gap: calc(44 * 1rem / 16); margin-left: calc(11 * 1rem / 16); }
    .media-text__text { font-size: var(--fs-lead); line-height: 1.5; gap: 0.55em; font-weight: var(--fw-medium); }

    /* intro: foto a sangre (7 columnas) y texto arriba, a la derecha */
    .media-text--bleed .media-text__grid { align-items: start; }
    .media-text--bleed .media-text__figure {
      grid-column: 1 / 8;
      margin-left: calc(-1 * var(--container-pad) - (100vw - min(100vw, var(--container-max))) / 2);
      --media-ratio: 995 / 612;
      --media-radius: 0 var(--radius-small) var(--radius-small) 0;
    }
    .media-text--bleed .media-text__body { grid-column: 8 / 13; margin: calc(9 * 1rem / 16) 0 0; }
    .media-text--bleed .media-text__text { font-weight: var(--fw-regular); max-width: 27em; }
    .media-text__claim { grid-column: 1 / 7; margin-top: calc(29 * 1rem / 16); font-size: var(--fs-h1); line-height: 0.95; }
  }

}


/* ───── sections/service-list.css ───── */
/* ==========================================================================
   SECCIÓN: .service-list                                 v1.1 · 13/10/2026
   Figma:      «servicios-claude» › «services» (escritorio) y «servicio movil
               estilo correcto» (móvil).
   Composición escritorio (retícula de 12, 20 px de hueco):
               índice de anclas arriba (etiquetas de 40 px, 12 entre ellas);
               a 98 px, cada servicio: titular (74) y texto (22) en 1-4,
               imagen 533 × 383 en 6-9, lista numerada (32; números de 20)
               y SABER MÁS en 10-12, abajo. 140 px entre servicios.
   Composición móvil: titular (60) · texto (20) · lista (28) · imagen
               (374 × 271, radio 10) · SABER MÁS, todo en una columna.
   Índice:     al final del bloque y fijo abajo de la pantalla mientras dura (v1.1); la etiqueta
               del servicio que cruza la mitad de la pantalla va en amarillo
               (aria-current, service-list.js). En móvil, fila con scroll.
   Fondo:      soles amarillos (__glow) dentro del bloque que se desplazan
               con el scroll (--p de 0 a 1, service-list.js): marcan dónde
               empieza y acaba. Sin JS o con movimiento reducido, quietos.
   Vista:      components/ril/service-list.njk · JS: modules/service-list.js
   ========================================================================== */
@layer layout {

  .service-list {
    --p: 0.5;
    position: relative;
    isolation: isolate;
    overflow: clip;
    padding-block: calc(40 * 1rem / 16 + 40 * var(--fluid-c)) calc(64 * 1rem / 16 + 16 * var(--fluid-c));
  }

  /* fondo: tres soles que derivan con el scroll (degradados, sin desenfoque) */
  .service-list__glow { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
  .service-list__glow b {
    position: absolute;
    border-radius: 50%;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--color-primary) 70%, transparent), color-mix(in srgb, var(--color-primary) 22%, transparent) 55%, transparent);
    will-change: translate;
  }
  .service-list__glow b:nth-child(1) { left: -38vw; top: 4%; width: 70vw; height: 60%; translate: calc(var(--p) * 10vw) calc(var(--p) * 30%); }
  .service-list__glow b:nth-child(2) { right: -34vw; top: -12%; width: 64vw; height: 45%; translate: calc(var(--p) * -8vw) calc(var(--p) * 60%); }
  .service-list__glow b:nth-child(3) { right: -30vw; bottom: -14%; width: 80vw; height: 48%; translate: calc((1 - var(--p)) * 6vw) calc((1 - var(--p)) * 30%); opacity: 0.8; }

  /* índice */
  .service-list__index {
    position: sticky;
    bottom: var(--space-md);
    z-index: calc(var(--z-base) + 2);
    margin-inline: calc(-1 * var(--container-pad));
    margin-top: calc(48 * 1rem / 16 + 32 * var(--fluid-c));
  }
  .service-list__tags {
    display: flex;
    gap: calc(12 * 1rem / 16);
    margin: 0;
    padding: 0 var(--container-pad);
    list-style: none;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .service-list__tags::-webkit-scrollbar { display: none; }
  .service-list__tag {
    display: block;
    padding: calc(8 * 1rem / 16) calc(14 * 1rem / 16);
    font-size: var(--fs-label);
    font-stretch: var(--ril-stretch-cta);
    line-height: var(--lh-label);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    white-space: nowrap;
    text-decoration: none;
    color: var(--color-light);
    background-color: var(--color-dark);
    border-radius: var(--radius-xs);
    transition: background-color var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard);
  }
  .service-list__tag span { margin-right: 0.35em; }
  .service-list__tag:is(:hover, :focus-visible),
  .service-list__tag[aria-current="true"] { color: var(--color-dark); background-color: var(--color-primary); }

  /* servicio (móvil: una columna) */
  .service-list__item {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    scroll-margin-top: calc(var(--header-height) + var(--space-lg));   /* el ancla, bajo la cabecera */
  }
  .service-list__item + .service-list__item { margin-top: calc(72 * 1rem / 16 + 68 * var(--fluid-c)); }
  .service-list__title { font-size: var(--fs-title); line-height: var(--lh-heading); }
  .service-list__title .u-br-desktop { display: none; }
  .service-list__text { display: grid; gap: 0.5em; margin-top: calc(12 * 1rem / 16); max-width: 24.5em; font-size: var(--fs-lead-lg); line-height: 1.5; }
  .service-list__list {
    counter-reset: svc;
    margin: calc(38 * 1rem / 16) 0 0;
    padding: 0;
    list-style: none;
    font-size: var(--fs-list);
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    line-height: 1.1;
    text-transform: uppercase;
  }
  .service-list__list li {
    counter-increment: svc;
    display: grid;
    grid-template-columns: calc(36 * 1rem / 16 + 3 * var(--fluid-c)) minmax(0, 1fr);
    align-items: baseline;
  }
  .service-list__list li::before {
    content: counter(svc, decimal-leading-zero) ".";
    font-size: var(--fs-label);
    font-weight: var(--fw-regular);
    font-stretch: var(--ril-stretch-cta);
    letter-spacing: var(--ls-wide);
  }
  .service-list__figure { margin-top: calc(26 * 1rem / 16); --media-ratio: 374 / 271; --media-radius: calc(10 * 1rem / 16); }
  .service-list__more { justify-self: start; margin-top: calc(24 * 1rem / 16); }

  @media (width >= 48em) {
    .service-list__index { margin-inline: 0; }
    .service-list__tags { padding: 0; flex-wrap: wrap; justify-content: center; overflow: visible; }
    .service-list__item {
      grid-template-columns: repeat(12, minmax(0, 1fr));
      grid-template-rows: auto 1fr;
      column-gap: calc(20 * 1rem / 16);
      align-items: start;
    }
    .service-list__title .u-br-desktop { display: inline; }
    .service-list__title { grid-column: 1 / 5; grid-row: 1; }
    .service-list__text { grid-column: 1 / 5; grid-row: 2; margin-top: calc(56 * 1rem / 16); }
    .service-list__figure { grid-column: 6 / 10; grid-row: 1 / 3; margin-top: 0; --media-ratio: 533 / 383; --media-radius: var(--radius-small); }
    .service-list__list { grid-column: 10 / 13; grid-row: 1; margin: 0 0 0 calc(7 * 1rem / 16); }
    .service-list__more { grid-column: 10 / 13; grid-row: 2; align-self: end; margin: var(--space-md) 0 0 calc(7 * 1rem / 16); }
  }

}


/* ───── sections/steps.css ───── */
/* ==========================================================================
   SECCIÓN: .steps                                        v1.1 · 13/10/2026
   Figma:      «servicios-claude» › «method · así lo hacemos» y «así lo
               hacemos animation example».
   Composición escritorio: titular (74) y, a 82 px, cuatro pasos en
               columnas (25 px de hueco): filete de 2 px, número (74),
               nombre (32) y texto (18).
   Composición móvil: pasos uno debajo de otro; número y nombre en la
               misma línea (28).
   Animación:  steps.js pone data-state en cada paso: «wait» (tapado) →
               «on» (se destapa de izquierda a derecha como una máscara, con
               filete, número y nombre en amarillo; el texto, en negro) → «done» (pasa a negro). El siguiente empieza cuando
               el anterior se apaga. Sin JS o con movimiento reducido: todo
               visible en negro.
   Vista:      components/ril/steps.njk · JS: modules/steps.js
   ========================================================================== */
@layer layout {

  .steps { padding-block: calc(56 * 1rem / 16 + 44 * var(--fluid-c)) calc(56 * 1rem / 16 + 32 * var(--fluid-c)); }
  .steps__title { font-size: var(--fs-h1); line-height: var(--lh-heading); }
  .steps__list {
    display: grid;
    gap: calc(28 * 1rem / 16);
    margin: calc(28 * 1rem / 16 + 54 * var(--fluid-c)) 0 0;
    padding: 0;
    list-style: none;
  }
  .steps__item {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: 0.3em;
    align-items: baseline;
    padding-top: calc(10 * 1rem / 16);
    border-top: 2px solid currentColor;
    font-size: var(--fs-list);
    clip-path: inset(0 -1% 0 0);
    transition: border-color 0.6s var(--ease-in-out), clip-path 0.8s var(--ease-in-out);
  }
  .steps__num, .steps__name {
    font-weight: var(--ril-fw-black);
    font-stretch: var(--ril-stretch-condensed);
    line-height: 1.1;
    text-transform: uppercase;
    transition: color 0.6s var(--ease-in-out);
  }
  .steps__name { font-size: inherit; }
  .steps__text { grid-column: 1 / -1; margin-top: calc(8 * 1rem / 16); font-size: var(--fs-body); line-height: 1.5; max-width: 22em; }

  /* animación (steps.js) */
  .steps__item[data-state="wait"] { clip-path: inset(0 101% 0 0); transition: none; }
  /* en amarillo, el filete, el número y el nombre; el texto, siempre en negro (v1.1) */
  .steps__item[data-state="on"] { border-color: var(--color-primary); }
  .steps__item[data-state="on"] :is(.steps__num, .steps__name) { color: var(--color-primary); }

  @media (width >= 48em) {
    .steps__list { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: calc(25 * 1rem / 16); }
    .steps__item { display: block; padding-top: calc(18 * 1rem / 16); }
    .steps__num { display: block; font-size: var(--fs-h1); line-height: 0.96; }
    .steps__name { margin-top: calc(18 * 1rem / 16); }
    .steps__text { margin-top: calc(18 * 1rem / 16); }
  }

}



/* ───── pages/_index.css ───── */
/* ==========================================================================
   pages/  —  orden y excepciones mínimas de una página · @layer layout
   Idealmente vacío. Si algo de aquí se repite en otra página, sube a
   sections/. Su tamaño mide la salud del sistema.
   ========================================================================== */


/* ───── pages/home.css ───── */
/* Home · excepciones de página. Vacío a propósito. */
@layer layout {
}



/* ───── lenis.css (vendor, v1.3.11) ───── */
html.lenis,html.lenis body{height:auto}.lenis:not(.lenis-autoToggle).lenis-stopped{overflow:clip}.lenis [data-lenis-prevent],.lenis [data-lenis-prevent-wheel],.lenis [data-lenis-prevent-touch]{overscroll-behavior:contain}.lenis.lenis-smooth iframe{pointer-events:none}.lenis.lenis-autoToggle{transition-property:overflow;transition-duration:1ms;transition-behavior:allow-discrete}

/* Añadido a mano en ril (no viene de ril-web-temp; si se regenera este CSS, llevarlo también allí):
   enlaces de la lista de servicios de /conocenos/servicios-pruebas2. Sin subrayado; al pasar,
   una línea de 2px se dibuja de izquierda a derecha. El <span> interior hace que la línea siga
   al texto (el <a> es un elemento de grid y ocuparía toda la columna). */
@layer layout {
  /* Interlineado mayor (antes 1.1) para que el subrayado no toque la línea de abajo: la caja del texto mide ~1.4em */
  .service-list__list { line-height: 1.3; }
  .service-list__link { justify-self: start; color: inherit; text-decoration: none; }
  .service-list__link-text {
    background: linear-gradient(currentColor, currentColor) no-repeat 0 100% / 0 2px;
    transition: background-size var(--dur-base) var(--ease-standard);
  }
  .service-list__link:hover .service-list__link-text,
  .service-list__link:focus-visible .service-list__link-text { background-size: 100% 2px; }
}

/* añadido a mano: con vídeo + imagen hover, la imagen hover pasa a ser el único <img> de la tarjeta;
   sin esto se ampliaría al pasar el ratón (el zoom solo es para tarjetas con una única imagen) */
.project-card__img--hover:only-of-type { transform: none; }

/* añadido a mano: enlaces dentro del párrafo de «Agencia IA de marketing digital» (split-media__lead):
   subrayado fino que se engrosa al pasar el ratón */
.split-media__lead a { color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.18em; transition: text-decoration-thickness 0.2s; }
.split-media__lead a:is(:hover, :focus-visible) { text-decoration-thickness: 2px; }
.split-media__lead strong { font-weight: var(--fw-medium, 500); }

/* añadido a mano: portada de Opal en Vimeo (iframe). Se amplía un poco para recortar las franjas negras y no recibe el ratón */
.project-card__iframe { border: 0; pointer-events: none; transform: scale(1.14); transform-origin: center; }
.project-card:is(:hover, :focus-within) .project-card__iframe { transform: scale(1.14); }

/* añadido a mano: bloque «10 años impulsando marcas» (componente impulsando-marcas).
   Tres piezas en una fila, en escritorio y en móvil: «10 AÑOS» a la izquierda (en la mitad de arriba), el vídeo vertical en el
   centro y «IMPULSANDO MARCAS» a la derecha (en la mitad de abajo). El vídeo gira de 0° a 10° con el scroll (animation-timeline). */
.impulsando-marcas { min-height: 100svh; display: grid; align-content: center; padding-block: var(--space-xl); }
.impulsando-marcas__grid {
  --video-w: clamp(9rem, 36vw, calc(78svh * 635 / 875));
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--video-w) minmax(0, 1fr);
  grid-template-rows: 1fr 1fr;
  column-gap: var(--space-md);
  align-items: center;
}
.impulsando-marcas__side {
  margin: 0;
  font-size: clamp(1.25rem, 5vw, var(--fs-h1));
  font-weight: var(--ril-fw-black);
  font-stretch: var(--ril-stretch-condensed);
  line-height: var(--lh-heading);
  text-transform: uppercase;
}
.impulsando-marcas__side--left  { grid-column: 1; grid-row: 1; align-self: end;   justify-self: end;   text-align: right; }
.impulsando-marcas__side--right { grid-column: 3; grid-row: 2; align-self: start; justify-self: start; text-align: left; }
.impulsando-marcas__num { display: inline; margin-right: 0.12em; }
.impulsando-marcas__figure { grid-column: 2; grid-row: 1 / 3; width: var(--video-w); margin: 0; --media-ratio: 635 / 875; }

/* móvil: una sola columna en este orden: título («10 años»), vídeo y texto («impulsando marcas»), todo centrado */
@media (width < 48em) {
  /* el alto lo marca el contenido. Arriba el bloque anterior (equipo) ya deja ~110-140 px vacíos bajo sus últimos avatares, así que no se suma relleno;
     abajo se pone ese mismo aire (≈ 29vw, entre 6 y 9,5 rem) para que el espacio hasta el título y hasta el bloque negro sea igual */
  .impulsando-marcas { min-height: 0; padding-top: 0; padding-bottom: clamp(6rem, 29vw, 9.5rem); }
  .impulsando-marcas__grid {
    --video-w: clamp(11rem, 62vw, 18rem);
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto;
    row-gap: var(--space-lg);
    justify-items: center;
  }
  .impulsando-marcas__side { grid-column: 1; justify-self: center; text-align: center; }
  .impulsando-marcas__side--left  { grid-row: 1; font-size: var(--fs-h1); }
  .impulsando-marcas__figure      { grid-column: 1; grid-row: 2; justify-self: center; }
  .impulsando-marcas__side--right { grid-row: 3; font-size: var(--fs-h2); }
}

@keyframes impulsando-marcas-giro { from { rotate: 0deg; } to { rotate: 10deg; } }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .impulsando-marcas__figure {
      animation: impulsando-marcas-giro linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
    }
  }
}

/* ───── añadido a mano: texto «Inteligencia artificial a medida» sobre el vídeo del hero ─────
   Va dentro de .hero__frame (la caja del vídeo, fija en escritorio). No toca el crecimiento del vídeo (--hero-p);
   solo lo mantiene una pantalla más (--hero-hold). Escritorio: aparece de abajo arriba y sus letras .u-expanded se
   ensanchan al hacer scroll durante esa pausa (animation-timeline sobre la escena, en CSS puro). Móvil: aparece cuando el
   vídeo ha crecido (--hero-p). Sin soporte de animation-timeline o con «reducir movimiento»: texto estático, letras en su estado final. */
.hero__ia {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: var(--space-md);
  padding-inline: var(--container-pad);
  text-align: center;
  --color-heading: var(--color-light);
  color: var(--color-light);
}
.hero__ia::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top, color-mix(in srgb, var(--color-dark) 62%, transparent), color-mix(in srgb, var(--color-dark) 32%, transparent));
}
/* el titular usa el mismo tamaño que «Proyectos que han nacido para brillar» (.showcase__title: --fs-h1, --lh-heading, centrado); el color crema viene de --color-heading de .hero__ia */
.hero__ia-title { max-width: 12em; margin-inline: auto; font-size: var(--fs-h1); line-height: var(--lh-heading); }
.hero__ia-text { margin: 0; max-width: 30em; font-size: var(--fs-body-lg); }
@media (width < 48em) {
  .hero__ia { opacity: clamp(0, calc((var(--hero-p) - 0.85) * 6.67), 1); padding-block: var(--space-xl); }   /* aire arriba y abajo del texto */
  /* la caja del vídeo termina más alta que el 4:3 para que quepan el titular (cuatro líneas) y el párrafo con ese aire; hero-video.js mide la caja, no se toca */
  .hero__scene { --hero-h1: max(calc(100cqi * 3 / 4), 26rem); }
}
@keyframes hero-ia-entra { from { opacity: 0; translate: 0 2.5rem; } to { opacity: 1; translate: 0 0; } }
@keyframes hero-ia-letra { from { font-stretch: var(--ril-stretch-expanded-from); } to { font-stretch: var(--ril-stretch-expanded); } }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) and (width >= 48em) {
    .hero__scene { view-timeline: --hero-scene block; }
    .hero__ia {
      animation: hero-ia-entra linear both;
      animation-timeline: --hero-scene;
      animation-range: cover 100svh cover calc(100svh + 0.35 * var(--hero-hold));
    }
    .hero__ia .u-expanded {
      font-stretch: var(--ril-stretch-expanded-from);
      animation: hero-ia-letra linear both;
      animation-timeline: --hero-scene;
      animation-range: cover calc(100svh + 0.4 * var(--hero-hold)) cover calc(100svh + 0.65 * var(--hero-hold));
    }
  }
}

/* añadido a mano: cada palabra del menú de servicios (home) es clicable en toda la fila, de borde a borde de la página,
   y pasar por al lado activa su hover (el ::after del enlace cuenta como el propio enlace). Sin ::after de más abajo
   que cubra las imágenes: estas van después en el DOM y quedan por encima. */
.services { overflow-x: clip; }                          /* el recorte horizontal pasa de la nav a la sección (ancho completo) */
.services .ril-menu-servicios { overflow-x: visible; }
.menu-servicios__word::after {
  content: "";
  position: absolute;
  inset-block: calc(var(--ms-gap) / var(--ms-word) * -0.5em);   /* hasta la mitad del hueco entre filas */
  inset-inline: -100vw;
}
@media (width < 48em) {
  .menu-servicios__word::after { inset-inline: calc(-1 * var(--container-pad)); }   /* móvil: sin salirse de la pantalla */
}
