/* vietnamese */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/3578a2b6.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/12b53b2e.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, 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;
}
/* latin */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/e51539db.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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* vietnamese */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/3578a2b6.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/12b53b2e.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, 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;
}
/* latin */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/e51539db.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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* cyrillic-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/570a2bdd.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/71e69e06.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/3644d51c.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/c010f9b7.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/9ea68c62.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, 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;
}
/* latin */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/530d036b.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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/570a2bdd.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/71e69e06.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/3644d51c.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/c010f9b7.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/9ea68c62.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, 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;
}
/* latin */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/530d036b.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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


/* latin-ext */
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/assets/fonts/c4fcfea4.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, 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;
}
/* latin */
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/assets/fonts/2ee17598.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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url(/assets/fonts/c4fcfea4.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, 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;
}
/* latin */
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url(/assets/fonts/2ee17598.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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url(/assets/fonts/c4fcfea4.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, 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;
}
/* latin */
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url(/assets/fonts/2ee17598.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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


/* 4dim — sistema de diseño v1.0
   El color es notación, no decoración. Dos grosores de línea. Papel, no blanco. */

:root {
  --ink:        #0F1216;
  --paper:      #F2EFE7;
  --cobalt:     #1B44C8;
  --vermillion: #DE3F22;
  --graphite:   #5F5E5A;
  --ash:        #B4B2A9;
  /* Superficie elevada sobre papel. La guia la define desde la v1.0 y nunca
     se implemento: hasta ahora nada necesitaba levantarse del fondo sin
     recurrir a una sombra, que esta prohibida. Una burbuja de conversacion si. */
  --hueso:      #FAF8F3;
  /* Lo que exige atencion. Distinto del bermellon, que es lo oculto y el
     error: una persona esperando respuesta no es un fallo, y pintarla del
     color del fallo gasta el bermellon hasta que deja de significar. */
  --ocre:       #E0A032;

  --mono:  "Commit Mono", "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --serif: "Newsreader", "Source Serif 4", Georgia, "Times New Roman", serif;
  /* La grotesca del registro de producto. La guia la pide desde la v1.0 —«el
     laboratorio escribe en serif, el producto habla en grotesca»— y hasta ahora
     no estaba: la app entera leia en serif. Una consola que se opera ocho horas
     seguidas, con renglones cortos a 13-15px, no se lee en serif editorial.
     Instrument Sans es la primera opcion de la guia; Inter esta prohibida ahi
     por defecto del sector. El sitio publico NO la usa: sigue en serif. */
  --grot:  "Instrument Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --gap: clamp(1.5rem, 4vw, 4rem);
  --rail: clamp(3.25rem, 5vw, 4.75rem);

  /* Orden de apilamiento, declarado en un solo sitio para que las dos mitades
     lo lean igual. El raíl va por encima de cualquier columna que la app
     monte a su lado: su leyenda al señalar se dibuja sobre ella, y si empatan
     gana la que venga después en el DOM — que es la de la app. */
  --z-campo: 0;
  --z-contenido: 2;
  --z-columna-app: 3;
  --z-rail: 4;
  --rule: 0.5px;
}

/* Aqui vivia un bloque que copiaba la paleta oscura cuando el SISTEMA estaba en
   oscuro y nadie habia elegido tema. Se fue, y con el la causa de que el tono
   cambiara solo al navegar: bastaba un instante sin `data-theme` puesto —una
   pagina del sitio que no entendia el tema guardado— para que el navegador
   cayera aqui y pintara oscuro, y a la pagina siguiente volviera lo elegido.

   El claro es ahora el suelo: sin `data-theme` se ve claro, con JavaScript o
   sin el, tenga el sistema el tema que tenga. Lo oscuro existe porque alguien
   lo elige, no porque su portatil lo tenga puesto. */
:root[data-theme="dark"] {
  --ink:        #E8E4DA;
  --paper:      #0F1216;
  --cobalt:     #4A72E8;
  --vermillion: #F0684D;
  --graphite:   #9A978F;
  --ash:        #3A3F47;
  --hueso:      #191D23;
  --ocre:       #E8B75A;
}

/* ── temas extra (solo en la app Connection) ────────────────────────────────
   El sitio público solo conoce claro y oscuro, los de arriba. Este bloque
   define los cuatro extra del selector, todos bajo :root[data-app], que el
   sitio nunca pone: sus IDs se conocen pero no tienen efecto fuera de la app.

   Seis temas en total: tres tonos —cobalto, esmeralda, ámbar— en dos bases.
   La base clara hereda los tokens de :root y la oscura los de dark; entre
   temas de la misma base lo único que cambia es el acento (--cobalt). Eran
   doce y el número era parte del problema: doce acentos no se distinguen de
   un vistazo. Los seis retirados —vino, índigo, malva, cielo, lima, coral,
   lavanda— los reasigna main.js a su superviviente más cercano, así que a
   nadie se le queda un data-theme sin estilo. */

/* Acentos del lado claro: la base la heredan de :root, donde cobalto ya es el
   acento por defecto y no necesita regla. */
:root[data-app][data-theme="esmeralda"] { --cobalt: #1E8E5E; }
:root[data-app][data-theme="ambar"]     { --cobalt: #B27115; }

/* Lado oscuro: la base la comparten con dark (los tokens funcionales son los
   mismos que ya define :root[data-theme="dark"]); el acento se suma encima.
   Los dos acentos son los que la guía ya fija para oscuro —el verde sube a
   #3FB8A4 y el ámbar al mismo #E8B75A que ahí toma el ocre— porque los valores
   claros no contrastan sobre tinta. */
:root[data-app][data-theme="teal"],
:root[data-app][data-theme="miel"] {
  --ink:        #E8E4DA;
  --paper:      #0F1216;
  --vermillion: #F0684D;
  --graphite:   #9A978F;
  --ash:        #3A3F47;
  --hueso:      #191D23;
  --ocre:       #E8B75A;
}
:root[data-app][data-theme="teal"] { --cobalt: #3FB8A4; }
:root[data-app][data-theme="miel"] { --cobalt: #E8B75A; }

* { box-sizing: border-box; }

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

body {
  margin: 0;
  min-height: 100svh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Raíl. Es opaco a propósito: el campo llega a sangre hasta el borde y sin
   una franja de papel detrás cruzaría el logotipo y la línea de estructura.
   Va por encima del canvas; el dibujo queda debajo. */
.rail {
  position: fixed;
  inset: 0 auto 0 0;
  width: var(--rail);
  background: var(--paper);
  border-right: var(--rule) solid var(--ash);
  z-index: var(--z-rail);
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Poco aire arriba: el logotipo manda, no el margen. */
  padding: 1rem 0 1.35rem;
}

/* Las secciones se agrupan abajo; la marca queda arriba, y en medio —pegado a
   la marca— el hueco de las soluciones. Se reparte con un margen automático y
   no con space-between: con tres bloques, space-between habría plantado las
   soluciones en el centro exacto de la columna, lejos de donde se buscan. Así
   además el hueco puede estar vacío sin que nada se mueva. */
.rail__tools {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.35rem;
  margin-top: auto;
}
.rail__mark {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .7rem;
  color: var(--ink);
  text-decoration: none;
}
.rail__mark svg { width: 2.45rem; height: 2.45rem; display: block; }

/* Marca corta: en un raíl estrecho el logotipo se lee en vertical. */
.rail__word {
  font-family: var(--mono);
  font-size: .74rem;
  letter-spacing: .2em;
  color: var(--graphite);
  writing-mode: vertical-rl;
  transform: rotate(180deg);
}

/* Caja axonométrica abierta con un sólido saliendo. Nada de destellos:
   la guía los prohíbe por nombre. */
.rail__tool {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--graphite);
  text-decoration: none;
  transition: color 180ms ease-out;
}
.rail__ico svg { width: 1.75rem; height: 1.75rem; display: block; }
.rail__tool:hover, .rail__tool:focus-visible { color: var(--cobalt); }
.rail__tool:focus-visible { outline: none; }

/* El anillo. Un círculo de 0.5pt que se dibuja al señalar, empezando arriba y
   dando la vuelta: el gesto del compás, que es como se traza un círculo a mano.
   Antes eran dos escuadras de registro en las esquinas; el mismo recurso, en
   redondo, para que todos los iconos del raíl —incluido el de tu herramienta,
   que ya era un disco— se señalen igual.
   No es un efecto añadido: es una línea que se traza, que es exactamente lo que
   hace el resto del sistema. Sin resplandor, sin sombra, sin escala.
   `pathLength=100` normaliza el perímetro, así que el trazo se mide en
   porcentaje y no hay que calcular 2πr a mano. */
.rail__anillo {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 2.6rem;
  height: 2.6rem;
  transform: translate(-50%, -50%) rotate(-90deg);
  fill: none;
  stroke: currentColor;
  pointer-events: none;
  overflow: visible;
}
.rail__anillo circle {
  stroke-width: .5;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  transition: stroke-dashoffset 220ms ease-out;
}
.rail__tool:hover .rail__anillo circle,
.rail__tool:focus-visible .rail__anillo circle,
.rail__app:hover .rail__anillo circle,
.rail__app:focus-visible .rail__anillo circle { stroke-dashoffset: 0; }

/* La página actual lo lleva puesto: marca dónde estás sin necesidad de
   señalar, y por eso al pasar por encima no se dibuja nada — ya está trazado. */
.rail__tool[aria-current="page"] { color: var(--ink); }
.rail__tool[aria-current="page"] .rail__anillo circle,
.rail__app[aria-current="page"] .rail__anillo circle { stroke-dashoffset: 0; }

/* Etiqueta al señalar. Horizontal y fuera del raíl: en vertical el rótulo
   competía con el logotipo y ensuciaba la columna. */
.rail__tip {
  position: absolute;
  left: calc(100% + .85rem);
  white-space: nowrap;
  font-family: var(--mono);
  font-size: .72rem;
  color: var(--ink);
  background: var(--paper);
  padding: .3rem .5rem;
  border: var(--rule) solid var(--ash);
  opacity: 0;
  transform: translateX(-.25rem);
  pointer-events: none;
  transition: opacity 160ms ease-out, transform 160ms ease-out;
}
.rail__tool:hover .rail__tip,
.rail__tool:focus-visible .rail__tip { opacity: 1; transform: none; }

/* ── el raíl con la sesión abierta ─────────────────────────────────────────
   `data-sesion` en la raíz es la única señal, y de ella cuelgan los dos
   cambios. En la app la pone el servidor al montar el documento; en el sitio
   estático, el guion en línea del parcial del raíl, antes de que el navegador
   termine de leer la página. Que sea CSS y no JavaScript es lo que permite que
   las dos mitades acierten en el primer fotograma sin escribir la regla dos
   veces.

   Fuera el catálogo. Soluciones es la página de quien todavía está mirando qué
   se vende. Quien ya entró tiene su consola arriba, en el hueco de sus
   soluciones, y un catálogo en su raíl no es un atajo: es un sitio al que no
   va a volver ocupando la columna todos los días. */
:root[data-sesion] .rail__tool--catalogo { display: none; }

/* El último icono deja de ser una acción pendiente y pasa a ser un sitio. Se
   escriben los dos rótulos y se enseña uno: así los dos llevan su `data-es` y
   su `data-en` desde el HTML, y el cambio de idioma de main.js los alcanza a
   los dos sin saber nada de la sesión. */
.rail__rotulo--dentro { display: none; }
:root[data-sesion] .rail__rotulo--fuera { display: none; }
:root[data-sesion] .rail__rotulo--dentro { display: inline; }

/* ── las soluciones contratadas ────────────────────────────────────────────
   Viven en el raíl compartido y no en la hoja de la app: con sesión abierta el
   icono de tu herramienta se ve estés donde estés —también en el sitio, que es
   HTML estático y donde antes no aparecía nunca—. Un atajo que existe según la
   página no es un atajo.

   Sin soluciones el hueco no ocupa: el sitio lo sirve vacío en todas las
   páginas y solo se llena si /api/soluciones contesta que hay algo. */
.rail__apps {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .7rem;
  margin-top: 1.9rem;
}
.rail__apps:empty { display: none; }

.rail__app {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}

/* El disco. Mismo dibujo que los iconos de abajo, otro soporte: allí el trazo
   va suelto sobre el papel, aquí sobre tinta maciza. Como se pinta con --ink
   sobre --paper y los dos tokens se invierten con el tema, en claro es una
   bolita negra y en oscuro una clara: siempre el contrario del fondo, que es lo
   que lo hace saltar sin encender un color. */
.rail__app-ico {
  display: grid;
  place-items: center;
  width: 2.15rem;
  height: 2.15rem;
  border-radius: 50%;
  background: var(--ink);
  color: var(--paper);
  transition: background 180ms ease-out;
}
.rail__app-ico svg { width: 1.2rem; height: 1.2rem; display: block; }

/* Una solución sin glifo propio cae en su inicial, en mono, dentro del mismo
   disco. Es el respaldo, no el caso normal. */
.rail__app-ico--letra {
  font-family: var(--mono);
  font-size: .95rem;
  line-height: 1;
}

.rail__app:hover .rail__app-ico,
.rail__app:focus-visible .rail__app-ico { background: var(--cobalt); }
.rail__app:focus-visible { outline: none; }

.rail__app .rail__tip { opacity: 0; transform: translateX(-.25rem); }
.rail__app:hover .rail__tip,
.rail__app:focus-visible .rail__tip { opacity: 1; transform: none; }

@media (max-width: 60rem) {
  .rail__app-ico { width: 1.95rem; height: 1.95rem; }
  .rail__app-ico svg { width: 1.1rem; height: 1.1rem; }
}

/* ── cabecera ─────────────────────────────────────────────────────────────── */
.head {
  display: flex;
  align-items: baseline;
  /* Un solo hijo desde que el logotipo vive en el raíl: space-between lo
     mandaba al borde izquierdo. */
  justify-content: flex-end;
  gap: 1rem;
  padding: var(--gap) var(--gap) 0 calc(var(--rail) + var(--gap));
  position: relative;
  /* Al nivel del raíl, no al del contenido. La cabecera va en el flujo normal
     y nunca se solapa con nada por geometria, asi que subirla no tapa nada:
     lo que cambia es lo que cuelga de ella. Con --z-contenido empataba con
     .sheet, que viene despues en el DOM y por tanto ganaba, y el panel de
     temas —hijo de la cabecera, y por tanto atrapado en su contexto de
     apilamiento— se dibujaba por debajo de la lamina. El CRM ya la sube por su
     cuenta a 7; esto arregla las paginas que usan el cromo del sitio. */
  z-index: var(--z-rail);
}

.mark {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  text-decoration: none;
  color: inherit;
}
.mark__sym { width: 1.35rem; height: 1.35rem; color: var(--ink); flex: none; }
.mark__word {
  font-family: var(--mono);
  font-size: .95rem;
  letter-spacing: .01em;
  /* Alineación óptica: el símbolo se centra contra la altura de x. */
  transform: translateY(.04em);
}

.tools { display: flex; align-items: center; gap: .9rem; }

/* Marca de registro: mitad papel, mitad tinta. En el sitio gira media vuelta
   al cambiar de tema (claro/oscuro), como siempre lo hizo. En la app el boton
   abre el selector, asi que la rotacion binaria no aplica ahi. */
.theme {
  display: inline-flex;
  position: relative;
  padding: 0;
  border: 0;
  background: none;
  color: var(--graphite);
  cursor: pointer;
  transition: color 180ms ease-out, transform 320ms ease-out;
}
.theme svg { width: .82rem; height: .82rem; display: block; }
.theme:hover { color: var(--ink); }
.theme:focus-visible { outline: var(--rule) solid var(--cobalt); outline-offset: 4px; }

/* Sitio: toggle binario — rotacion media vuelta al tema oscuro. Una sola regla:
   antes habia otra que giraba el icono segun el tema del SISTEMA, y con el
   claro de suelo eso dejaba el boton al reves de lo que se veia en pantalla. */
:root:not([data-app])[data-theme="dark"] .theme { transform: rotate(180deg); }

/* App: el boton abre el panel. No gira —la media vuelta significa "cambiaste
   de tema" y aqui abrir no cambia nada—; solo sube a tinta mientras esta
   abierto, como cualquier control activo. */
:root[data-app] .theme[aria-expanded="true"] { color: var(--ink); }

/* El envoltorio ancla el panel. En el sitio estatico no hay panel y no hace
   nada; el hueco existe igual para que las dos mitades compartan markup. */
.theme-wrap { position: relative; display: inline-flex; }

/* ── selector de tema (solo en la app) ───────────────────────────────────────
   Un cuadro que baja del boton con las seis fichas y nada mas: tres tonos
   claros arriba, los mismos tres oscuros debajo.

   La ficha dice sola de que va el tema: el relleno es su base —papel o tinta—
   y el borde, su acento. Por eso no hace falta rotular las filas: la de arriba
   se ve clara y la de abajo oscura, que es exactamente lo que decian «claro» y
   «oscuro» cuando estaban escritos. El nombre completo sigue existiendo en el
   rotulo del navegador y en el del lector de pantalla.

   Sin texto, el cuadro se encoge a lo que miden las fichas: 88x62, contra los
   229x245 de la version con nombres. Es lo mas pequeño que puede ser sin que
   las fichas dejen de tocarse comodamente — 20px de lado, por encima del
   minimo de superficie tactil una vez se cuenta el hueco entre ellas.

   Antes eran doce iconos flotando en dos arcos alrededor del boton, entrando
   escalonados y cabeceando. Se cambio por tres razones, y las tres estan en la
   guia: el movimiento decorativo escalonado y el rebote no entran (seccion
   10), los elementos sueltos flotando en el vacio tampoco (seccion 8), y doce
   acentos no se distinguen de un vistazo — se prueban uno a uno.

   Dos grosores, como manda la seccion 8: 0.5pt para la estructura —el borde
   del cuadro y los anillos de rozar y de foco— y 1.5pt para el borde de las
   fichas, que es el sujeto. Superficie en hueso, que es exactamente el papel
   elevado que la guia define para levantar algo del fondo sin recurrir a una
   sombra. */
:root[data-app] .theme-panel {
  position: absolute;
  top: calc(100% + .7rem);
  right: 0;
  z-index: var(--z-rail);
  width: max-content;
  padding: .5rem;
  background: var(--hueso);
  border: var(--rule) solid var(--ash);
  border-radius: 5px;
  display: grid;
  gap: .35rem;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-.3rem);
  /* Funcional e invisible: 170ms ease-out y un cuarto de renglon de recorrido.
     La visibilidad espera a que termine el desvanecido al cerrar, y no espera
     nada al abrir. */
  transition: opacity 170ms ease-out, transform 170ms ease-out,
              visibility 0s linear 170ms;
}
:root[data-app] .theme-panel[data-open="true"] {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 170ms ease-out, transform 170ms ease-out;
}

/* El hueco entre fichas tiene que dar de si para los anillos: el de lo puesto
   sale 1.5px a 2px del borde, asi que dos vecinas gastan 7px de los 8. */
:root[data-app] .theme-fila { display: flex; gap: .5rem; }

:root[data-app] .theme-op {
  display: block;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
}

/* La ficha es la marca de registro del sitio, la misma del boton que abre
   esto: el circulo es el papel del tema y la media luna su acento. Los dos
   colores llegan en linea desde main.js porque describen el tema que se
   ofrece, no el que hay puesto ahora mismo. */
:root[data-app] .theme-chip {
  display: block;
  width: 1.25rem;
  height: 1.25rem;
}
:root[data-app] .theme-chip circle {
  fill: var(--ficha, var(--paper));
  stroke: var(--acento, var(--cobalt));
  stroke-width: 1;
}
:root[data-app] .theme-chip path { fill: var(--acento, var(--cobalt)); }

/* Tres anillos, de menos a mas mandon; solo se ve uno porque `outline` es una
   sola propiedad y gana la ultima regla que case. Rozar es de estructura
   (0.5pt ceniza); lo puesto lleva el trazo de sujeto (1.5pt) en su propio
   acento, que es lo unico permanente y por eso lo mas fuerte; el foco de
   teclado manda sobre los dos, que para eso es el unico que se pide. */
:root[data-app] .theme-op:hover {
  outline: var(--rule) solid var(--ash);
  outline-offset: 2px;
}
:root[data-app] .theme-op[aria-checked="true"] {
  outline: 1.5px solid var(--acento, var(--cobalt));
  outline-offset: 2px;
}
:root[data-app] .theme-op:focus-visible {
  outline: var(--rule) solid var(--cobalt);
  outline-offset: 3px;
}

/* Banderitas. La medida y el filo se declaran una vez aquí porque las usan las
   dos mitades: el conmutador de idioma —que es cromo compartido con el sitio— y
   el teléfono del contacto dentro de la consola. El filo tenue no es adorno:
   sin él, las que llevan blanco en el borde se derraman sobre el papel. */
.bandera {
  width: 1.15rem;
  height: auto;
  display: block;
  border-radius: 1.5px;
  flex: none;
}

.lang { display: flex; align-items: center; gap: .4rem; }
.lang button {
  background: none;
  border: 0;
  padding: 0;
  line-height: 0;
  border-radius: 2px;
  cursor: pointer;
  /* El idioma que no está puesto se apaga en vez de desaparecer: tiene que
     seguir viéndose para poder elegirlo, pero sin competir con el activo.
     Bajar opacidad y saturación a la vez —y no solo una— es lo que separa las
     dos banderas de un vistazo; con solo opacidad, dos rectángulos de colores
     al mismo tamaño se leen como uno doble. */
  opacity: .4;
  filter: saturate(.45);
  transition: opacity 160ms ease-out, filter 160ms ease-out;
}
.lang button[aria-pressed="true"] { opacity: 1; filter: none; }
.lang button:hover { opacity: 1; filter: none; }
.lang button:focus-visible { outline: var(--rule) solid var(--cobalt); outline-offset: 3px; }

/* ── lámina ───────────────────────────────────────────────────────────────── */
.sheet {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1fr;
  align-content: center;
  gap: var(--gap);
  padding: var(--gap) var(--gap) var(--gap) calc(var(--rail) + var(--gap));
  min-height: 0;
}


/* A sangre y detras de todo. Una figura que cabe en su caja se lee como
   ilustracion; esta se sale por los bordes y es el entorno de la pagina. */
.field {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

/* ── declaración ──────────────────────────────────────────────────────────── */
.say { max-width: 34ch; display: grid; gap: .85rem; }
.say__lead {
  margin: 0;
  position: relative;
  font-size: clamp(1.25rem, 2.4vw, 1.7rem);
  line-height: 1.34;
  text-wrap: balance;
}
.say__sub { margin: 0; font-size: .95rem; color: var(--graphite); max-width: 40ch; }

/* Un solo estilo de botón en todo el sistema: el de .btn. Definir aquí una
   variante propia habría creado dos definiciones que se separan con el tiempo. */
.say__go { margin: .9rem 0 0; }

/* ── pie ──────────────────────────────────────────────────────────────────── */
.foot {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: flex-end;
  gap: 1rem;
  padding: 0 var(--gap) var(--gap) calc(var(--rail) + var(--gap));
  font-family: var(--mono);
  font-size: .72rem;
  color: var(--graphite);
}
.foot__mail { color: var(--graphite); text-decoration: none; border-bottom: var(--rule) solid var(--ash); }
.foot__mail:hover { color: var(--cobalt); border-color: var(--cobalt); }

/* ── composición ancha: lámina y texto conviven, sin héroe ────────────────── */
@media (min-width: 60rem) {
  .sheet {
    grid-template-columns: minmax(0, 1.4fr) minmax(20rem, .8fr);
    align-items: center;
    gap: calc(var(--gap) * 1.15);
  }
  .say { align-self: center; grid-column: 2; }
  .sheet--page { grid-template-columns: minmax(0, 1fr); }
}

/* En pantalla estrecha el texto ocupa todo el ancho y cae sobre el campo.
   Bajando la opacidad del canvas entero, el acento bermellón —que es lo que
   mas estorba— baja en la misma proporción. */
@media (max-width: 48rem) {
  .field { opacity: .42; }
}

/* El raíl tiene sitio de sobra también en el teléfono: la marca vertical se
   queda. Solo se reduce el símbolo para que no roce los bordes. */
@media (max-width: 34rem) {
  .rail__mark svg { width: 1.95rem; height: 1.95rem; }
  .rail__word { font-size: .7rem; letter-spacing: .16em; }
}

/* ── página interior ──────────────────────────────────────────────────────
   Aquí el campo acompaña y manda el contenido: una sola columna editorial,
   alineada a la retícula, con medida de lectura de 65-75 caracteres. */
.sheet--page {
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  padding-top: calc(var(--gap) * 1.6);
  gap: calc(var(--gap) * .9);
}

.page__head { display: grid; gap: .5rem; max-width: 42ch; }
.page__eyebrow {
  margin: 0;
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .04em;
  color: var(--graphite);
}
.page__title {
  margin: 0;
  font-weight: 400;
  font-size: clamp(1.9rem, 4.4vw, 3rem);
  line-height: 1.12;
  letter-spacing: -0.01em;
}

/* Medida de lectura. No se negocia: la legibilidad larga es activo de marca. */
.prose { max-width: 68ch; display: grid; gap: 1.1rem; }
.prose p { margin: 0; }
.prose h2 {
  margin: 1.4rem 0 0;
  font-weight: 400;
  font-size: 1.25rem;
  line-height: 1.3;
}
.prose h3 {
  margin: 1rem 0 0;
  font-family: var(--mono);
  font-weight: 400;
  font-size: .8rem;
  letter-spacing: .05em;
  color: var(--graphite);
}
.prose a { color: var(--cobalt); text-decoration: none; border-bottom: var(--rule) solid currentColor; }
.prose ul { margin: 0; padding-left: 1.1rem; display: grid; gap: .4rem; }
.prose table { border-collapse: collapse; font-variant-numeric: tabular-nums; width: 100%; }
.prose th, .prose td { text-align: left; padding: .45rem .6rem .45rem 0; border-bottom: var(--rule) solid var(--ash); }
.prose th { font-family: var(--mono); font-weight: 400; font-size: .74rem; color: var(--graphite); }

.page__note { color: var(--graphite); }

/* ── formulario (registro de producto) ────────────────────────────────────
   Grotesca no: aquí seguimos en el laboratorio. Bordes de 0.5pt en ceniza,
   radio 6px y transiciones de 150-200ms, como pide la guía. */
.auth { display: grid; gap: 1.1rem; max-width: 26rem; margin-top: .6rem; }
.field-row { display: grid; gap: .4rem; }
.field-row__label {
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .04em;
  color: var(--graphite);
}
.input {
  font: inherit;
  font-size: .95rem;
  color: var(--ink);
  background: var(--paper);
  border: var(--rule) solid var(--ash);
  border-radius: 6px;
  padding: .6rem .7rem;
  transition: border-color 160ms ease-out;
}
.input:hover { border-color: var(--graphite); }
.input:focus { outline: none; border-color: var(--cobalt); }
/* Tinta, no cobalto. El cobalto es notación —lo visible, la proyección— y
   gastarlo en un botón lo devalúa. En tinta el botón manda por contraste y el
   color sigue significando algo. Al señalarlo sí aparece cobalto: ahí el color
   marca la acción, que es cuando toca.

   Va con los tokens y no con el valor literal, así que en modo oscuro se
   invierte solo: tinta clara sobre papel oscuro, mismo contraste. */
.btn {
  justify-self: start;
  font-family: var(--mono);
  font-size: .8rem;
  letter-spacing: .04em;
  color: var(--paper);
  background: var(--ink);
  border: 0;
  border-radius: 6px;
  padding: .62rem 1.15rem;
  cursor: pointer;
  transition: background-color 170ms ease-out;
}
.btn:hover { background: var(--cobalt); }
.btn:focus-visible { outline: var(--rule) solid var(--ink); outline-offset: 3px; }
.auth__note { margin: 0; font-size: .84rem; color: var(--graphite); }

/* ── índice de proyectos ──────────────────────────────────────────────────
   Cada entrada trae su propia proyección del mismo objeto: es la tesis de la
   marca hecha estructura — lo que se vende es la sombra de lo que se investiga. */
.page__lead {
  margin: .4rem 0 0;
  max-width: 40ch;
  font-size: 1.05rem;
  color: var(--graphite);
}

.index {
  list-style: none;
  margin: calc(var(--gap) * .6) 0 0;
  padding: 0;
  max-width: 52rem;
  /* Filete superior: la retícula puede ser visible, es lenguaje. */
  border-top: var(--rule) solid var(--ash);
}
.index__item { border-bottom: var(--rule) solid var(--ash); }

.index__link {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.2rem);
  padding: 1.15rem .2rem;
  text-decoration: none;
  color: inherit;
  transition: background-color 170ms ease-out;
}
.index__link:hover { background: color-mix(in srgb, var(--ash) 16%, transparent); }
.index__link:focus-visible { outline: var(--rule) solid var(--cobalt); outline-offset: 2px; }

.index__plate {
  display: block;
  width: clamp(84px, 10vw, 116px);
  aspect-ratio: 1;
  flex: none;
}

.index__body { display: grid; gap: .18rem; min-width: 0; }
.index__endorse {
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .04em;
  color: var(--graphite);
}
.index__name { font-size: 1.35rem; line-height: 1.2; }
.index__desc { font-size: .92rem; color: var(--graphite); }

/* Numeración de figura: refuerza el registro de publicación. */
.index__meta {
  font-family: var(--mono);
  font-size: .72rem;
  color: var(--ash);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 34rem) {
  .index__link { grid-template-columns: auto minmax(0, 1fr); gap: 1rem; }
  .index__meta { display: none; }
}

.page__back { margin: calc(var(--gap) * .8) 0 0; font-family: var(--mono); font-size: .78rem; }
.page__back a { color: var(--graphite); text-decoration: none; }
.page__back a:hover { color: var(--cobalt); }


/* ── Connection ───────────────────────────────────────────────────────────
   Registro de producto: más aire y jerarquía clara, pero la misma paleta, la
   misma tipografía y los mismos dos grosores. La guía permite al producto
   hablar más claro; no le permite cambiar de casa.

   La composición es de cuaderno de laboratorio: una columna de lectura con
   medida controlada y un margen ancho que aloja la numeración y el número de
   figura. Sin ese margen todo colgaba del mismo borde y la página era una pila
   de bloques sin jerarquía.

   Estas reglas las comparte world.html, que reutiliza las filas sin declarar
   --margen: allí la columna del margen no existe y el número cae encima del
   titular, que es lo que esa página quiere. Por eso las medidas van en
   variables y no escritas a mano en cada regla.

   Este bloque estaba duplicado —dos versiones seguidas, la segunda un borrador
   anterior que ganaba por orden de cascada— y la página se servía con la peor
   de las dos: sin la columna de margen efectiva, sin filetes en las preguntas
   y con la lámina sin líneas de corte. */
.conn {
  gap: 0;
  max-width: 74rem;
  --margen: clamp(0px, 7vw, 5.5rem);
  --canal: clamp(0px, 2.5vw, 2rem);
  /* La medida de lectura, y por tanto dónde terminan los filetes. El ancho
     total (74rem) lo usa solo la lámina: ese contraste —columna estrecha,
     plancha ancha— es la composición del cuaderno. Con el texto ocupando todo
     el ancho los filetes corrían el doble que la línea que subrayaban. */
  --medida: 34rem;
}

/* Cada movimiento es una fila de dos columnas: margen y contenido. */
.conn__sec,
.conn .page__head {
  display: grid;
  grid-template-columns: var(--margen) minmax(0, var(--medida));
  column-gap: var(--canal);
  /* La plantilla interior limita la cabecera a 42ch; con la columna de margen
     encima el titular se partía en cinco líneas. La medida se controla en cada
     pieza, no en el contenedor. */
  max-width: none;
}
/* La lámina es la excepción: su fila usa el ancho entero. */
.conn__fig {
  display: grid;
  grid-template-columns: var(--margen) minmax(0, 1fr);
  column-gap: var(--canal);
  max-width: none;
}
.conn__sec > *,
.conn .page__head > *,
.conn__fig > * { grid-column: 2; }

.conn__num {
  grid-column: 1;
  grid-row: 1 / 3;
  margin: .35rem 0 0;
  font-family: var(--mono);
  font-size: .72rem;
  color: var(--ash);
  font-variant-numeric: tabular-nums;
  align-self: start;
}

/* Portada de la página. */
.conn__title { max-width: 17ch; }
.conn .page__lead { max-width: 46ch; font-size: 1.12rem; }

/* Nota al margen, aunque no quepa en el margen: la columna mide 5.5rem como
   mucho y dos renglones de prosa no entran ahí. Se queda en la columna de
   lectura y se distingue por la monoespaciada, que es la firma del sistema. */
.conn__nota {
  margin: 1.5rem 0 0;
  font-family: var(--mono);
  font-size: .74rem;
  line-height: 1.75;
  letter-spacing: .01em;
  color: var(--graphite);
  max-width: 46ch;
}

/* La lámina. Cruza también la columna del margen y se corta arriba y abajo con
   filete de 0.5pt: es una lámina de laboratorio, no una ilustración metida
   entre párrafos. El número de figura baja al margen, a la altura del pie. */
.conn__fig { margin: calc(var(--gap) * 1.5) 0 0; }
.conn__fig > .conn__canvas {
  grid-column: 1 / -1;
  display: block;
  width: 100%;
  height: clamp(190px, 30vw, 360px);
  border-top: var(--rule) solid var(--ash);
  border-bottom: var(--rule) solid var(--ash);
}
.conn__fignum {
  grid-column: 1;
  margin: .6rem 0 0;
  font-family: var(--mono);
  font-size: .72rem;
  color: var(--ash);
}
.conn__figcap {
  margin: .6rem 0 0;
  font-size: .88rem;
  line-height: 1.6;
  color: var(--graphite);
  max-width: 56ch;
}

/* El color como notación, dicho en el propio pie: el lector aprende a leer la
   lámina en la lámina. Peso normal — en negrita el color se convertiría en
   énfasis, que es justo lo que la guía no quiere que sea. */
.tinta { font-weight: 400; }
.tinta--cobalto { color: var(--cobalt); }
.tinta--bermellon { color: var(--vermillion); }

/* Ritmo vertical: mucho aire entre movimientos, poco dentro. Con el mismo
   hueco en los dos sitios la página se lee como una lista y no como un
   documento. */
.conn__sec { margin-top: calc(var(--gap) * 2.1); }
.conn__sec > h2 {
  margin: 0 0 1.1rem;
  font-weight: 400;
  font-size: clamp(1.45rem, 2.7vw, 2.05rem);
  line-height: 1.18;
  max-width: 24ch;
  letter-spacing: -0.005em;
}
.conn .prose { max-width: 58ch; }
.conn__punch {
  font-size: 1.12rem;
  color: var(--ink);
  border-left: 1.5px solid var(--cobalt);
  padding-left: .9rem;
}

/* Las tres afirmaciones. Filetes y numeración al margen: la misma retícula
   visible del resto, sin cajas ni fondos. Tres tarjetas habrían sido más
   llamativas y menos de esta casa. */
.conn__sec > .tres {
  grid-column: 1 / -1;
  list-style: none;
  margin: 0;
  padding: 0;
}
.tres li {
  display: grid;
  grid-template-columns: var(--margen) minmax(0, var(--medida));
  column-gap: var(--canal);
  padding: 1.5rem 0;
  border-top: var(--rule) solid var(--ash);
}
.tres li:last-child { border-bottom: var(--rule) solid var(--ash); }
.tres__n {
  grid-column: 1;
  grid-row: 1 / 3;
  margin: .3rem 0 0;
  font-family: var(--mono);
  font-size: .72rem;
  color: var(--ash);
  font-variant-numeric: tabular-nums;
  align-self: start;
}
.tres h2 {
  grid-column: 2;
  margin: 0;
  font-weight: 400;
  font-size: clamp(1.12rem, 1.9vw, 1.38rem);
  line-height: 1.25;
}
.tres li > p:not(.tres__n) {
  grid-column: 2;
  margin: .45rem 0 0;
  color: var(--graphite);
  font-size: .95rem;
}

.conn__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .9rem;
  margin: 1.6rem 0 0;
}
.btn--link { display: inline-block; text-decoration: none; }
.conn__cta-note { font-size: .88rem; color: var(--graphite); }

.conn__close {
  margin-top: calc(var(--gap) * 2.4);
  border-top: var(--rule) solid var(--ash);
  padding-top: calc(var(--gap) * 1.1);
}

/* Cifras. Tabulares porque son números, no texto. Hoy solo las usa Mundo. */
.figures {
  list-style: none;
  margin: 1.6rem 0 0;
  padding: 0;
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  background: var(--ash);
  border: var(--rule) solid var(--ash);
}
.figures li { background: var(--paper); padding: 1.15rem 1.2rem; display: grid; gap: .35rem; }
.figures b {
  font-family: var(--mono);
  font-weight: 400;
  font-size: 1.75rem;
  font-variant-numeric: tabular-nums;
  color: var(--cobalt);
  line-height: 1;
}
.figures span { font-size: .88rem; color: var(--graphite); }

/* En pantalla estrecha la columna del margen no da para alojar nada: 7vw son
   28px en un teléfono, donde «fig. 1» ya no cabe. Se colapsa a una columna y
   los rótulos se ponen encima de lo que numeran. */
@media (max-width: 48rem) {
  .conn { --margen: 0px; --canal: 0px; --medida: 1fr; }
  .conn__num,
  .conn__fignum { grid-column: 2; grid-row: auto; margin: 0 0 .3rem; }
  .conn__fignum { margin: .6rem 0 .2rem; }
  .conn__sec > h2 { max-width: none; }
  .tres__n { grid-row: auto; margin: 0 0 .35rem; }
  .tres li { grid-template-columns: minmax(0, 1fr); }
  .tres__n, .tres h2, .tres li > p:not(.tres__n) { grid-column: 1; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
