/* ==========================================================================
   NOSOTROS · hoja propia de /nosotros/

   Sólo la enlaza esa página, después de sections.css y en lugar de
   mockups.css. No toca un solo selector de las otras cinco hojas.

   ESTA HOJA ES UN CALCO MEDIDO de brumalab.agency/nosotros. Cada número con
   un comentario "Bruma:" salió de su CSS de producción o de medir su render
   con Playwright (claude/verificacion/nosotros/v-escenario.mjs), no de mirar
   una captura. Si alguna vez hay que cambiar uno, vale la pena volver a medir
   antes: son las medidas las que hacen que el calco sea un calco.

   LO QUE REUSA, y por eso no está acá: .container .eyebrow .btn .icon
   .ph-badge .visually-hidden .nav .footer, los tokens de tokens.css y todo el
   sistema de reveals de base.css.

   ⚠ LA PÁGINA NO LLEVA NINGUNA COSTURA .seam. En Bruma el fondo es claro de
   punta a punta y los dos bloques oscuros son PANELES EMBUTIDOS con radio
   grande. Ese es el esqueleto, y meter costuras lo rompe.

   ÍNDICE
     00 · Cortes, movimiento y reglas comunes
     01 · section_about-header — "Nuestra / Visión"
     02 · section_about        — "Nuestra Esencia"
     03 · section_team         — el escenario de 150svh
     04 · section_members      — "Fundamentos"
     05 · section_approach     — "Método"
     06 · section_awards       — "Acreditaciones"
     07 · Degradación: sin JS, movimiento reducido, táctil
   ========================================================================== */


/* ==========================================================================
   00 · CORTES, MOVIMIENTO Y REGLAS COMUNES

   Los cortes son los de Bruma —991 / 767 / 479— y no los de la casa, porque
   son los que gobiernan su geometría. Mezclarlos con otros movería los
   bloques respecto del original.

   EL REVELADO. Bruma entra con opacity 0→1 y translateY 8px→0; obs-rise de la
   casa usa 22px. Se calca el de Bruma, que es más contenido y es lo que hace
   que la página se sienta igual de quieta. Se cambia sólo el animation-name:
   la duración, la curva y la escalera de --reveal-delay siguen siendo las de
   base.css, así que el ritmo con el resto del sitio no se rompe.
   ========================================================================== */
@keyframes nos-rise {
  from { opacity: 0; transform: translate3d(0, 8px, 0); }   /* Bruma: 8px */
  to   { opacity: 1; transform: none; }
}
.ncab     [data-reveal-item].is-visible,
.nesencia [data-reveal-item].is-visible,
.nestudio [data-reveal-item].is-visible,
.nfund    [data-reveal-item].is-visible,
.nmet     [data-reveal-item].is-visible,
.nacred   [data-reveal-item].is-visible { animation-name: nos-rise; }

/* La etiqueta técnica de Bruma es Roboto Mono en versalitas. Obscura no tiene
   monoespaciada, y su registro equivalente es la etiqueta de la casa: Plus
   Jakarta con tracking de rótulo. tabular-nums es lo que mantiene los años de
   la tabla alineados en columna sin usar una mono. */
/* EL AIRE ENTRE BLOQUES. Bruma no usa padding simetrico: su .padding-section-medium
   es un espaciador de padding-TOP y nada mas, de 6rem (96px) en escritorio. La
   casa usa --section-pad, que son 152px A CADA LADO — o sea el triple. Medido
   bloque por bloque contra el render de Bruma, esa diferencia sola explicaba
   718px de mas en la pagina (v-ritmo.mjs). Se calca el de Bruma.
   El unico que ademas lleva aire abajo es el ultimo, porque despues viene el
   pie de la casa y no el de Bruma. */
:root { --nos-aire: clamp(3rem, 1rem + 5.5vw, 6rem); }   /* Bruma: 6rem en escritorio */
.nesencia, .nestudio, .nfund, .nmet, .nacred { padding-block: var(--nos-aire) 0; }
.nacred { padding-bottom: var(--nos-aire); }

/* ⚠ LAS DOS SECCIONES OSCURAS LLEVAN EL TEMA PERO NO PINTAN.

   `data-theme` tiene que estar en la <section> —hija directa de <main>— porque
   es de ahí de donde main.js saca las zonas para voltear el nav; anidado en el
   panel no hay zonas, la variable cae a su default 'dark' y el nav dibuja
   CREMA SOBRE CREMA arriba de todo. Medido: era invisible.

   Pero base.css § 177 dice `[data-theme] { background: var(--bg) }`, o sea que
   TODA sección temada pinta. Con el tema oscuro en la sección, el negro se
   comía el filo de crema que rodea al panel embutido y el bloque dejaba de ser
   un panel para ser una banda a sangre — que es exactamente lo que este calco
   NO es. El negro lo pone el panel; la sección sólo declara qué hay debajo. */
.nesencia, .nacred { background: transparent; }

/* ⚠ LAS DOS QUE VAN DETRAS DE UNA COSTURA NO LLEVAN AIRE ARRIBA. La costura
   mide 72px (56 en movil) y ya ES el aire: sumarle los 96 del bloque abria un
   hueco de 168px justo donde el ornamento pide que la vista siga. Se hace por
   clase y no por :has() para que no dependa del orden del markup. */
.nestudio, .nacred { padding-top: 0; }

.ncab__dato-label,
.nacred__c,
.npilar__label {
  font-family: var(--font-ui);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}


/* ==========================================================================
   01 · SECTION_ABOUT-HEADER — "Nuestra / Visión"

   Bruma: .section_about-header { min-height:100vh; flex column; center }
   Acá svh y no vh: en móvil el 100vh cuenta la barra del navegador que
   después se retrae, y la franja técnica —que va anclada abajo— se iría fuera
   de pantalla. A partir de tablet los dos valores son el mismo número.
   ========================================================================== */
.ncab {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: stretch;
  min-height: 100svh;
}

/* Bruma: .about-header_component { flex; center; z-index:5; relative } */
.ncab__escena {
  position: relative;
  z-index: 5;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Bruma: .about-header_headings { flex; space-between; center; w:100%; z:10 }
   Bruma parte el titular en dos elementos (<h1>Our</h1> + <h2>Vision</h2>).
   Acá es UN solo <h1> que hace de contenedor flex: misma geometría, y el
   título de la página queda siendo la frase entera y no la mitad. */
.ncab__titulo {
  position: relative;
  z-index: 10;
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  margin: 0;
  gap: var(--sp-4);
}

/* Bruma: h1 = 4.5rem / 95% / -.02em, y 3rem en el corte de 479.
   Los dos extremos del clamp son exactamente esos. */
.ncab__palabra {
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: clamp(3rem, 1.4rem + 3.6vw, 4.5rem);
  line-height: .95;
  letter-spacing: var(--track-tight);
  color: var(--ink);
}
/* La firma tipográfica de la casa: exactamente UN <em> en serif itálica. El
   split de Bruma cae justo acá y por eso no hubo que forzar nada. */
.ncab__palabra--em {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.01em;
}

/* Bruma: .about-header_imgs-wrapper { absolute; flex column; center; gap 2rem }
   En Bruma queda centrado por su posición estática dentro de un flex centrado,
   que es frágil. Acá se centra explícito: mismo resultado medido (chip a 152px
   y ficha a 208px con viewport de 900), sin depender del orden del flujo. */
.ncab__centro {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-8);                    /* Bruma: 2rem */
}

/* Bruma: .about-header_location { flex; gap .25rem } + globo animado de 1.5rem.
   Acá va sin el globo/diafragma: solo el texto del lugar. */
.ncab__lugar {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  margin: 0;
  font-family: var(--font-ui);
  font-size: 1rem;                     /* Bruma: 1rem / 500 */
  font-weight: 600;                    /* ver la nota del peso 500, mas abajo */
  color: var(--ink);
}

/* Bruma: .about-header_imgs { h:60vh; aspect-ratio:1/1.2; radius:2vh; clip }
   overflow: clip y NO hidden. Es lo que deja recortar los fotogramas sin
   crear un contenedor de scroll, que rompería los timelines de más abajo.
   Bruma lo hace igual y no es casualidad. */
/* La caja de afuera existe SOLO para separar el revelado del rebote: en esta
   hoja el revelado se hace cambiando `animation-name`, y una regla de
   `.ncab [data-reveal-item].is-visible` le gana por especificidad a cualquier
   `animation` puesta en la misma ficha. Se descubrió midiendo: la escala salía
   1,0000 clavada y `getAnimations()` devolvía `nos-rise` corriendo sola.
   Bruma también parte en dos por esto mismo. No aporta caja de layout: es un
   flex que se ajusta a su único hijo. */
.ncab__caja { display: flex; }

.ncab__ficha {
  position: relative;
  height: 60svh;
  aspect-ratio: 1 / 1.2;
  border-radius: 2vh;
  overflow: clip;
  background: var(--bg-sunk);
  will-change: transform;
  /* EL REBOTE. Ver la nota de abajo. */
  animation: nos-rebote 1177ms linear infinite both;
}

/* ⚠ ESTO NO ERA UNA COMPRESIÓN POR VELOCIDAD DE SCROLL, Y HASTA LA 22ª SE
   CREYÓ QUE SÍ. En la 21ª se midió la ficha de Bruma a scale 0,95 mientras se
   hacía scroll y se dedujo un `squash` por velocidad; se portó con doce
   renglones de rAF. Estaba mal leído.

   Se volvió a medir separando los dos casos (m-scroll.mjs): con la página
   QUIETA la ficha baja igual a 0,950, y con scroll fuerte baja a 0,950
   también — el mínimo no responde a la velocidad. Lo que hay es un REBOTE
   ligado al corte del moodboard, de período 1177 ms, o sea uno por imagen.
   Es lo que el cliente marcó como «la animación tipo bounce que falta».

   La curva es la medida, no una inventada (m-bounce2.mjs, muestreo a 16 ms):

     · dura 334 ms en total y está CENTRADA EN EL CORTE — el cambio de imagen
       pasa exactamente en el mínimo. Medido: la imagen cambia en el mismo
       cuadro en que la escala toca 0,950.
     · baja de 1 a 0,95 en 167 ms y vuelve en otros 167, simétrica.
     · cada mitad es una potencia de exponente ~2,32 sobre el tiempo; los
       cinco pasos de abajo la reproducen con un error menor a 0,002.

   Va con `linear`: la interpolación entre paradas ES la curva. Con el `ease`
   por defecto se estaría curvando una curva.

   El mínimo cae en 0% y 100% para que coincida con el corte del cuadro 0, que
   empieza en 0% de su propio ciclo de 9416 ms (8 × 1177). Las dos animaciones
   arrancan juntas al cargar, así que quedan en fase; lo verifica
   v-moodboard.mjs. */
@keyframes nos-rebote {
  0%              { transform: scale(.9500); }
  2.84%           { transform: scale(.9700); }
  5.68%           { transform: scale(.9847); }
  8.51%           { transform: scale(.9939); }
  11.35%          { transform: scale(.9988); }
  14.19%, 85.81%  { transform: scale(1); }
  88.65%          { transform: scale(.9988); }
  91.49%          { transform: scale(.9939); }
  94.32%          { transform: scale(.9847); }
  97.16%          { transform: scale(.9700); }
  100%            { transform: scale(.9500); }
}
.ncab__cuadro {
  position: absolute;
  inset: 0;
  opacity: 0;
  /* 8 cuadros x 1177 ms. Ver la nota de abajo. */
  animation: nos-moodboard 9416ms infinite both;
}
.ncab__cuadro picture, .ncab__cuadro img { width: 100%; height: 100%; }
.ncab__cuadro img { object-fit: cover; }

/* ⚠ ES UN CORTE SECO, NO UN FUNDIDO, y la diferencia es todo el efecto.
   Medido cuadro a cuadro sobre el render de Bruma: 1177 ms exactos por imagen
   (media de ocho transiciones, dispersion de ~12 ms), cambiando `display` de
   golpe. Antes aca habia un cruce de 5 s, que se lee como un carrusel y no
   como un tablero que alguien va dando vuelta.

   Se porta con opacity y paradas PEGADAS (14,28 / 14,29 %): el salto dura
   menos de un milisegundo, o sea que es un corte. No se anima `display`
   porque no es animable, y no hace falta un solo renglon de JS.

   ⚠ EL SIGNO DEL RETARDO HACE LO CONTRARIO DE LO QUE PARECE. Un delay negativo
   ADELANTA la animacion, asi que el cuadro con −1177 ya PASO su ventana y no
   vuelve a mostrarse hasta el final del ciclo: con los retardos en orden
   creciente el tablero corria HACIA ATRAS (medido: 7→6→5→4→3→2→1). Para que
   avance, el cuadro k lleva −(N−k)·1177, o sea la lista al reves. El 0 se
   queda en 0 para que el primero en verse sea el unico con fetchpriority
   alto. */
@keyframes nos-moodboard {
  0%,     12.5%  { opacity: 1; }
  12.51%, 100%   { opacity: 0; }
}
.ncab__cuadro[data-cuadro="0"] { animation-delay:     0ms; }
.ncab__cuadro[data-cuadro="1"] { animation-delay: -8239ms; }
.ncab__cuadro[data-cuadro="2"] { animation-delay: -7062ms; }
.ncab__cuadro[data-cuadro="3"] { animation-delay: -5885ms; }
.ncab__cuadro[data-cuadro="4"] { animation-delay: -4708ms; }
.ncab__cuadro[data-cuadro="5"] { animation-delay: -3531ms; }
.ncab__cuadro[data-cuadro="6"] { animation-delay: -2354ms; }
.ncab__cuadro[data-cuadro="7"] { animation-delay: -1177ms; }

/* Bruma: .about-header_infos { absolute; inset:auto 0 3rem }
          .about-header_infos-in { grid 1fr 1fr 1fr; align-items:flex-end } */
.ncab__franja {
  position: absolute;
  inset: auto 0 var(--sp-12);          /* Bruma: 3rem */
}
.ncab__franja-in {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  align-items: end;
  gap: 16px;                           /* Bruma: 16px */
}
.ncab__dato { display: flex; flex-direction: column; gap: var(--sp-1); }
.ncab__dato-label { color: var(--ink-mute); }
.ncab__dato-valor {
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  font-weight: 600;                    /* ver la nota del peso 500, mas abajo */
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
/* La segunda y la tercera se alinean a su borde, como en Bruma. */
.ncab__dato:nth-child(2) { align-items: center; text-align: center; }
.ncab__dato:nth-child(3) { align-items: flex-end; text-align: right; }


/* ==========================================================================
   02 · SECTION_ABOUT — "Nuestra Esencia"

   Bruma: .about_component { min-height:90vh; negro; radius xlarge; clip }
   Panel EMBUTIDO, no banda a sangre. El data-theme="dark" del markup es lo
   que invierte los tokens adentro: ni un literal de color en toda la sección.
   ========================================================================== */
.nesencia__panel {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 90svh;                   /* Bruma: 90vh */
  padding: var(--sp-6);
  border-radius: var(--radius-xl);
  overflow: clip;                      /* clip, no hidden. Ver §01. */
  color: var(--ink);
  /* ⚠ EL FONDO CAMBIÓ EN LA 23ª. Salió la malla de degradé en paleta Obscura
     —el cliente la marcó por colorida— y entró el registro de la caja de
     brumalab.agency/proyectos: oscuro plano, sin color. Bruma usa negro puro;
     acá va `--bg-sunk` (el escalón más hondo del tema oscuro) con una subida
     apenas perceptible hacia `--bg-elev` arriba, para que no sea una plancha
     muerta. Dos tokens, ni un literal de color. */
  background:
    radial-gradient(115% 80% at 50% 0%, var(--bg-elev), transparent 64%),
    var(--bg-sunk);
}

/* LA RETÍCULA DE PUNTOS — calco del pixel.svg de Bruma, dibujado con CSS.

   Su archivo es un SVG de 900×900 con puntos de r=1,7578 cada 36,328, todo el
   grupo al 40% y enmascarado por un degradé radial que apaga hacia el borde;
   lo sirve con `background-size: auto 100%`, o sea UN CUADRADO DEL ALTO DEL
   PANEL, centrado y sin repetir — no una trama que cubre todo el ancho.

   Acá es la misma geometría en proporciones del lado, así que escala con el
   panel en vez de quedar clavada en píxeles. **Y no pesa un byte de red**: el
   SVG de Bruma son 128 KB. Para un fondo de puntos eso es una imagen entera.

   El color sale de `--ink` con color-mix y no de un literal: si el tema se
   invierte, la trama lo sigue. Donde no haya color-mix la declaración entera
   se descarta y quedan el fondo y el rastro, que es una degradación invisible. */
.nesencia__trama {
  position: absolute;
  top: 50%;
  left: 50%;
  height: 100%;
  aspect-ratio: 1;                     /* Bruma: `auto 100%` = un cuadrado del alto */
  transform: translate(-50%, -50%);
  z-index: 1;
  pointer-events: none;
  /* 36,328/900 del lado entre punto y punto; 1,7578/900 de radio. */
  --paso: 4.0364%;
  /* ⚠ EL RADIO NO ES 4,84% AUNQUE ESA SEA LA FRACCIÓN. En un `radial-gradient`
     con extensión `farthest-corner` los porcentajes de las paradas se miden
     sobre la línea del degradé, que va del centro a la ESQUINA de la baldosa:
     √2/2 del lado, no el lado. Poniendo 4,84% directo los puntos salían al 71%
     del tamaño y la trama casi no se veía. 4,84/0,7071 = 6,84. */
  background-image: radial-gradient(circle at 50% 50%,
    color-mix(in srgb, var(--ink) 40%, transparent) 0 6.84%, transparent 6.94%);
  background-size: var(--paso) var(--paso);
  /* El degradé radial que enmascara el grupo en el SVG de Bruma. */
  -webkit-mask-image: radial-gradient(closest-side at 50% 50%, #000, transparent);
          mask-image: radial-gradient(closest-side at 50% 50%, #000, transparent);
}

/* LA CAPA DEL RASTRO. Entre la trama y la tarjeta.

   ⚠ VA POR DETRÁS DE LA TARJETA Y EN BRUMA VA POR DELANTE. Su capa es
   `position: fixed; z-index: 20` sobre todo el viewport, así que sus imágenes
   pasan POR ENCIMA del titular. Puede hacerlo porque su texto son dos palabras
   enormes en blanco sobre negro; acá hay una cita de seis renglones, y taparla
   con una foto sería cambiar legibilidad por efecto. Pasando por detrás, el
   `backdrop-filter` de la tarjeta las difumina — que es exactamente para lo
   que existe el vidrio. Es una divergencia deliberada y anotada.

   No necesita `overflow`: el panel ya recorta con `clip`. */
.nesencia__rastro {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

/* El precalentado: el <template> clonado a un rincón de 1px para que las siete
   estén en caché cuando el cursor se mueva. Cada <picture> elige por `media` y
   no por `sizes`, así que este tamaño no cambia qué archivo baja. */
.nesencia__precarga {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  overflow: clip;
  opacity: 0;
  pointer-events: none;
}

/* UN CLON DEL RASTRO.

   Bruma: `.interaction_img` de 36rem con relación 2/2.7 y radio 8px. El ancho
   de abajo da 576 px justos a 1440 —su medida— y baja con la pantalla en vez
   de desbordar. Se centra en el cursor; Bruma lo cuelga hacia abajo y a la
   derecha porque su capa no recorta y acá el panel sí, así que centrado el
   corte queda parejo en los cuatro bordes. */
.nrastro {
  position: absolute;
  top: 0;
  left: 0;
  width: min(36rem, 40vw);
  aspect-ratio: 2 / 2.7;               /* Bruma: 2/2.7 */
  margin: 0;
  border-radius: var(--radius-sm);
  overflow: clip;
  will-change: transform, opacity;
  animation:
    nos-rastro-mov var(--rastro-vida, 700ms) cubic-bezier(.16, 1, .3, 1) both,
    nos-rastro-luz var(--rastro-vida, 700ms) cubic-bezier(.33, 1, .68, 1) both;
}
.nrastro > picture {
  display: block;
  width: 100%;
  height: 100%;
  animation: nos-rastro-fin var(--rastro-vida, 700ms) linear both;
}
.nrastro img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* LOS TRES TIEMPOS, MEDIDOS SOBRE LOS CLONES DE BRUMA (m-rastro3.mjs):

     · nace en el punto del clon anterior y viaja hasta el cursor con una
       salida muy larga — el clon 0 tardó 514 ms en asentarse.
     · aparece en ~200 ms, con salida suave.
     · a los ~515 ms empieza a apagarse encogiéndose a 0,6 en ~170 ms, y a los
       ~715 se lo saca del DOM. La caída medida es casi recta: va `linear`.

   El encogido va en el <picture> y no en la <figure>, igual que en Bruma: así
   el traslado y la muerte no se pelean por la misma propiedad `transform`.

   El `translate(-50%, -50%)` va DESPUÉS del translate3d: primero se lleva la
   caja al punto y después se corre media caja, que es lo que la centra. */
@keyframes nos-rastro-mov {
  from    { transform: translate3d(var(--x0), var(--y0), 0) translate(-50%, -50%); }
  73%, to { transform: translate3d(var(--x1), var(--y1), 0) translate(-50%, -50%); }
}
@keyframes nos-rastro-luz {
  from    { opacity: 0; }
  29%, to { opacity: 1; }
}
@keyframes nos-rastro-fin {
  from, 73% { opacity: 1; transform: scale(1); }
  to        { opacity: 0; transform: scale(.6); }
}

/* Bruma: .about_block { max-width:40rem; padding:3rem; radius small;
                         backdrop-filter: blur(50px); background:#0003 }
   ⚠ EL VELO NO ES EL DE BRUMA Y NO PUEDE SERLO. Bruma apoya blanco sobre un
   degradé oscuro y le alcanza con #0003. Acá la tarjeta tiene que sostener AA
   sobre CUALQUIER cosa que pase por detrás, y desde la 23ª por detrás pasa el
   rastro: siete imágenes que entran y salen.

   El número salió de calcular el peor caso y después medirlo. Con velo .58 la
   cita aguanta (4,75:1 contra la más clara), pero el subtítulo en `--ink-mute`
   —que es crema al 72%— cae a 3,54:1, porque un texto translúcido pierde por
   los dos lados a la vez: se aclara el fondo Y se aclara la tinta. A .70 el
   mismo caso da 4,76:1. Lo verifica v-rastro-aa.mjs, que fija la imagen más
   clara detrás de la tarjeta y mide el composite real.

   La otra mitad del arreglo está en assets.mjs: las siete se hornean con el
   techo de luminancia bajado. Las dos cosas juntas, no una sola. */
.nesencia__vidrio {
  position: relative;
  z-index: 3;
  width: 100%;
  max-width: 40rem;                    /* Bruma: 40rem */
  padding: var(--sp-12);               /* Bruma: 3rem */
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);                    /* Bruma: 1.5rem */
  text-align: center;
  border-radius: var(--radius);
  background: rgba(15, 14, 12, .70);   /* ver la nota de arriba: .58 no aguanta el rastro */
  backdrop-filter: blur(50px);         /* Bruma: 50px */
  -webkit-backdrop-filter: blur(50px);
  box-shadow: inset 0 0 0 var(--hairline) rgba(234, 227, 214, .10);
}
.nesencia__titulo {
  margin: 0;
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-snug);
  color: var(--ink);
}
.nesencia__titulo em {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
}
/* Bruma pone el subtítulo al 50% de blanco. Acá va --ink-mute (72% de crema):
   es el escalón más bajo que llega a AA sobre este velo, y sobre vidrio la
   regla de la casa prohíbe --ink-soft. Se cayó seis veces. */
.nesencia__sub {
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: 600;                    /* ver la nota del peso 500, mas abajo */
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-mute);
}
/* Bruma: .about_quote { 1.25rem / 130% / semibold / centrado } */
.nesencia__cita {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--ink);
  text-wrap: pretty;
}


/* ==========================================================================
   03 · SECTION_TEAM — EL ESCENARIO DE 150svh

   EL BLOQUE QUE HAY QUE CLAVAR. La estructura es la de Bruma tal cual:

     .nestudio__escenario   150vh, relative
       .nestudio__placa     STICKY top:30%        ← crece 1x → 2,21x
       .nestudio__campo     100vh, translateY(-35%)
         .nestudio__enc     rótulo + h2
         .nsat x4           absolutos contra el campo, con parallax
       .nestudio__col--izq  absoluto, bottom 9.5%
       .nestudio__col--der  absoluto, bottom 0

   EL CAMPO INTERMEDIO DE 100vh NO ES DE MÁS. Los porcentajes de los cuatro
   satélites (top 33/28/61/65%) están medidos contra él. Sacarlo obliga a
   recalcularlos contra un alto distinto y el calco deja de serlo.

   EL MOVIMIENTO SALE DE MEDIR, NO DE MIRAR (v-escenario.mjs, viewport 900):
     · arranca en cover 23% y termina en cover 75%
     · placa      scale 1 → 2,21   (lineal: los pasos medidos son parejos)
     · satélite 2 translateY 0 → −360px      −40svh
     · satélite 3 translateY 0 → −270px      −30svh
     · satélite 4 translateY 0 → −135px      −15svh
     · satélite 5 translateY 0 → −225px      −25svh
   Los cuatro frenan al final: eso es una salida, no una lineal.

   ⚠ Bruma los tiene en PÍXELES absolutos dentro de un escenario medido en vh,
   que es la incoherencia habitual de un editor visual. Acá van en svh: a 900px
   de alto dan el mismo número exacto que Bruma y arriba de eso no se
   despegan del escenario que los contiene.
   ========================================================================== */
.nestudio__escenario {
  position: relative;
  height: 150svh;                      /* Bruma: 150vh */
  max-height: 110rem;                  /* Bruma: 110rem */
  /* view-timeline-name publica el recorrido de ESTE bloque para que la placa
     y los cuatro satélites cuelguen todos del mismo reloj. Con view() a secas
     cada uno mediría su propio cruce y el conjunto se desarmaría. */
  view-timeline-name: --escenario;
}

/* Bruma: .team_img-wrap.is-first { sticky; top:30%; max-width:24rem;
                                    margin:0 auto 11.5%; z-index:3 }
   El tamaño base sale de .team_img-wrap { width:15% } y la relación 180x193
   es la que se midió en su render. */
.nestudio__placa {
  position: sticky;
  top: 30%;                            /* Bruma: 30% */
  z-index: 3;
  width: 15%;                          /* Bruma: 15% */
  max-width: 24rem;                    /* Bruma: 24rem */
  margin: 0 auto 11.5%;                /* Bruma: 0 auto 11.5% */
  aspect-ratio: 180 / 193;             /* medido en su render */
  display: grid;
  place-items: center;
  background: var(--brand-negro);
  /* clip-path y NO overflow:hidden. overflow crea contenedor de scroll y
     rompería el timeline de los descendientes; clip-path no. Es la regla de
     la casa y ya se cobró una vez. */
  clip-path: inset(0 round var(--radius));
  transform-origin: center center;
  will-change: transform;
}
.nestudio__marca {
  width: 72%;
  height: auto;
  color: var(--brand-crema);
  /* LA ⟨O⟩ ES LA APERTURA. Misma fracción de pupila que el diafragma del
     sitio (0,1321 / 0,4399 de la caja del logotipo). En circle() los
     porcentajes de posición son del propio elemento, así que las dos
     fracciones entran literales; el radio va en la unidad de circle(), que se
     resuelve contra la diagonal — de ahí el 4,6% para el 0,0338 del ancho.
     ESTADO BASE = YA ABIERTA. Si no hay soporte de timeline, se ve entera. */
  clip-path: circle(150% at 13.21% 43.99%);
}

/* Bruma: .team_imgs-wrap { h:100vh; flex col center; relative;
                            transform: translateY(-35%) } */
.nestudio__campo {
  position: relative;
  height: 100svh;                      /* Bruma: 100vh */
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  transform: translateY(-35%);         /* Bruma: -35% */
}
/* Bruma: .team_heading { max-width:35rem; flex col center; z-index:1 } */
.nestudio__enc {
  position: relative;
  z-index: 1;
  max-width: 35rem;                    /* Bruma: 35rem */
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--sp-3);
}
.nestudio__h2 {
  margin: 0;
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: clamp(2rem, 1.1rem + 2.4vw, 3rem);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--ink);
}
.nestudio__h2 em {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
}

/* Bruma: .team_img-wrap { absolute; w:15%; max-width:11.25rem; radius small } */
.nsat {
  position: absolute;
  width: 15%;                          /* Bruma: 15% */
  max-width: 11.25rem;                 /* Bruma: 11.25rem */
  margin: 0;
  clip-path: inset(0 round var(--radius));   /* ver §placa: clip, no overflow */
  background: var(--brand-negro);
  will-change: transform;
}
.nsat picture { display: block; }
.nsat img { width: 100%; height: 100%; display: block; object-fit: cover; }
.nsat--second, .nsat--fifth { aspect-ratio: 180 / 193; }   /* ver nota del glifo */
.nsat--second { top: 33%; left: 12%;  }              /* Bruma: 33% / 12%  */
.nsat--third  { top: 28%; right: -1%; z-index: 2; }  /* Bruma: 28% / -1%  */
.nsat--fourth { top: 61%; left: 4%;   }              /* Bruma: 61% / 4%   */
.nsat--fifth  { top: 65%; right: 13%; z-index: 2; }  /* Bruma: 65% / 13%  */

/* Los dos satélites que en Bruma son logos de terceros (React, Shopify) acá
   son glifos de Obscura grabados sobre placa oscura: mismo ritmo cara/símbolo,
   sin marcas ajenas. Van en SVG, así que pesan 0 KB y escalan sin ensuciar el
   trazo. La relación es la misma que la de las fotos para que la tira no se
   despareje. */
/* Los cuatro satelites son imagen: dos fotos propias en blanco y negro y dos
   retratos historicos a color. Los glifos que ocupaban dos de estos huecos
   salieron; la <O> recortada al cuenco se reusa en Fundamentos. */

/* Bruma: .team_content-items { w:32%; absolute; inset:auto auto 0 0;
                                padding-right:2.5rem }
          .is-left     { bottom: 9.5% }
          .is-inverted { left:auto; right:0; padding-left:2.5rem; gap:2.25rem } */
.nestudio__col {
  position: absolute;
  width: 32%;                          /* Bruma: 32% */
  inset: auto auto 0 0;
}
.nestudio__col--izq {
  bottom: 9.5%;                        /* Bruma: 9.5% */
  padding-right: 2.5rem;               /* Bruma: 2.5rem */
}
.nestudio__col--der {
  left: auto;
  right: 0;
  padding-left: 2.5rem;                /* Bruma: 2.5rem */
  display: flex;
  flex-direction: column;
  gap: 2.25rem;                        /* Bruma: 2.25rem */
}
.nestudio__parrafo {
  margin: 0;
  font-size: var(--fs-body);
  line-height: var(--lh-relaxed);
  color: var(--ink-mute);
  text-wrap: pretty;
}
.npilar { display: flex; flex-direction: column; gap: var(--sp-2); }
/* Bruma numera 01 · 02 · 03. Acá van romanos minúsculos: la doctrina de
   numeración de base.css § 281 reserva los arábigos para PASOS QUE SE
   RECORREN, y además #trabajo de la home ya usa 01..04. Tres pilares se
   cuentan, no se caminan. */
.npilar__label { margin: 0; color: var(--accent-2); }
.npilar__rom {
  display: inline-block;
  min-width: 1.6em;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.15em;
  letter-spacing: 0;
  text-transform: none;
}
.npilar__titulo {
  margin: 0;
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: var(--fs-h3);             /* Bruma h6: 1.125rem */
  line-height: 1.2;
  letter-spacing: var(--track-snug);
  color: var(--ink);
}


/* ==========================================================================
   04 · SECTION_MEMBERS — "Fundamentos"
   Bruma: grid 1fr 1fr 1fr x2, gap .875rem. Tarjeta: padding .5rem, radius
   xsmall, fondo claro, flex fila, imagen 5rem cuadrada.
   En Bruma esa imagen es una placa naranja con su isotipo; acá es la misma
   placa con el ícono de línea de la casa sobre cobre — el calco es directo.
   ========================================================================== */
.nfund__h2, .nmet__h2 {
  margin: 0 0 var(--sp-10);
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: var(--fs-h2);             /* Bruma h5: 2rem */
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--ink);
}
.nfund__grilla {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: .875rem;                        /* Bruma: .875rem */
}
.nfund__item {
  display: flex;
  align-items: stretch;
  gap: var(--sp-4);                    /* Bruma: 1rem */
  padding: var(--sp-2);                /* Bruma: .5rem */
  border-radius: var(--radius-sm);
  background: var(--bg-elev);
  box-shadow: inset 0 0 0 var(--hairline) var(--line);
}
/* Bruma pone una placa naranja de 5rem con SU isotipo, la MISMA en las seis.
   Aca va exactamente eso con la <O> de Obscura.
   ⚠ El blanco es literal y es el UNICO blanco puro de la pagina: la casa usa
   --brand-crema como su claro. Es pedido explicito, y funciona porque la placa
   tiene que separarse de la tarjeta, que ya es arena sobre crema — con crema
   sobre arena la placa desaparecia. */
.nfund__marca {
  flex: none;
  width: 5rem;                         /* Bruma: 5rem */
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: var(--radius-sm);
  background: #FFFFFF;
  color: var(--brand-negro);
}
.nfund__marca svg { width: 52%; height: auto; fill: currentColor; }
.nfund__texto {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  padding: .25rem .25rem 0 0;          /* Bruma: .25rem arriba y derecha */
  min-width: 0;
}
.nfund__titulo {
  margin: 0;
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 1.125rem;                 /* Bruma: 1.125rem */
  line-height: 1.2;
  letter-spacing: var(--track-snug);
  color: var(--ink);
}
.nfund__bajada {
  font-size: var(--fs-sm);             /* Bruma: .875rem */
  line-height: var(--lh-normal);
  color: var(--ink-mute);
}


/* ==========================================================================
   05 · SECTION_APPROACH — "Método"
   Bruma: .line punteada arriba del h2, grid 1fr 1fr 1fr con gap 2rem, y cada
   ítem en columna con gap 1.5rem sobre una imagen 3:2 con radius small.
   ========================================================================== */
.nmet__linea {
  width: 100%;
  border-top: 1px dotted var(--line-strong);   /* Bruma: 1px dotted */
  margin-bottom: var(--sp-8);
}
.nmet__grilla {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-8);                    /* Bruma: 2rem */
}
.nmet__item { display: flex; flex-direction: column; gap: var(--sp-6); }  /* Bruma: 1.5rem */
.nmet__marco {
  position: relative;
  aspect-ratio: 3 / 2;                 /* Bruma: 3/2 */
  border-radius: var(--radius);
  overflow: clip;
  background: var(--brand-negro);
}
.nmet__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.nmet__cuerpo { display: flex; flex-direction: column; gap: var(--sp-4); }  /* Bruma: 1rem */
.nmet__titulo {
  margin: 0;
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: var(--fs-h3);
  letter-spacing: var(--track-snug);
  color: var(--ink);
}
.nmet__texto {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
  color: var(--ink-mute);
  text-wrap: pretty;
}
.nmet__pie { margin: var(--sp-12) 0 0; }


/* ==========================================================================
   06 · SECTION_AWARDS — "Acreditaciones"
   Bruma: panel negro con radius xlarge; filas en grid 1fr 1fr 1fr 1fr con
   border-top punteado y padding .5rem 0; dato a .875rem.

   ⚠ ES UNA <table> DE VERDAD Y NO UNA GRILLA DE <div> COMO LA DE BRUMA. Son
   datos tabulares: un lector de pantalla tiene que poder recorrerlos por
   columna y anunciar el encabezado de cada celda. table-layout: fixed da las
   cuatro columnas iguales que pide el calco sin renunciar a la semántica.
   ========================================================================== */
.nacred__panel {
  border-radius: var(--radius-xl);     /* Bruma: xlarge */
  background: var(--bg);               /* dark → negro de marca */
  color: var(--ink);
  padding: clamp(var(--sp-8), 4vw, var(--sp-16));
}
.nacred__eyebrow { margin: 0 0 var(--sp-4); }
.nacred__h2 {
  margin: 0 0 var(--sp-10);
  max-width: 50rem;                    /* Bruma: .awards_heading 50rem */
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: var(--fs-display);
  line-height: var(--lh-tight);
  letter-spacing: var(--track-tight);
  color: var(--ink);
}
.nacred__tabla { width: 100%; border-collapse: collapse; table-layout: fixed; }
.nacred__c {
  padding: var(--sp-2) 16px var(--sp-2) 0;   /* Bruma: .5rem vertical, gap 16px */
  border-top: 1px dotted var(--line-strong); /* Bruma: 1px dotted */
  text-align: left;
  vertical-align: top;
  color: var(--ink-mute);
  /* ⚠ NINGUN PESO 500 EN ESTA HOJA, Y NO ES CAPRICHO. La familia esta partida
     en archivos por peso, asi que usar 500 en cuatro reglas obligaba a bajar
     plus-jakarta-sans-500-latin.woff2 ENTERO: 27 KB y un pedido mas que ninguna
     otra pagina del sitio pide. Medido en el perfil movil de Lighthouse, que es
     la metrica floja. El 600 ya viene con el resto y la diferencia optica entre
     500 y 600 a 12-15px no se ve. */
  font-weight: 600;
}
/* Bruma pone la cabecera de columnas en un gris muy bajo. --ink-faint (32% de
   crema) sobre el negro del panel da 2,40:1 medido, o sea la MITAD del umbral.
   --ink-mute (72%) es el escalon mas bajo que llega a AA sobre este fondo. */
.nacred__fila--cab .nacred__c { color: var(--ink-mute); border-top: 0; }
.nacred__c--anio { color: var(--ink); }
.nacred__c--tit  { color: var(--ink); }
.nacred__curso {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--accent-2);
  text-transform: none;
  letter-spacing: 0;
}
.nacred__curso::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
/* La línea que explica el hueco. Sin ella un .ph-badge se lee como error de
   carga; con ella se lee como la regla. Es la lección de .caso-cifra de la
   19ª pasada, y por eso no es una nota al pie tipográficamente escondida. */
.nacred__nota {
  margin: var(--sp-8) 0 0;
  max-width: 46rem;
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
  color: var(--ink-mute);
}

/* EL CIERRE. Mismo gesto de espaciado que .nmet__pie: la sección termina y la
   invitación viene después, separada. El titular reusa el cuerpo de la casa y
   la micro reusa .nacred__nota entera — sólo se le achica el margen, porque
   cuelga del botón y no de la tabla. */
.nacred__cierre { margin: var(--sp-12) 0 0; }
.nacred__cierre-linea {
  margin: 0 0 var(--sp-6);
  max-width: 34rem;
  font-family: var(--font-ui);
  font-size: var(--fs-h4);
  line-height: var(--lh-snug);
  color: var(--ink);
  text-wrap: balance;
}
.nacred__cierre-micro { margin-top: var(--sp-5); }


/* ==========================================================================
   EL MOVIMIENTO LIGADO AL SCROLL

   Rangos `cover`, nunca `entry`: entry mide sólo la entrada y deja la mitad
   del recorrido sin animar. Todo va dentro de @supports Y de la consulta de
   movimiento reducido, y todos los estados base de arriba están YA DIBUJADOS
   — sin soporte y sin JS la página se ve entera, sólo que quieta.
   ========================================================================== */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    /* La placa: 1 → 2,21 lineal, entre cover 23% y 75%. Los pasos medidos son
       parejos (0,100 por tramo), así que la curva es una recta de verdad. */
    .nestudio__placa {
      animation: nos-placa linear both;
      animation-timeline: --escenario;
      animation-range: cover 23% cover 75%;
    }
    @keyframes nos-placa { from { transform: scale(1); } to { transform: scale(2.21); } }

    /* La ⟨O⟩ irisa MIENTRAS LA PLACA SE ACERCA, y termina antes de que empiece
       a crecer (la escala arranca en cover 23%). Medido sobre render: con el
       tramo puesto más tarde la placa pasa medio recorrido siendo un cuadrado
       negro con media palabra, y eso no se lee como una apertura sino como una
       imagen a medio cargar. La apertura tiene que estar RESUELTA antes de que
       el bloque sea el centro de la pantalla. */
    .nestudio__marca {
      animation: nos-iris linear both;
      animation-timeline: --escenario;
      animation-range: cover 6% cover 24%;
    }
    @keyframes nos-iris {
      from { clip-path: circle(4.6% at 13.21% 43.99%); }
      to   { clip-path: circle(150% at 13.21% 43.99%); }
    }

    /* Los cuatro satélites. Mismo reloj y mismo tramo que la placa; lo que
       cambia es cuánto recorre cada uno — eso es lo que da la profundidad.
       Frenan al final: la curva es de salida, no lineal. */
    .nsat {
      animation: nos-sat var(--ease-out) both;
      animation-timeline: --escenario;
      animation-range: cover 23% cover 75%;
    }
    .nsat--second { --sat-y: -40svh; }   /* Bruma: −360px a 900 de alto */
    .nsat--third  { --sat-y: -30svh; }   /* Bruma: −270px */
    .nsat--fourth { --sat-y: -15svh; }   /* Bruma: −135px */
    .nsat--fifth  { --sat-y: -25svh; }   /* Bruma: −225px */
    @keyframes nos-sat {
      from { transform: translate3d(0, 0, 0); }
      to   { transform: translate3d(0, var(--sat-y), 0); }
    }
  }
}


/* ==========================================================================
   07 · CORTES

   Los de Bruma: 991 / 767 / 479.
   ========================================================================== */

/* --------------------------------------------------------------------------
   ≤ 991 — TABLET
   Bruma: el hero pierde el alto fijo, los titulares pasan a columna alineados
   a la izquierda, la ficha entra EN EL FLUJO entre las dos palabras y la
   franja técnica deja de estar anclada. El escenario colapsa.
   -------------------------------------------------------------------------- */
@media (max-width: 991px) {
  .ncab {
    min-height: auto;                                  /* Bruma: min-height auto */
    padding-block: calc(76px + var(--sp-14)) var(--sp-10);
  }
  /* Bruma: .about_component { min-height: auto } y .about_block { width:100%;
     max-width:none }. El panel deja de reservar 90vh y el vidrio pasa a ocupar
     todo el ancho: en tablet una tarjeta de 40rem centrada dentro de un panel
     casi vacio se lee como un error de maqueta, no como una estampa. */
  .nesencia__panel  { min-height: auto; }
  .nesencia__vidrio { max-width: none; margin-inline: auto; }
  /* ⚠ ACA EL CALCO SE APARTA A PROPOSITO, Y ES POR COMPOSICION.
     Bruma apila titular / ficha / titular en una columna, y su ficha de 40vw
     funciona porque queda ENTRE las dos palabras. Aca el titular es UN solo
     <h1> —para que el titulo de la pagina sea la frase entera y no la mitad—,
     asi que la ficha cae DESPUES de las dos y a 768 dejaba medio ancho vacio a
     la derecha: 763px de alto contra 588 de Bruma, con el hueco justo en el
     medio. Copiar el 40vw sin copiar el orden es copiar el numero y no la
     composicion.
     Solucion: en tablet van LADO A LADO, que es lo que hace el escritorio.
     A 479 vuelve a apilarse, que es donde Bruma tambien apila. */
  .ncab__escena {
    flex-direction: row;
    align-items: center;
    gap: var(--sp-10);
  }
  .ncab__titulo {
    flex: 1 1 auto;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    gap: var(--sp-2);
  }
  /* Bruma mete el bloque central ENTRE las dos palabras con el orden del
     flujo. Acá el <h1> es un solo elemento, así que el centro va después y
     se ordena con flex: mismo resultado, sin partir el título en dos. */
  .ncab__centro {
    position: static;
    transform: none;
    align-items: flex-start;
    flex: 0 0 auto;
  }
  .ncab__caja  { width: 40vw; }
  .ncab__ficha { width: 100%; height: auto; border-radius: 2vw; }  /* Bruma: 40vw / 2vw */
  /* El primero define la caja; los otros seis se apilan encima. */
  .ncab__cuadro { position: absolute; inset: 0; }
  .ncab__cuadro[data-cuadro="0"] { position: relative; }
  .ncab__lugar { display: none; }                    /* Bruma lo oculta acá */
  .ncab__franja { position: relative; inset: auto; margin-top: 2.75rem; }  /* Bruma: 2.75rem */

  /* EL ESCENARIO SE DESARMA. Bruma acá oculta los cuatro satélites; nosotros
     los dejamos, porque esconder dos de las cinco fotos es perder justo el
     contenido que esta página existe para mostrar. Es la única divergencia
     deliberada del calco y está anotada en el plan.

     Pasa a una grilla de cuatro columnas: rótulo y placa a todo el ancho, los
     cuatro satélites en una tira pareja debajo, y las dos columnas de texto
     apiladas al final. El orden lo fija `order` porque en el DOM la placa va
     antes que el rótulo — que es lo que necesita el sticky de escritorio. */
  .nestudio__escenario {
    height: auto;
    max-height: none;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    justify-items: center;
    align-items: start;
    gap: var(--sp-6) var(--sp-4);
    view-timeline-name: none;
  }
  .nestudio__enc   { order: -1; grid-column: 1 / -1; max-width: 100%; }
  .nestudio__placa {
    order: 0; grid-column: 1 / -1;
    position: static;
    width: 100%; max-width: 11.25rem;
    margin: 0;
    transform: none !important;
    animation: none !important;
  }
  .nestudio__marca { animation: none !important; clip-path: circle(150% at 13.21% 43.99%); }
  /* display:contents sube el rótulo y los cuatro satélites a la grilla del
     escenario, que es donde tienen que estar ahora. */
  .nestudio__campo { display: contents; }
  .nsat {
    position: static;
    width: 100%; max-width: none;
    transform: none !important;
    animation: none !important;
  }
  .nsat--second { order: 1; }
  .nsat--third  { order: 2; }
  .nsat--fourth { order: 3; }
  .nsat--fifth  { order: 4; }
  .nestudio__col     { position: static; grid-column: 1 / -1; width: 100%; padding: 0 !important; order: 5; }
  .nestudio__col--der { order: 6; }

  .nfund__grilla { grid-template-columns: 1fr 1fr; }   /* Bruma: 2 columnas */
  .nmet__grilla { gap: var(--sp-4); }                  /* Bruma: 1rem */
}

/* --------------------------------------------------------------------------
   ≤ 767 — MÓVIL GRANDE
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {
  .ncab__franja { margin-top: var(--sp-6); }           /* Bruma: 1.5rem */
  .nesencia__panel { padding: var(--sp-4); }
  .nesencia__vidrio { padding: var(--sp-8); }          /* Bruma: 2rem de lado */
  .nfund__grilla { gap: var(--sp-2); }
}

/* --------------------------------------------------------------------------
   ≤ 479 — MÓVIL
   Bruma: la ficha ocupa el ancho completo, la franja pasa a bloque, vuelve el
   chip de lugar, Fundamentos y Método a una columna, y la fila de la tabla se
   APILA. Eso último es lo que evita el scroll horizontal y que se pierda la
   columna del título, que es la que importa.
   -------------------------------------------------------------------------- */
@media (max-width: 479px) {
  /* Bruma tambien apila aca. Vuelve la columna y la ficha a ancho completo. */
  .ncab__escena { flex-direction: column; align-items: stretch; gap: var(--sp-8); }
  .ncab__centro { width: 100%; }
  .ncab__caja   { width: 100%; }
  .ncab__ficha  { width: 100%; }
  .ncab__lugar { display: flex; }                      /* Bruma lo devuelve acá */
  .ncab__franja-in { grid-template-columns: 1fr; gap: var(--sp-4); }
  .ncab__dato:nth-child(2), .ncab__dato:nth-child(3) {
    align-items: flex-start; text-align: left;
  }

  .nestudio__escenario { grid-template-columns: repeat(2, 1fr); }
  .nfund__grilla { grid-template-columns: 1fr; }
  .nmet__grilla { grid-template-columns: 1fr; gap: var(--sp-12); }  /* Bruma: 3rem */

  /* ⚠ EL TITULAR DEL PANEL BAJA A --fs-h2, Y ES EL ARREGLO DE UN DESBORDE REAL
     (45ª). --fs-display tiene PISO de 40px porque la escala está calibrada
     390→1440; abajo de eso ya no achica más, pero la caja sí. Medido a 320:
     «Acreditaciones» pedía 285px donde el panel daba 232, y esos 53px subían
     por .nacred__panel hasta .sangre y corrían el documento 9px.
     Se baja el tamaño en vez de dejar que parta: `overflow-wrap` (base.css) es
     la red de seguridad, no la solución — un titular de una sola palabra
     partido al medio se lee como un error de maqueta.
     A 390 entraba por 17px, o sea al filo; el corte va en el 479 de la hoja
     (los cortes de Bruma, ver tokens.css § 6ter) y no en un valor nuevo. */
  .nacred__h2 { font-size: var(--fs-h2); }

  /* LA TABLA SE APILA. thead se esconde y cada celda lleva su propio rótulo
     desde data-col, así que no se pierde ni una relación de la tabla. */
  .nacred__tabla, .nacred__tabla tbody, .nacred__fila, .nacred__c { display: block; width: 100%; }
  .nacred__tabla thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .nacred__fila { padding: var(--sp-4) 0; border-top: 1px dotted var(--line-strong); }
  .nacred__c {
    border-top: 0;
    padding: 0 0 var(--sp-2);
    display: grid;
    grid-template-columns: 7rem 1fr;
    gap: var(--sp-3);
    align-items: baseline;
  }
  .nacred__c::before {
    content: attr(data-col);
    color: var(--ink-faint);
    font-size: var(--fs-eyebrow);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
}


/* ==========================================================================
   08 · DEGRADACIÓN

   ⚠ animation-timeline: view() FUNCIONA SIN JAVASCRIPT, y el valor calculado
   de una animación le gana a cualquier declaración normal por más específica
   que sea. Por eso las reglas de abajo llevan `animation: none` y no sólo la
   propiedad final: sin eso son letra muerta. Costó una pasada entera
   descubrirlo.

   Todos los estados base ya están dibujados, así que sin JS no hace falta
   apagar nada más: la página se ve completa, sólo que quieta.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .nestudio__placa  { animation: none !important; transform: none !important; }
  .nestudio__marca  { animation: none !important; clip-path: circle(150% at 13.21% 43.99%) !important; }
  .nsat             { animation: none !important; transform: none !important; }
  .ncab__cuadro     { animation: none !important; opacity: 0; }
  .ncab__cuadro[data-cuadro="0"] { opacity: 1; }
  .ncab__ficha      { animation: none !important; }
  /* El rastro ni siquiera se arma: el script sale antes de crear nada. Esto
     es por si alguna vez queda un clon vivo cuando se cambia la preferencia. */
  .nrastro, .nrastro > picture { animation: none !important; display: none; }
}
