/* ============================================================
   Esforal — la web del estudio.

   Oscura, quieta y con una sola idea en pantalla cada vez. No imita a
   esforia.app, que es cinematográfica y tiene pétalos cayendo porque su
   trabajo es enseñar cómo se siente el producto; el de ésta es decir quién
   responde. Lo que sí comparten, y a propósito, son las dos tipografías de la
   app: Sora en los titulares y Manrope en el texto.

   Un único gesto en movimiento — el nombre escribiéndose al entrar — y el
   resto se revela al pasar, sin nada que gire ni parpadee de fondo.
   ============================================================ */

/* ------------------------------------------------------------
   Tipografías, servidas desde esta misma carpeta.

   Solo los pesos que se usan, y solo latin + latin-ext, que es lo que cubren
   los seis idiomas de la página. Añadir un peso que nada renderiza cuesta
   descarga a cambio de nada — la misma regla que sigue la app.

   `font-display: swap`: el texto se pinta con la pila del sistema y cambia
   cuando llega la fuente. El comportamiento por defecto deja la primera
   pantalla en blanco hasta tres segundos, y la primera pantalla de esta
   página es justamente el nombre escribiéndose.
   ------------------------------------------------------------ */
@font-face {
  font-family: "Sora"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/sora-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Sora"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/sora-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Sora"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../fonts/sora-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Sora"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../fonts/sora-latin-ext-500-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Sora"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("../fonts/sora-latin-600-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Sora"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("../fonts/sora-latin-ext-600-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Manrope"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/manrope-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Manrope"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/manrope-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Manrope"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../fonts/manrope-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Manrope"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../fonts/manrope-latin-ext-500-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ------------------------------------------------------------
   Tokens.

   La página se compromete con un solo mundo visual, el oscuro, y por eso no
   hay bloque de `prefers-color-scheme`: no es un olvido. Un fondo casi negro
   con un halo morado ES la página; en claro sería otra distinta y peor, no la
   misma con los colores cambiados. La contrapartida obligatoria de esa
   decisión es que todo color esté declarado aquí y que `body` pinte su fondo
   explícitamente, para que la página se sostenga sobre cualquier lienzo.
   ------------------------------------------------------------ */
:root {
  --void:        #08080B;
  --sup:         #101017;
  --sup-2:       #16161F;
  --ink:         #F5F5F8;
  --ink-soft:    #A9A9BA;
  --ink-faint:   #8A8A9B;
  --linea:       #22222D;
  --linea-viva:  #33333F;
  --acento:      #8B7BFF;
  --acento-ap:   #A99CFF;
  --acento-baja: rgba(139, 123, 255, 0.13);
  --vivo:        #4ED89C;
  --vivo-baja:   rgba(78, 216, 156, 0.12);

  /* Los tres colores de la marca. Son un CALCO de assets/marca.svg y se
     cambian a la vez que él, nunca por su cuenta.

     Tienen token propio aunque --marca-punta valga hoy lo mismo que --acento, y
     esa duplicación es el motivo de que existan: --acento es un color de
     interfaz y algún día se retocará por razones de interfaz. Si la barra
     bebiera de él, la marca de la barra se separaría en silencio del fichero
     maestro y nadie se enteraría hasta ver las dos juntas. */
  --marca-punta: #8B7BFF;
  --marca-cola:  #4C4470;
  --marca-aro:   #3A3450;

  --sora: "Sora", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --manrope: "Manrope", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  --canal: 1180px;
  --margen: clamp(22px, 5vw, 72px);
  --alto-nav: 68px;
}

/* En un monitor grande, 1180px de contenido sobre 2545 disponibles se leen
   como una cinta centrada con la pantalla sobrando alrededor. Crece un poco,
   lo justo para que la página parezca hecha para ese tamaño; más sería
   estirar el texto, que es lo contrario de lo que se busca aquí. */
@media (min-width: 1700px) {
  :root { --canal: 1320px; }
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Un ancla que aterriza debajo de la barra fija deja su titular tapado. */
  scroll-padding-top: var(--alto-nav);
}

body {
  background: var(--void);
  color: var(--ink);
  font-family: var(--manrope);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--acento-ap);
  outline-offset: 3px;
  border-radius: 3px;
}

/* Escondido sin sacarlo de la pantalla. El clásico `left: -9999px` ensancha
   el lienzo hacia la izquierda y es una de las dos cosas que hacían que el
   documento midiera más que la ventana. `clip-path` lo oculta sin ocupar. */
.skip {
  position: absolute; top: 10px; left: 12px; z-index: 200;
  width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%);
  background: var(--sup-2); border: 1px solid var(--linea-viva);
  padding: 11px 18px; border-radius: 8px; text-decoration: none;
  white-space: nowrap;
}
.skip:focus { width: auto; height: auto; overflow: visible; clip-path: none; }

/* ------------------------------------------------------------
   Barra superior
   ------------------------------------------------------------ */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 60;
  height: var(--alto-nav);
  display: flex; align-items: center; gap: clamp(14px, 3vw, 40px);
  padding: 0 var(--margen);
  /* Transparente arriba del todo y con fondo en cuanto se baja. La clase la
     quita el script; sin JavaScript se queda el estado con fondo, que es el
     que nunca estorba. */
  background: rgba(8, 8, 11, 0.72);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  backdrop-filter: blur(18px) saturate(1.3);
  border-bottom: 1px solid var(--linea);
  transition: background .3s ease, border-color .3s ease;
}
.nav.arriba {
  background: transparent;
  border-bottom-color: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.nav__mark { display: flex; align-items: center; gap: 10px; text-decoration: none; margin-right: auto; }
/* La aguja va suelta, sin teja detrás, y es lo que más separa esta marca de la
   de Esforia: aquella es una letra dentro de una caja morada, ésta es un
   dibujo sin contenedor. Poner la aguja sobre una teja habría dejado dos
   marcas hermanas donde hacen falta dos marcas distintas.

   Va a 28px y no a 30: sin fondo, la mancha de tinta es menor a igualdad de
   caja, así que necesita un pelo más de aire alrededor para pesar lo mismo
   junto al nombre. */
/* La aguja de la barra pinta con los colores del fichero maestro, no con los
   del acento. Llevaba la punta aclarada a --acento-ap para pesar más a 30px, y
   el resultado eran dos marcas casi iguales en la misma página: la de la barra
   un punto más clara que la de Sobre nosotros. Casi iguales es peor que
   distintas. */
.nav__aguja { width: 30px; height: 30px; flex: none; display: block; overflow: visible; }
.aguja__punta { fill: var(--marca-punta); }
.aguja__cola { fill: var(--marca-cola); }
.aguja__aro { stroke: var(--marca-aro); }
/* Al pasar el ratón se aclara, que es lo que hacía la punta en reposo: el
   mismo tono, ahora ganado en vez de regalado. */
.nav__mark:hover .aguja__punta { fill: var(--acento-ap); }
.nav__mark:hover .aguja__cola { fill: #5C5488; }
.nav__mark:hover .aguja__aro { stroke: #4A4368; }
.aguja__punta, .aguja__cola, .aguja__aro { transition: fill .2s ease, stroke .2s ease; }
.nav__word { font-family: var(--sora); font-size: 1.02rem; font-weight: 500; letter-spacing: -.01em; }

.nav__links { display: flex; align-items: center; gap: 4px; }
.nav__links a {
  padding: 8px 13px; border-radius: 8px;
  font-size: .92rem; color: var(--ink-soft); text-decoration: none;
  white-space: nowrap;
  transition: color .2s ease, background .2s ease;
}
.nav__links a:hover { color: var(--ink); background: rgba(255, 255, 255, 0.05); }
/* Dos redacciones para el destino más largo; la media query de 400px elige. */
.nav-corto { display: none; }

/* ---- selector de idioma ---- */
.lang { position: relative; flex: none; }
.lang__btn {
  display: flex; align-items: center; gap: 7px;
  padding: 7px 11px; border-radius: 9px;
  background: transparent; border: 1px solid var(--linea-viva);
  color: var(--ink-soft); font-family: var(--manrope); font-size: .84rem;
  cursor: pointer;
  transition: color .2s ease, border-color .2s ease;
}
.lang__btn:hover { color: var(--ink); border-color: var(--acento); }
.lang__globo { width: 17px; height: 17px; flex: none; }
.lang__codigo { font-weight: 500; letter-spacing: .06em; }

.lang__menu {
  position: absolute; top: calc(100% + 9px); right: 0;
  min-width: 168px; list-style: none;
  background: var(--sup-2);
  border: 1px solid var(--linea-viva);
  border-radius: 11px;
  padding: 6px;
  box-shadow: 0 22px 48px rgba(0, 0, 0, .55);
}
.lang__menu[hidden] { display: none; }
.lang__menu button {
  display: block; width: 100%; text-align: left;
  padding: 9px 12px; border-radius: 7px;
  background: transparent; border: none;
  color: var(--ink-soft); font-family: var(--manrope); font-size: .9rem;
  cursor: pointer;
  transition: color .16s ease, background .16s ease;
}
.lang__menu button:hover { background: rgba(255, 255, 255, 0.06); color: var(--ink); }
.lang__menu button[aria-current="true"] { color: var(--acento-ap); background: var(--acento-baja); }

/* ------------------------------------------------------------
   Piezas comunes
   ------------------------------------------------------------ */
.eyebrow {
  font-family: var(--sora);
  font-size: 11px; font-weight: 500;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--ink-faint);
}

h2 {
  font-family: var(--sora);
  font-size: clamp(1.9rem, 4.4vw, 3.1rem);
  font-weight: 400; letter-spacing: -.03em; line-height: 1.12;
  text-wrap: balance;
}

main > section {
  max-width: var(--canal);
  margin: 0 auto;
  padding-left: var(--margen);
  padding-right: var(--margen);
}

/* ------------------------------------------------------------
   Inicio — el nombre escribiéndose
   ------------------------------------------------------------ */
/* El inicio va A SANGRE, y es lo único de la página que no se ciñe a la
   columna de lectura.

   `main > section` limita cada sección a --canal (1180px) y la centra, que es
   lo correcto para un texto que se lee. Pero el halo del inicio no es texto:
   es el fondo, y al recortarlo el `overflow: hidden` de aquí abajo moría en el
   borde de esa columna. En una ventana de 1524px eso dejaba la atmósfera
   encerrada entre 165 y 1345 y dos franjas de negro plano a los lados, con un
   canto vertical perfectamente visible — más a la derecha, porque el
   resplandor verde cae al 78% del ancho, justo contra el corte.

   Soltando el máximo, la sección mide la ventana entera, el halo la llena y el
   recorte pasa a hacerse en el borde de la pantalla, que es donde no se ve. El
   contenido sigue centrado por el propio flex y cada bloque conserva su medida
   (la tagline, 34ch), así que en un monitor ancho no se estira nada. */
.inicio {
  max-width: none;
  min-height: 100svh;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
  position: relative;
  padding-top: var(--alto-nav);
  padding-bottom: 72px;
  /* El halo se sale 20% por cada lado a propósito, para que el degradado
     muera fuera de cuadro en vez de cortarse en el borde. Sin recortarlo aquí
     ese exceso alarga el documento: a 435px de ventana el lienzo medía 522 y
     la página se podía arrastrar de lado. */
  overflow: hidden;
}

/* El halo. Un degradado radial fijo, sin animación: la única cosa que se
   mueve en esta pantalla tiene que ser el nombre. */
.inicio__halo {
  position: absolute; inset: -10% -20% auto -20%; height: 120%;
  background:
    radial-gradient(52% 46% at 50% 38%, rgba(139, 123, 255, 0.17), transparent 70%),
    radial-gradient(38% 34% at 78% 66%, rgba(78, 216, 156, 0.06), transparent 72%);
  pointer-events: none;
  z-index: 0;
}
/* El contenido por encima del halo, elemento a elemento y NO con un
   `.inicio > *`. Aquella regla ponía `position: relative` a todos los hijos,
   incluida la flecha de "desliza", que es `absolute`: la relativa ganaba por
   orden en la hoja, la flecha volvía al flujo y su `bottom` pasaba a ser un
   desplazamiento relativo. Resultado, la flecha aterrizaba a media pantalla
   encima de la tagline. `isolation` crea el contexto de apilado sin tocar la
   posición de nadie. */
.inicio { isolation: isolate; }
.inicio__halo { z-index: 0; }
.inicio__eyebrow,
.inicio__nombre,
.inicio__tagline { position: relative; z-index: 1; }
.inicio__cue { z-index: 1; }

.inicio__eyebrow { margin-bottom: clamp(20px, 4vh, 34px); }

/* El nombre. Un `grid` que apila fantasma y texto en la misma celda: el
   fantasma lleva las siete letras y fija el ancho, el texto crece encima sin
   mover nada. Sin eso la línea se ensancha letra a letra y toda la pantalla
   tiembla mientras se escribe. */
.inicio__nombre {
  display: grid;
  font-family: var(--sora);
  /* El techo estaba en 10.5rem, que a 13vw se alcanza ya sobre los 1292px: de
     ahí para arriba el nombre se quedaba clavado en 899px de ancho, y en un
     monitor de 2560 ocupaba un tercio de la pantalla con todo lo demás vacío.
     A 16rem manda el 13vw hasta cerca de 1970px, así que entre un portátil y un
     Full HD el nombre ocupa siempre en torno al 70% del ancho, y por encima
     baja poco a poco en vez de cortarse de golpe. */
  font-size: clamp(3.1rem, 13vw, 16rem);
  font-weight: 500;
  letter-spacing: clamp(.02em, .6vw, .09em);
  line-height: 1;
}
.nombre__fantasma,
.nombre__texto { grid-area: 1 / 1; white-space: nowrap; }
.nombre__fantasma { visibility: hidden; }
.nombre__texto {
  justify-self: center;
  background: linear-gradient(178deg, var(--ink) 30%, #B9B3E8 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* El cursor va en la misma celda para no ensanchar la caja. El script lo
   coloca con --avance, que es la mitad del ancho ya escrito. */
.nombre__cursor {
  grid-area: 1 / 1;
  justify-self: center;
  align-self: center;
  width: 2px; height: .74em;
  background: var(--acento);
  translate: calc(var(--avance, 0px) + .32em) 0;
  animation: parpadeo 1.05s steps(1) infinite;
}
.nombre__cursor.apagado { opacity: 0; animation: none; }
@keyframes parpadeo { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

.inicio__tagline {
  margin: clamp(22px, 4vh, 36px) auto 0;
  max-width: 34ch;
  font-size: clamp(1rem, 1.9vw, 1.22rem);
  color: var(--ink-soft);
  line-height: 1.55;
  transition: opacity .8s ease .1s, transform .8s cubic-bezier(.22, 1, .36, 1) .1s;
}
/* El estado oculto de partida sólo existe si hay JavaScript para deshacerlo.
   Ver el script en línea del <head>. */
.js .inicio__tagline { opacity: 0; transform: translateY(10px); }
.js .inicio__tagline.dentro { opacity: 1; transform: none; }

.inicio__cue {
  position: absolute; bottom: clamp(24px, 5vh, 46px); left: 50%;
  translate: -50% 0;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  font-family: var(--sora);
  font-size: 10.5px; letter-spacing: .22em; text-transform: uppercase;
  color: var(--ink-faint); text-decoration: none;
  transition: opacity .8s ease .5s, color .2s ease;
}
.js .inicio__cue { opacity: 0; }
.js .inicio__cue.dentro { opacity: 1; }
.inicio__cue:hover { color: var(--ink-soft); }
.inicio__cue svg { width: 19px; height: 19px; animation: respira 2.4s ease-in-out infinite; }
@keyframes respira {
  0%, 100% { transform: translateY(0); opacity: .55; }
  50% { transform: translateY(5px); opacity: 1; }
}

/* ------------------------------------------------------------
   Sobre nosotros — la raíz del nombre
   ------------------------------------------------------------ */
.sobre {
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  padding-top: clamp(90px, 12vh, 150px);
  padding-bottom: clamp(90px, 12vh, 150px);
  gap: 18px;
}
.sobre__titulo { max-width: 16ch; }
.sobre__intro { max-width: 52ch; color: var(--ink-soft); }

.raiz {
  list-style: none;
  margin-top: clamp(26px, 5vh, 52px);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--linea);
  border-block: 1px solid var(--linea);
}
.raiz__parte {
  background: var(--void);
  padding: clamp(24px, 3.4vw, 40px) clamp(18px, 2.4vw, 32px);
  display: flex; flex-direction: column; gap: 10px;
  /* Revelado al pasar. El retardo lo pone el script por índice, para que las
     tres entren en cascada y no las tres a la vez. */
  transition: opacity .75s ease, transform .75s cubic-bezier(.22, 1, .36, 1);
  transition-delay: var(--retardo, 0ms);
}
.js .raiz__parte { opacity: 0; transform: translateY(20px); }
.js .raiz__parte.dentro { opacity: 1; transform: none; }

.raiz__palabra {
  font-family: var(--sora);
  font-size: clamp(1.05rem, 1.9vw, 1.42rem);
  font-weight: 400;
  letter-spacing: .04em;
  color: var(--ink-faint);
  line-height: 1.2;
}
/* Las letras que forman el nombre. Es todo el gesto de esta sección: la
   palabra entera se lee, y sus tres primeras letras dicen de dónde sale
   "Esforal" sin una sola frase de explicación. */
.raiz__palabra b {
  font-weight: 600;
  color: var(--acento-ap);
  font-size: 1.32em;
  letter-spacing: .01em;
}
.raiz__traduccion {
  font-family: var(--sora);
  font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-faint);
  margin-top: -4px;
}
.raiz__traduccion[hidden] { display: none; }
/* Entre 601 y 900px la raíz va a una sola columna y la glosa se estiraba a
   todo el ancho: 97 caracteres por línea a 900px, 91 en un móvil apaisado. El
   ojo pierde el renglón pasados unos 75. El tope no estorba en tres columnas,
   donde cada parte ya mide bastante menos. */
.raiz__glosa { color: var(--ink-soft); font-size: .97rem; max-width: 62ch; }

/* La marca cerrando la sección. Fila que envuelve: el dibujo y su pie van
   lado a lado mientras quepan y se apilan cuando no, sin necesidad de una
   media query propia. */
.marca-cierre {
  margin: clamp(30px, 6vh, 56px) 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(20px, 4vw, 44px);
}
.marca-cierre__dibujo {
  width: clamp(112px, 15vw, 176px);
  height: auto;
  flex: none;
  display: block;
}
.marca-cierre__pie {
  color: var(--ink-soft);
  font-size: .97rem;
  max-width: 44ch;
  min-width: min(100%, 24ch);
}

.sobre__cierre {
  margin-top: clamp(26px, 5vh, 48px);
  max-width: 56ch;
  color: var(--ink-soft);
}

/* ------------------------------------------------------------
   Sobre nosotros — las personas
   ------------------------------------------------------------ */
.personas {
  padding-top: clamp(80px, 11vh, 140px);
  padding-bottom: clamp(80px, 11vh, 140px);
  display: flex; flex-direction: column; gap: 18px;
  border-top: 1px solid var(--linea);
}
.personas__titulo { max-width: 18ch; }
.personas__lead { color: var(--ink-soft); max-width: 52ch; }

.fichas {
  list-style: none;
  margin-top: clamp(20px, 4vh, 40px);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(18px, 3vw, 34px);
}
.ficha {
  background: linear-gradient(168deg, var(--sup-2), var(--sup));
  border: 1px solid var(--linea);
  border-radius: 18px;
  overflow: hidden;
  display: flex; flex-direction: column;
}

/* Las dos fotos vienen del repo de la web de producto y NO miden lo mismo:
   800x1066 una y 800x1202 la otra. Sin encuadre forzado, una ficha saldría más
   alta que la otra y la fila quedaría descuadrada. `aspect-ratio` fija el marco
   y `object-fit: cover` recorta lo que sobra sin deformar a nadie — que es el
   fallo clásico de estirar un retrato para que quepa. */
.ficha__foto {
  width: 100%;
  /* `height: auto` no es decorativo: los atributos width/height del <img> se
     traducen a `height: 400px`, y con un alto definido el navegador ignora el
     aspect-ratio de abajo. Medido: la caja salía 507x400 en vez de 507x634.
     Los atributos se quedan igualmente, porque reservan el hueco antes de que
     la foto llegue y evitan que la página salte al cargarla. */
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center 22%;
  display: block;
  background: var(--sup-2);
}
.ficha__texto { padding: 18px 20px 22px; display: flex; flex-direction: column; gap: 9px; }
.ficha__nombre {
  font-family: var(--sora);
  font-size: clamp(1.1rem, 2vw, 1.35rem);
  font-weight: 500; letter-spacing: -.02em;
}
.ficha__cargos { display: flex; flex-wrap: wrap; gap: 7px; }
.ficha__cargo {
  font-family: var(--sora);
  font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--acento-ap); background: var(--acento-baja);
  border-radius: 20px; padding: 5px 11px;
}

/* Revelado al pasar, como el resto. Sin JS nacen visibles — ver el script en
   línea del <head>. */
.ficha { transition: opacity .75s ease, transform .75s cubic-bezier(.22, 1, .36, 1); transition-delay: var(--retardo, 0ms); }
.js .ficha { opacity: 0; transform: translateY(20px); }
.js .ficha.dentro { opacity: 1; transform: none; }

/* ------------------------------------------------------------
   Apps
   ------------------------------------------------------------ */
.apps {
  padding-top: clamp(80px, 11vh, 140px);
  padding-bottom: clamp(80px, 11vh, 140px);
  display: flex; flex-direction: column; gap: 18px;
}
.apps__titulo { margin-bottom: clamp(14px, 3vh, 26px); }

.app {
  background: linear-gradient(168deg, var(--sup-2), var(--sup));
  border: 1px solid var(--linea);
  border-radius: 18px;
  padding: clamp(26px, 3.4vw, 40px);
  display: flex; flex-direction: column; gap: 22px; align-items: flex-start;
  transition: opacity .75s ease, transform .75s cubic-bezier(.22, 1, .36, 1);
}
.js .app { opacity: 0; transform: translateY(22px); }
.marca-cierre { transition: opacity .75s ease, transform .75s cubic-bezier(.22, 1, .36, 1); }
.js .marca-cierre { opacity: 0; transform: translateY(20px); }
.js .marca-cierre.dentro { opacity: 1; transform: none; }
.js .app.dentro { opacity: 1; transform: none; }

.app__head { display: flex; align-items: center; gap: 15px; flex-wrap: wrap; }

/* El icono del proyecto, si lo tiene. Va como <img> y no en línea: el
   contenido lo escribe un panel, y un SVG pegado dentro del documento
   ejecutaría lo que trajera. Dentro de un <img> no. */
.app__icono {
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 11px;
  object-fit: cover;
  background: var(--sup-2);
  border: 1px solid var(--linea);
}

.app__nombre {
  font-family: var(--sora);
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  font-weight: 500; letter-spacing: -.025em;
}
.app__estado {
  font-family: var(--sora);
  font-size: 10.5px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--vivo); background: var(--vivo-baja);
  border-radius: 20px; padding: 6px 13px;
}
.app__desc { color: var(--ink-soft); max-width: 62ch; }

/* Cuatro columnas declaradas, no `auto-fit`: los datos son exactamente
   cuatro, y auto-fit reparte el ancho en cuantas pistas quepan — a partir de
   cierto ancho salía una quinta vacía, que se lee como un dato que falta. */
.datos {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-template-rows: auto auto;
  gap: 22px 28px;
  width: 100%;
  padding: 24px 0;
  border-block: 1px solid var(--linea);
}
/* Etiquetas en una fila y cifras en otra, con `subgrid`.

   Cada par vive en su propio <div> por semántica — dt y dd emparejados —, y
   eso los aislaba: "Permisos peligrosos" ocupa dos líneas donde "Idiomas"
   ocupa una, así que el 0 quedaba un renglón por debajo del 6 y la fila de
   cifras salía escalonada. Con subgrid los <div> heredan las dos filas de la
   rejilla madre, la altura de la fila de etiquetas la marca la más alta de
   todas, y las cuatro cifras se alinean. Un navegador sin subgrid vuelve al
   apilado de antes, que es feo pero legible. */
.datos > div {
  display: grid;
  grid-row: span 2;
  grid-template-rows: subgrid;
  gap: 7px;
}
.datos dt {
  font-family: var(--sora);
  font-size: 10.5px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-faint);
}
.datos dd {
  font-family: var(--sora);
  font-size: clamp(1.4rem, 2.4vw, 1.85rem);
  font-weight: 400; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}

.boton {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 13px 22px; border-radius: 11px;
  background: var(--acento); color: var(--void);
  font-size: .95rem; font-weight: 600; text-decoration: none;
  transition: filter .2s ease, transform .2s ease;
}
.boton:hover { filter: brightness(1.09); transform: translateY(-1px); }
.boton svg { width: 17px; height: 17px; }

/* La fila de botones de una ficha. Existe desde que hay dos: el que lleva al
   producto y el que lleva a su documento legal. */
.app__botones { display: flex; gap: 11px; flex-wrap: wrap; align-items: center; }

/* El legal es el segundo botón y tiene que parecerlo. Dos botones con el mismo
   peso no dicen a dónde ir primero, y la política de privacidad, por obligatoria
   que sea, no es la razón por la que alguien llega a la ficha. */
.boton--tenue {
  background: transparent;
  color: var(--ink-soft);
  border: 1px solid var(--linea-viva);
  font-weight: 500;
}
.boton--tenue:hover { color: var(--ink); border-color: var(--acento); filter: none; }

.apps__vacio {
  color: var(--ink-faint);
  font-size: .95rem;
  border-left: 2px solid var(--linea-viva);
  padding-left: 17px;
  max-width: 56ch;
}

/* ------------------------------------------------------------
   Contacto
   ------------------------------------------------------------ */
.contacto {
  padding-top: clamp(80px, 11vh, 140px);
  padding-bottom: clamp(90px, 13vh, 160px);
  display: flex; flex-direction: column; gap: 18px; align-items: flex-start;
  border-top: 1px solid var(--linea);
}
.contacto__lede { color: var(--ink-soft); max-width: 48ch; }
.contacto__mail {
  margin-top: 10px;
  font-family: var(--sora);
  font-size: clamp(1.3rem, 3.4vw, 2.1rem);
  font-weight: 400; letter-spacing: -.025em;
  color: var(--acento-ap); text-decoration: none;
  border-bottom: 1px solid var(--linea-viva);
  padding-bottom: 5px;
  transition: border-color .25s ease;
}
.contacto__mail:hover { border-bottom-color: var(--acento); }

/* ------------------------------------------------------------
   Pie
   ------------------------------------------------------------ */
.pie {
  max-width: var(--canal);
  margin: 0 auto;
  padding: 30px var(--margen) 44px;
  border-top: 1px solid var(--linea);
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px 32px;
}
.pie__marca { font-family: var(--sora); font-size: .98rem; font-weight: 500; letter-spacing: -.01em; }
.pie__enlaces { list-style: none; display: flex; flex-wrap: wrap; gap: 8px 24px; margin-right: auto; }
.pie__enlaces a { font-size: .9rem; color: var(--ink-soft); text-decoration: none; transition: color .2s ease; }
.pie__enlaces a:hover { color: var(--ink); }
.pie__legal {
  font-family: var(--sora);
  font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-faint);
}

/* ------------------------------------------------------------
   Anchos estrechos
   ------------------------------------------------------------ */
@media (max-width: 900px) {
  .raiz { grid-template-columns: 1fr; }
  .fichas { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
  .datos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sobre { min-height: 0; padding-top: 84px; padding-bottom: 84px; }
}

/* La barra es lo primero que se rompe al estrechar, y la lección ya está
   aprendida en esforia.app: lo que no puede pasar es que se quede vacía. Se
   va el nombre junto al glifo, y se va el código de idioma — el globo por sí
   solo ya dice qué hace ese botón. Los tres destinos no se tocan. */
@media (max-width: 640px) {
  .nav { gap: 8px; }
  .nav__word { display: none; }
  .nav__links { gap: 0; }
  .nav__links a { padding: 8px 9px; font-size: .86rem; }
  .lang__btn { padding: 7px 9px; }
  .lang__codigo { display: none; }
}

/* Por debajo de 375px la barra no cabía: a 320 el botón del idioma terminaba
   44px fuera de la pantalla, y a 360 todavía 4. De esos, 116 se los llevaba
   "Sobre nosotros" él solo, así que pasa a "Nosotros" y el resto se aprieta.
   Los tres destinos y el idioma se quedan — una barra que pierde botones al
   estrechar es justo el fallo que hubo que arreglar en esforia.app. */
@media (max-width: 400px) {
  /* Dos retratos de 4:5 en paralelo por debajo de 400px dejan cada cara en
     unos 160px de ancho. Se apilan. */
  .fichas { grid-template-columns: 1fr; }
  .nav { padding-inline: 16px; }
  .nav-largo { display: none; }
  .nav-corto { display: inline; }
  .nav__links a { padding: 8px 7px; font-size: .82rem; }
  .lang__btn { padding: 7px 7px; }
}

/* Móvil apaisado. Con 360px de alto, el inicio metía eyebrow, nombre, tagline
   y flecha en la misma pantalla y dejaba 14px entre las dos últimas: no
   llegaban a solaparse, pero se leía apelotonado.

   La condición lleva `orientation` además de la altura, y no un `max-height` a
   secas: un móvil vertical con el teclado abierto también es bajo, y ahí esta
   compresión no pinta nada. Es la misma trampa que ya documenta la app. */
@media (orientation: landscape) and (max-height: 540px) {
  .inicio { padding-top: calc(var(--alto-nav) + 10px); padding-bottom: 54px; }
  .inicio__eyebrow { margin-bottom: 12px; }
  .inicio__nombre { font-size: clamp(2.4rem, 8.5vw, 5rem); }
  .inicio__tagline { margin-top: 14px; font-size: 1rem; max-width: 46ch; }
  .inicio__cue { bottom: 14px; }
  .inicio__cue svg { width: 16px; height: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* El nombre aparece entero, la cascada no cae y el cursor no parpadea. Lo
     que se pierde es el efecto; lo que se lee es idéntico. */
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
  .inicio__tagline, .inicio__cue, .raiz__parte, .app, .marca-cierre, .ficha {
    opacity: 1 !important;
    transform: none !important;
  }
  .nombre__cursor { display: none; }
}

/* ============================================================
   La página legal de una app: /legal/<id>

   Un documento, no una sección de la web. Nadie llega aquí a pasearse: llega
   desde una ficha de Play o desde el botón de una ficha, a comprobar una cosa
   concreta. Así que ancho de lectura, títulos numerables y nada que se revele
   al pasar — todo el texto, desde el primer instante.
   ============================================================ */

.legal {
  max-width: 74ch;
  margin: 0 auto;
  padding: calc(var(--alto-nav) + 48px) var(--margen) 96px;
}

.legal__langs {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  margin-bottom: 30px;
  border: 1px solid var(--linea);
  border-radius: 11px;
  background: var(--sup);
}
.legal__lang {
  appearance: none; border: 0; background: transparent;
  color: var(--ink-soft); font: inherit; font-size: .85rem;
  padding: 7px 13px; border-radius: 8px; cursor: pointer;
  transition: background .18s ease, color .18s ease;
}
.legal__lang:hover { color: var(--ink); }
.legal__lang.is-on { background: var(--sup-2); color: var(--ink); font-weight: 600; }

.legal__eyebrow {
  font-size: .82rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-faint); margin-bottom: 10px;
}
.legal__title {
  font-family: var(--sora); font-weight: 600; letter-spacing: -.02em;
  font-size: clamp(1.7rem, 4vw, 2.4rem); line-height: 1.2;
  margin-bottom: 36px;
}

.legal__section { margin-bottom: 34px; }
.legal__section h2 {
  font-family: var(--sora); font-weight: 600; letter-spacing: -.01em;
  font-size: 1.16rem; line-height: 1.35;
  margin-bottom: 12px;
  /* La barra a la izquierda separa una sección de la siguiente sin una línea
     que cruce la página: en un documento largo, las reglas horizontales lo
     trocean y hacen perder el hilo. */
  padding-left: 15px;
  border-left: 2px solid var(--acento);
}
.legal__section p, .legal__section ul { padding-left: 17px; }
.legal p, .legal li { color: var(--ink-soft); }
.legal p + p, .legal ul { margin-top: 13px; }
.legal ul { padding-left: 34px; }
.legal li { margin-bottom: 7px; }

.legal__cargando { color: var(--ink-faint); }

.legal a { color: var(--acento-ap); }

/* En un móvil la barra de la izquierda se come el ancho de lectura, que es lo
   único que esta página tiene que proteger. */
@media (max-width: 560px) {
  .legal__section h2 { padding-left: 12px; }
  .legal__section p, .legal__section ul { padding-left: 0; }
  .legal ul { padding-left: 20px; }
}
