/* ══════════════════════════════════════════════════════════════════════════════════════════════════
   GoodNich · goodnich.io — LA HOJA DEL SITIO PÚBLICO DE LA PLATAFORMA.

   POR QUÉ VA APARTE Y NO EN LÍNEA. Es lo único pesado de la página, es IDÉNTICA en las dos lenguas y
   en las dos rutas (/ y /en/), y no cambia nunca entre visitas. Servida con su huella en la URL
   («/estilos.{huella}.css») se descarga UNA vez y se cachea un año como inmutable; en línea viajaría
   entera en cada página, en los dos idiomas, para siempre. El HTML sí se compone en cada petición —
   cambia con el idioma y con lo que el almacén público diga de la beta— y por eso se cachea aparte y
   corto.
   ══════════════════════════════════════════════════════════════════════════════════════════════════

   ── LAS TIPOGRAFÍAS SON NUESTRAS, Y SE SIRVEN DESDE NUESTRO ORIGEN ────────────────────────────────

   El diseño aprobado traía un «<link>» a fonts.googleapis.com. NO ENTRA, y no es una preferencia: es
   una petición a un TERCERO desde el navegador de quien nos visita —su IP en manos de Google antes de
   haber leído un titular— y este sitio no tiene banner de consentimiento ni va a tenerlo. Es la misma
   razón, escrita con las mismas palabras, por la que el reader auto-hospeda las suyas
   (apps/edge/src/reader/worker.ts, «FUENTES_PREFIJO») y por la que el panel sirve las suyas de /fonts
   (apps/dashboard/src/theme/fuentes.css). Aquí los .woff2 viajan DENTRO del worker.

   Son los subconjuntos «latin» oficiales de IBM Plex (OFL 1.1 — activos/fuentes/OFL.txt), con el mismo
   «unicode-range» que ya usa el panel. Newsreader es LITERALMENTE el fichero del panel: mismo byte,
   misma cara, y quien pase del sitio al panel no ve cambiar el texto de lectura. FRAUNCES, IGUAL: es el
   mismo fichero, y viaja aquí por una razón que no es tipográfica sino de marca — el logotipo se escribe
   con ella en el panel, y una marca que cambia de cara al cambiar de dominio deja de ser una marca. Lo
   vigila `tooling/ops/marca-una-sola.guard.test.ts`, que compara los dos ficheros byte a byte.

   Solo las variantes que esta hoja usa de verdad. Una cara de más son veinte kilobytes que nadie mira —
   Fraunces es la excepción que se paga a sabiendas: sesenta y siete kilobytes por UNA palabra, la única
   que tiene que ser idéntica en los dos sitios. Las URL las reescribe el worker con la huella de cada
   fichero: aquí van con su nombre a secas para que la hoja se pueda abrir tal cual en un navegador
   mientras se diseña. */

@font-face {
  font-family: 'Fraunces'; font-style: normal; font-weight: 400 900; font-display: swap;
  src: url(fuentes/fraunces.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;
}
@font-face {
  font-family: 'IBM Plex Sans Condensed'; font-style: normal; font-weight: 600; font-display: swap;
  src: url(fuentes/plex-cond-600.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;
}
@font-face {
  font-family: 'IBM Plex Sans Condensed'; font-style: normal; font-weight: 700; font-display: swap;
  src: url(fuentes/plex-cond-700.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;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap;
  src: url(fuentes/plex-mono-400.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;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500; font-display: swap;
  src: url(fuentes/plex-mono-500.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;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 600; font-display: swap;
  src: url(fuentes/plex-mono-600.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;
}
@font-face {
  font-family: 'Newsreader'; font-style: normal; font-weight: 300 500; font-display: swap;
  src: url(fuentes/newsreader.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;
}

/* ─────────────────────────── FICHA DE ESTILO ───────────────────────────
   LA PALETA ES LA DE LA CASA. Sale de apps/dashboard/src/theme/tokens.ts
   (Kanagawa Dragon: oscuro nativo, claro «sumi paper» derivado, cálido).
   Quien vea esta portada y luego entre en el panel tiene que reconocer los
   mismos colores diciendo LO MISMO. Por eso aquí no hay color de web:

     azul petróleo #3C6472 / #8BA4B0 ......... LA MARCA (accent)
     verde  #4E6440 / #8A9A7B ................ en marcha (success)
     ocre   #6E5716 / #C4B28A ................ esperando firma (warning)
     rojo   #9E3A33 / #C4746E ................ detenida, tema sensible (danger)
     papel  #EAE3D8 / #181616 ................ arena en claro, sumi en oscuro

   EL ÁMBAR HACÍA DOS TRABAJOS y por eso chirriaba: era la marca (botones,
   testigo, remates) Y el estado «esperando firma». Aquí van separados: la
   marca es el acento azul, la espera es el warning de la casa. Así la línea
   tiene TRES estados en TRES colores, con el significado que ya tienen dentro
   del producto.

   DOS FAMILIAS POR CADA ESTADO, y no es capricho: el tono liso (--espera)
   es RELLENO y BORDE (3:1, WCAG 1.4.11); el tono «-txt» es TEXTO sobre el
   papel o sobre su propio tinte (4.5:1). Mezclarlos es lo que deja una
   palabra ilegible dentro de su propia chapa.

   IBM Plex Sans Condensed (rótulo) · Newsreader (lectura) · IBM Plex Mono (dato)
   Fraunces (marca) — y SOLO la marca: no titula, no rotula, no se usa en ningún
   otro sitio de esta hoja. Es la cara del logotipo del panel, y está aquí para
   que la palabra «GoodNich» se escriba igual en los dos dominios.
   Diseño oscuro por defecto; el claro es el mismo instrumento con luz de día.
   ──────────────────────────────────────────────────────────────────── */

:root {
  color-scheme: dark;
  /* papeles: fondo < panel-alto (chasis) < panel (tarjeta); hueco = ranura */
  --fondo:      #181616;
  --panel:      #282727;
  --panel-alto: #1D1C19;
  --hueco:      #12100F;
  --linea:      #393733;
  --linea-alta: #54514B;
  /* el canto de un CONTROL: el único que llega a 3:1 contra los cuatro papeles */
  --borde-control: #847F77;
  --texto:      #C5C9C5;
  --texto-2:    #A6A69C;
  --gris:       #8E948C;

  /* LA MARCA */
  --acento:      #8BA4B0;
  --acento-vivo: #A4B8C1;
  --foco:        #7FB4CA;
  --acento-fondo: rgba(139, 164, 176, .13);
  /* Un solo primer plano vale para los cuatro rellenos: en oscuro todos los
     tonos de estado son claros, en claro todos son oscuros. */
  --sobre-color: #12100F;

  /* LOS TRES ESTADOS DE LA LÍNEA */
  --vivo:        #8A9A7B;
  --vivo-txt:    #A3B48F;
  --vivo-fondo:  rgba(138, 154, 123, .13);
  --espera:      #C4B28A;
  --espera-txt:  #C4B28A;
  --espera-fondo: rgba(196, 178, 138, .13);
  --alto:        #C4746E;
  --alto-txt:    #E4938C;
  --alto-fondo:  rgba(196, 116, 110, .13);

  /* La rejilla va teñida de acento, no de texto: sobre papel cálido un gris
     neutro se ensucia y parece suciedad de pantalla en vez de papel pautado. */
  --rejilla:    rgba(139, 164, 176, .06);
  --sombra:     0 1px 0 rgba(0, 0, 0, .30), 0 16px 40px -20px rgba(0, 0, 0, .60);

  --rotulo:  "IBM Plex Sans Condensed", "Roboto Condensed", "Arial Narrow", Arial, sans-serif;
  --lectura: "Newsreader", Georgia, "Times New Roman", serif;
  --dato:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  /* La pila es la MISMA que «--display» del panel (apps/dashboard/src/theme/tokens.css), respaldo
     incluido: si Fraunces no llega, las dos marcas caen en Georgia a la vez y siguen siendo la misma. */
  --marca:   "Fraunces", Georgia, serif;
  /* ── EL LOGOTIPO: PESO, ESCALA Y PROPORCIÓN ─────────────────────────────────────────────────────
     Los MISMOS siete valores que el panel (apps/dashboard/src/theme/tokens.css, donde está escrito el
     porqué de cada uno) y con los mismos nombres. Son copias, como las tipografías y como el isotipo, y
     por el mismo motivo: este worker no tiene dependencias de espacio de trabajo a propósito. Que no se
     separen lo vigila `tooling/ops/marca-una-sola.guard.test.ts`.
     El resumen: el «Nich» pesa más que «Good» porque el acento contrasta menos contra el papel; la
     escala tiene DOS pasos —grande donde la marca es la cabecera, pequeña donde comparte barra con
     controles—; y el isotipo, el hueco y el interletraje van con el logotipo para que el bloque crezca de
     una pieza.
     Aquí solo se usa el paso PEQUEÑO, y AHORA EN TODAS LAS PANTALLAS: esta barra lleva la marca y dos
     controles, y en el móvil lo que cede es la llamada a la acción (se muda a la esquina, más abajo) en
     vez de la marca. Antes había un tercer control —el botón «Pedir entrar»— y para que cupiera la marca
     bajaba a 20px por debajo de 30rem; eso era un TERCER paso de escala que solo tenía este sitio, y era
     justo lo que el dueño veía comparando las dos pantallas en su móvil. */
  --marca-peso: 700;
  --marca-peso-acento: 900;
  --marca-grande: 40px;
  --marca-pequena: 26px;
  /* Ver `theme/tokens.css` del panel: es el alto de la TINTA, que iguala la altura de mayúscula. */
  --marca-iso: 0.735em;
  --marca-hueco: 0.3em;
  --marca-letra: -0.025em;

  --caja: 74rem;
  --aire: clamp(3.5rem, 9vw, 7rem);
}

/* El claro NO es el oscuro invertido: es el «sumi paper» de la casa, cálido. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --fondo:      #EAE3D8;
    --panel:      #FAF6EF;
    --panel-alto: #F2ECE4;
    --hueco:      #E0D8CA;
    --linea:      #CFC5B5;
    --linea-alta: #B3A891;
    --borde-control: #7E7462;
    --texto:      #3A3833;
    --texto-2:    #5C594F;
    --gris:       #635F56;
    --acento:      #3C6472;
    --acento-vivo: #2E4E59;
    --foco:        #2C5867;
    --acento-fondo: rgba(60, 100, 114, .10);
    --sobre-color: #FAF6EF;
    --vivo:        #4E6440;
    --vivo-txt:    #43583A;
    --vivo-fondo:  rgba(78, 100, 64, .10);
    --espera:      #6E5716;
    --espera-txt:  #5F4B12;
    --espera-fondo: rgba(110, 87, 22, .10);
    --alto:        #9E3A33;
    --alto-txt:    #8C312B;
    --alto-fondo:  rgba(158, 58, 51, .10);
    --rejilla:    rgba(60, 100, 114, .07);
    --sombra:     0 1px 0 rgba(58, 56, 51, .05), 0 14px 34px -20px rgba(58, 56, 51, .30);
  }
}
:root[data-theme="light"] {
  color-scheme: light;
  --fondo:      #EAE3D8;
  --panel:      #FAF6EF;
  --panel-alto: #F2ECE4;
  --hueco:      #E0D8CA;
  --linea:      #CFC5B5;
  --linea-alta: #B3A891;
  --borde-control: #7E7462;
  --texto:      #3A3833;
  --texto-2:    #5C594F;
  --gris:       #635F56;
  --acento:      #3C6472;
  --acento-vivo: #2E4E59;
  --foco:        #2C5867;
  --acento-fondo: rgba(60, 100, 114, .10);
  --sobre-color: #FAF6EF;
  --vivo:        #4E6440;
  --vivo-txt:    #43583A;
  --vivo-fondo:  rgba(78, 100, 64, .10);
  --espera:      #6E5716;
  --espera-txt:  #5F4B12;
  --espera-fondo: rgba(110, 87, 22, .10);
  --alto:        #9E3A33;
  --alto-txt:    #8C312B;
  --alto-fondo:  rgba(158, 58, 51, .10);
  --rejilla:    rgba(60, 100, 114, .07);
  --sombra:     0 1px 0 rgba(58, 56, 51, .05), 0 14px 34px -20px rgba(58, 56, 51, .30);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background-color: var(--fondo);
  background-image:
    linear-gradient(var(--rejilla) 1px, transparent 1px),
    linear-gradient(90deg, var(--rejilla) 1px, transparent 1px);
  background-size: 46px 46px;
  color: var(--texto);
  font-family: var(--lectura);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img, svg { max-width: 100%; }
/* Que la barra fija no tape el titular al saltar a una sección. */
section[id], main[id] { scroll-margin-top: 4.5rem; }

a { color: inherit; }
:focus-visible { outline: 2px solid var(--foco); outline-offset: 2px; }

.caja { width: min(100% - 2rem, var(--caja)); margin-inline: auto; }
@media (min-width: 48rem) { .caja { width: min(100% - 4rem, var(--caja)); } }

/* ───────────── tipografía ───────────── */
h1, h2, h3 { margin: 0; text-wrap: balance; }
h1 {
  font-family: var(--rotulo); font-weight: 700;
  font-size: clamp(2.35rem, 10.5vw, 5.2rem); line-height: .98; letter-spacing: -.025em;
  text-transform: uppercase;
}
h2 {
  font-family: var(--rotulo); font-weight: 700;
  font-size: clamp(1.7rem, 5.6vw, 2.9rem); line-height: 1.05; letter-spacing: -.02em;
  text-transform: uppercase;
}
h3 { font-family: var(--rotulo); font-weight: 600; font-size: 1.16rem; line-height: 1.22; letter-spacing: -.005em; }
p { margin: 0; }

.rotulo {
  font-family: var(--dato); font-size: .68rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--gris);
}
.entradilla { font-size: clamp(1.05rem, 3.4vw, 1.26rem); line-height: 1.55; color: var(--texto-2); max-width: 36em; }
.dato { font-family: var(--dato); font-size: .8rem; }

/* ───────────── barra superior ───────────── */
.barra {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--fondo) 90%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--linea);
}
/*
 * LA FILA ENVUELVE, y esa línea arregla algo que ya estaba roto antes de que la marca creciera. Entre
 * el logotipo y los tres controles hay más de trescientos píxeles que no se parten por ningún sitio, así
 * que por debajo de unos 340 px no caben en una fila — y sin `wrap` no se plegaban: se salían, y con
 * ellos la PÁGINA ENTERA. Medido en un móvil de 320 px, la portada se iba cuarenta píxeles por la
 * derecha: barra de desplazamiento horizontal en todo el documento y el botón medio fuera de pantalla.
 * Con `wrap`, cuando deja de caber, los controles bajan a una segunda línea y ya está.
 */
.barra__fila { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .8rem; padding: .6rem 0; }
/* ───────────── LA MARCA ─────────────
   ISOTIPO + LOGOTIPO, y los dos son los del panel. No es simetría: es que ésta es la primera página
   donde nos ve alguien que no nos conoce, y el panel es la segunda. Con dos marcas distintas, quien
   pasa de una a la otra no reconoce que ha llegado al mismo sitio.

   El isotipo se pinta EN LÍNEA (`ISOTIPO`, en `pagina.ts`) y no como `<img>`: así hereda el color de
   aquí —del token, no de un hexadecimal clavado dentro del SVG— y cambia solo con el tema. Un `<img>`
   con el fichero dentro sería una petición más y un color congelado.

   El isotipo y el hueco van en `em` a propósito: crecen y encogen con la palabra, así que el ajuste del
   móvil de más abajo es UNA línea —el paso de escala— y no tres que se descuadran entre sí. Es la misma
   regla que el panel, con los mismos dos números, y ahora también el mismo CUERPO: esta barra iba a
   1,42rem (22,7px) y la cabecera del panel a 26, o sea la misma marca a dos tamaños que nadie eligió. */
.marca {
  /* `baseline`: los dos filos de la «G» y los del isotipo tienen que caer en el mismo píxel, y centrar dos
     cajas las junta por la mitad, no por la tinta. El porqué entero está en el panel (`styles.css`) y en
     `--marca-iso`; aquí es la misma decisión, escrita otra vez porque el worker no importa hojas. */
  display: inline-flex; align-items: baseline; gap: var(--marca-hueco);
  font-family: var(--marca); font-weight: var(--marca-peso); font-size: var(--marca-pequena); line-height: 1;
  letter-spacing: var(--marca-letra); text-decoration: none; white-space: nowrap;
}
.marca b { font-weight: var(--marca-peso-acento); color: var(--acento); }
/* El hundido del 2,2 % es el rebose de la redonda: ver el comentario largo del panel. */
.marca__iso { height: var(--marca-iso); width: auto; flex: 0 0 auto; color: var(--acento); position: relative; top: calc(var(--marca-iso) * 0.022); }
.testigo {
  display: inline-flex; align-items: center; gap: .42rem;
  font-family: var(--dato); font-size: .62rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--gris); border: 1px solid var(--linea); padding: .22rem .5rem;
  white-space: nowrap;
}
.testigo::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--acento); box-shadow: 0 0 0 3px var(--acento-fondo);
}
.barra__acc { margin-left: auto; display: flex; align-items: center; gap: .45rem; }
/*
 * EN EL MÓVIL, LO QUE SE VA DE LA BARRA ES EL BOTÓN — Y NO EL TAMAÑO DE LA MARCA.
 *
 * EL SÍNTOMA. El dueño veía la marca del sitio más pequeña que la del panel comparándolas en su móvil a
 * 360 px, y las dos declaraban 20 px. Se midieron las dos renderizadas y salían IGUALES al subpíxel:
 * cuerpo 20 px, altura de mayúscula 15,00 px, anchura de tinta de la palabra 98,00 px e isotipo 16,39 px
 * en las dos. No era la letra: era LA COMPAÑÍA. La barra del panel gasta sus 200 px sobrantes en tres
 * mandos de icono, y ahí la marca es lo único grande y lo único con acento; la del sitio gastaba 125 en
 * un botón macizo del MISMO azul del logotipo — o sea que dentro de la barra el acento más grande dejaba
 * de ser la marca. La misma palabra, del mismo tamaño, al lado de otra cosa.
 *
 * LA CUENTA, medida a 360 px con el botón puesto: la marca no podía pasar de 20 px sin que la fila
 * envolviera y la barra saltara de 61 a 91 px de alto. Sin el botón, a 26 px la barra no crece ni un
 * píxel — y 26 es el paso pequeño de la escala, el mismo que el panel usa en escritorio, así que el
 * sitio deja de tener un TERCER tamaño de marca que no tenía nadie más.
 *
 * POR QUÉ SE VA EL BOTÓN Y NO OTRA COSA. Porque está repetido: la misma llamada, con el mismo destino,
 * vuelve a salir 440 px más abajo a pantalla completa, y otra vez al final en el formulario. En un móvil,
 * la marca merece esos 125 px más que la tercera copia de un botón. Y no desaparece: se muda a la esquina
 * («la puerta flotante», aquí debajo), así que sigue habiendo una llamada a la vista en cada punto del
 * recorrido — que era la condición para quitarla de aquí.
 *
 * En escritorio no cambia nada: por encima de 30 rem el botón sigue en la barra, donde sobra sitio.
 *
 * Y A 320 PX SIGUE SIN DESBORDARSE: con la marca a 26 la fila envuelve (para eso está el `wrap` de
 * arriba) y los controles bajan a una segunda línea, sin un solo píxel de desplazamiento horizontal.
 */
@media (max-width: 29.99rem) {
  .testigo { display: none; }
  .barra__fila { gap: .4rem .55rem; }
  .barra__acc { gap: .35rem; }
  .barra__acc .btn { display: none; }
  .btn { padding: .5rem .8rem; font-size: .86rem; }
}

.btn {
  font-family: var(--rotulo); font-weight: 600; font-size: .92rem;
  letter-spacing: .02em; text-transform: uppercase;
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .55rem 1rem; cursor: pointer; text-decoration: none;
  border: 1px solid var(--acento); background: var(--acento); color: var(--sobre-color);
  transition: background .15s ease, border-color .15s ease, transform .15s ease;
}
.btn:hover { background: var(--acento-vivo); border-color: var(--acento-vivo); transform: translateY(-1px); }
.btn--linea { background: transparent; color: var(--texto); border-color: var(--linea-alta); }
.btn--linea:hover { border-color: var(--texto); }
.btn--g { padding: .8rem 1.4rem; font-size: 1rem; width: 100%; }
@media (min-width: 34rem) { .btn--g { width: auto; } }
.btn[disabled] { opacity: .45; cursor: not-allowed; transform: none; }
.btn-tema {
  background: transparent; border: 1px solid var(--linea); color: var(--texto);
  width: 2rem; height: 2rem; display: grid; place-items: center; cursor: pointer;
  font-size: .8rem; padding: 0;
}

/*
 * ───────────── LA PUERTA FLOTANTE ─────────────
 *
 * La llamada a la acción que se va de la barra en el móvil, mudada a la esquina de abajo. NO es un adorno
 * ni una moda: es la CONDICIÓN de que el botón pueda salir de la barra. Medido a 360 px, la portada mide
 * 8.279 px de alto y solo tenía dos llamadas visibles por encima del formulario —la de la barra, que es
 * fija, y la grande de la portada, que se pierde de vista a los 543 px—; sin nada que la sustituyera,
 * quitar la de la barra dejaba 6.763 px de recorrido, el 82 % de la página, sin una sola forma de pedir
 * entrar a la vista.
 *
 * SE VE SIN JAVASCRIPT, y esto es lo que decide el sentido de la regla. El botón está VISIBLE de fábrica y
 * lo único que hace el guion es ESCONDERLO cuando el formulario ya está en pantalla —donde estorba y donde
 * la llamada la hace el propio formulario—. Al revés, escondido de fábrica y revelado por el guion, un
 * bloqueador o un fallo de red dejarían la página sin ninguna puerta: exactamente el fallo que este botón
 * existe para impedir. Aquí no vale «ante la duda, se esconde».
 *
 * Va con `.btn` y no es una pieza nueva: es el MISMO botón que estaba en la barra, con el mismo texto del
 * diccionario y el mismo destino. Lo suyo es la sombra —que lo despega del papel— y el sangrado seguro,
 * que lo aparta de la barra de gestos de los móviles sin marco.
 *
 * VA DESPUÉS DE `.btn` A PROPÓSITO: las dos reglas son de un solo nombre de clase, así que a igual peso
 * gana la última, y con este bloque más arriba el `display: inline-flex` de `.btn` le ganaba al
 * `display: none` y el botón salía flotando también en escritorio.
 */
.puerta-flotante {
  display: none;
  position: fixed; z-index: 40;
  right: max(.9rem, env(safe-area-inset-right)); bottom: max(.9rem, env(safe-area-inset-bottom));
  box-shadow: var(--sombra);
  transition: opacity .18s ease, transform .18s ease;
}
/* Solo donde la barra ha perdido su botón: el mismo corte, para que no haya dos llamadas ni ninguna. */
@media (max-width: 29.99rem) { .puerta-flotante { display: inline-flex; } }
/* Escondida cuando el formulario está a la vista; el atributo lo pone `consola.js` en la raíz. El retardo
   de `visibility` va AQUÍ y no en la regla base: la transición que manda es la del estado de DESTINO, así
   que puesta arriba el botón también tardaba 180 ms en volver a existir al reaparecer. */
[data-puerta="cerca"] .puerta-flotante {
  opacity: 0; visibility: hidden; transform: translateY(.4rem);
  transition: opacity .18s ease, transform .18s ease, visibility 0s linear .18s;
}
@media (prefers-reduced-motion: reduce) {
  .puerta-flotante, [data-puerta="cerca"] .puerta-flotante { transition: none; }
}

/* ───────────── portada ───────────── */
.portada { padding: clamp(2rem, 6vw, 3.6rem) 0 var(--aire); }
.portada__texto { display: grid; gap: 1.2rem; }
.portada h1 span { color: var(--acento); }
.portada__acc { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: .4rem; }
@media (max-width: 33.99rem) { .portada__acc { flex-direction: column; } }

/* ───────────── la línea ───────────── */
.consola {
  margin-top: clamp(2rem, 6vw, 3.2rem);
  border: 1px solid var(--linea-alta);
  background: var(--panel);
  box-shadow: var(--sombra);
  position: relative;
}
.consola::before, .consola::after {
  content: ""; position: absolute; width: 9px; height: 9px; border: 1px solid var(--acento);
  border-right: 0; border-bottom: 0; top: -1px; left: -1px;
}
.consola::after { left: auto; right: -1px; transform: scaleX(-1); }

.consola__cabeza {
  display: flex; flex-wrap: wrap; gap: .5rem .9rem; align-items: center;
  padding: .7rem .9rem; border-bottom: 1px solid var(--linea);
  background: var(--panel-alto);
}
.consola__titulo { font-family: var(--rotulo); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; font-size: .92rem; }
.estado {
  margin-left: auto; font-family: var(--dato); font-size: .7rem; letter-spacing: .1em;
  text-transform: uppercase; padding: .22rem .55rem; border: 1px solid currentColor;
}
.estado[data-e="listo"]   { color: var(--gris); }
.estado[data-e="marcha"]  { color: var(--vivo-txt);   background: var(--vivo-fondo); }
.estado[data-e="espera"]  { color: var(--espera-txt); background: var(--espera-fondo); }
.estado[data-e="alto"]    { color: var(--alto-txt);   background: var(--alto-fondo); }
.estado[data-e="vivo"]    { color: var(--vivo-txt);   background: var(--vivo-fondo); }

.via { position: relative; padding: 1.1rem .9rem 1.3rem; }

/* móvil: estaciones apiladas · escritorio: en fila */
.estaciones { display: grid; gap: .5rem; position: relative; }
@media (min-width: 60rem) { .estaciones { grid-template-columns: repeat(6, 1fr); gap: .55rem; } }

.est {
  border: 1px solid var(--linea); background: var(--fondo);
  padding: .6rem .7rem; display: grid; gap: .18rem;
  transition: border-color .3s ease, background .3s ease;
  position: relative; min-height: 4.4rem; align-content: start;
}
.est__n { font-family: var(--dato); font-size: .64rem; letter-spacing: .12em; color: var(--gris); }
.est__t { font-family: var(--rotulo); font-weight: 600; font-size: .95rem; line-height: 1.15; text-transform: uppercase; letter-spacing: .01em; }
.est__d { font-family: var(--dato); font-size: .68rem; color: var(--gris); line-height: 1.4; }
.est[data-act="1"] { border-color: var(--vivo); background: var(--vivo-fondo); }
.est[data-hecho="1"] .est__n { color: var(--vivo-txt); }
.est--puerta[data-act="1"] { border-color: var(--espera); background: var(--espera-fondo); }
.est--puerta[data-bloq="1"] { border-color: var(--alto); background: var(--alto-fondo); }

/* la compuerta dentro de la estación 05 */
.compuerta { position: relative; height: 10px; margin-top: .35rem; border: 1px solid var(--linea); overflow: hidden; }
.compuerta i {
  position: absolute; top: 0; bottom: 0; width: 50%;
  background: repeating-linear-gradient(45deg, var(--espera) 0 4px, transparent 4px 8px);
  transition: transform .45s cubic-bezier(.4,0,.2,1);
}
.est--puerta[data-bloq="1"] .compuerta i {
  background: repeating-linear-gradient(45deg, var(--alto) 0 4px, transparent 4px 8px);
}
.compuerta i:first-child { left: 0;  transform: translateX(-101%); }
.compuerta i:last-child  { right: 0; transform: translateX(101%); }
.est--puerta[data-cerrada="1"] .compuerta i { transform: translateX(0); }

/* la pieza que viaja */
.pieza {
  position: absolute; z-index: 3; pointer-events: none;
  width: 2.1rem; height: 2.1rem; display: grid; place-items: center;
  background: var(--texto); color: var(--fondo);
  font-family: var(--dato); font-size: .6rem; font-weight: 600;
  box-shadow: 0 0 0 4px var(--fondo), 0 0 22px -4px var(--acento);
  transition: transform .62s cubic-bezier(.45,.05,.2,1), background .3s ease, color .3s ease, box-shadow .3s ease;
  opacity: 0;
}
.pieza[data-vista="1"] { opacity: 1; }
.pieza[data-tipo="espera"] { background: var(--espera); color: var(--sobre-color); box-shadow: 0 0 0 4px var(--fondo), 0 0 22px -4px var(--espera); }
.pieza[data-tipo="alto"]   { background: var(--alto);   color: var(--sobre-color); box-shadow: 0 0 0 4px var(--fondo), 0 0 22px -4px var(--alto); }
.pieza[data-tipo="vivo"]   { background: var(--vivo);   color: var(--sobre-color); box-shadow: 0 0 0 4px var(--fondo), 0 0 22px -4px var(--vivo); }

.mandos__botones { display: flex; flex-wrap: wrap; gap: .5rem; }
.mandos__botones .btn { flex: 1 1 auto; }
@media (min-width: 44rem) { .mandos__botones .btn { flex: 0 0 auto; } }
.mandos {
  display: grid; gap: .7rem; padding: .9rem;
  border-top: 1px solid var(--linea); background: var(--panel-alto);
}
@media (min-width: 44rem) { .mandos { grid-template-columns: auto auto 1fr; align-items: center; gap: 1rem; } }
.conmutador { display: flex; align-items: center; gap: .55rem; cursor: pointer; font-family: var(--dato); font-size: .74rem; letter-spacing: .06em; text-transform: uppercase; color: var(--texto-2); }
.conmutador input { position: absolute; opacity: 0; width: 0; height: 0; }
.conmutador .pista {
  width: 2.4rem; height: 1.2rem; border: 1px solid var(--borde-control); position: relative; flex: none;
  background: var(--hueco); transition: background .2s ease, border-color .2s ease;
}
.conmutador .pista::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: calc(1.2rem - 6px); height: calc(1.2rem - 6px);
  background: var(--texto-2); transition: transform .2s ease, background .2s ease;
}
.conmutador input:checked + .pista { border-color: var(--alto); background: var(--alto-fondo); }
.conmutador input:checked + .pista::after { transform: translateX(1.2rem); background: var(--alto); }
.conmutador input:focus-visible + .pista { outline: 2px solid var(--foco); outline-offset: 2px; }

.aviso-linea {
  font-family: var(--dato); font-size: .74rem; line-height: 1.5; color: var(--texto-2);
  border-left: 2px solid var(--linea); padding-left: .7rem;
}
.aviso-linea b { color: var(--acento); font-weight: 600; }
.aviso-linea.espera { border-color: var(--espera); }
.aviso-linea.espera b { color: var(--espera-txt); }
.aviso-linea.alto { border-color: var(--alto); }
.aviso-linea.alto b { color: var(--alto-txt); }
.aviso-linea.vivo { border-color: var(--vivo); }
.aviso-linea.vivo b { color: var(--vivo-txt); }
.aviso-linea a { color: var(--acento); text-underline-offset: 2px; }

/* ───────────── secciones ───────────── */
.sec { padding: var(--aire) 0; border-top: 1px solid var(--linea); }
.sec__cabeza { display: grid; gap: .9rem; margin-bottom: clamp(1.8rem, 5vw, 2.8rem); }
@media (min-width: 56rem) { .sec__cabeza { grid-template-columns: minmax(0,1.4fr) minmax(0,1fr); gap: 3rem; align-items: end; } }

.tarjetas { display: grid; gap: .6rem; }
@media (min-width: 44rem) { .tarjetas { grid-template-columns: repeat(3, 1fr); } }
.tarjeta {
  border: 1px solid var(--linea); background: var(--panel); padding: 1.1rem;
  display: grid; gap: .45rem; align-content: start;
  transition: border-color .25s ease, transform .25s ease;
}
.tarjeta:hover { border-color: var(--linea-alta); transform: translateY(-2px); }
.tarjeta p { font-size: .95rem; color: var(--texto-2); }

/* reglas — lista de circuito */
.circuito { display: grid; gap: 0; border-top: 1px solid var(--linea-alta); }
.regla {
  display: grid; grid-template-columns: auto 1fr; gap: .5rem 1rem;
  padding: 1.2rem 0; border-bottom: 1px solid var(--linea); align-items: start;
}
@media (min-width: 52rem) { .regla { grid-template-columns: 2.2rem minmax(0,1fr) minmax(0,1.15fr); gap: 1.8rem; align-items: baseline; } }
.regla__ico { width: 1.5rem; height: 1.5rem; display: grid; place-items: center; border: 1px solid currentColor; color: var(--acento); font-family: var(--dato); font-size: .72rem; }
.regla__t { font-family: var(--rotulo); font-weight: 700; text-transform: uppercase; font-size: clamp(1.05rem, 3.8vw, 1.4rem); line-height: 1.12; letter-spacing: -.01em; }
.regla__d { grid-column: 2 / -1; color: var(--texto-2); font-size: .96rem; }
@media (min-width: 52rem) { .regla__d { grid-column: 3; } }

/* contrato */
.rechazos { display: grid; gap: .5rem; margin-top: 1.6rem; }
@media (min-width: 44rem) { .rechazos { grid-template-columns: repeat(3, 1fr); } }
.rechazo {
  border: 1px solid var(--alto); background: var(--alto-fondo);
  padding: .8rem .9rem; font-family: var(--dato); font-size: .76rem; line-height: 1.5; color: var(--texto);
}
.rechazo b { display: block; color: var(--alto-txt); letter-spacing: .1em; margin-bottom: .3rem; }

/* ───────────── la galerada: una pieza detenida, por dentro ─────────────
   Reutiliza a propósito el chasis de la consola (.consola__cabeza,
   .consola__titulo, .estado) para que se lea como el MISMO instrumento
   ampliado, no como otra tarjeta. El resto es oficio de corrector traducido
   a este idioma: el tachón en rojo de «detenida», la corrección con su
   calderón de inserción, tres notas ancladas al punto exacto del texto y un
   sello. El sello es lo único fuera de escuadra de toda la página: lo pone
   una persona, y por eso no está a plomo con la rejilla. */
.galerada {
  border: 1px solid var(--linea-alta); background: var(--panel);
  box-shadow: var(--sombra); position: relative;
  margin-bottom: clamp(2.4rem, 7vw, 3.8rem);
  scroll-margin-top: 5rem;
}
.galerada__meta {
  display: flex; flex-wrap: wrap; gap: .3rem 1.3rem;
  font-family: var(--dato); font-size: .66rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--texto-2);
  padding: .6rem clamp(.9rem, 3.4vw, 1.6rem);
  border-bottom: 1px solid var(--linea); background: var(--panel);
}
.galerada__meta b { color: var(--texto); font-weight: 500; }

.galerada__cuerpo { display: grid; }
@media (min-width: 62rem) {
  .galerada__cuerpo { grid-template-columns: minmax(0, 1fr) minmax(17rem, 25rem); }
  .galerada__margen { border-top: 0; border-left: 1px solid var(--linea); }
  .galerada__hoja { padding: 1.9rem 2.1rem 2.4rem; gap: 1rem; }
}
.galerada__hoja { padding: clamp(1rem, 3.6vw, 1.7rem); display: grid; gap: .85rem; align-content: start; }
.galerada__titular {
  font-family: var(--rotulo); font-weight: 700;
  font-size: clamp(1.16rem, 4.6vw, 1.52rem); line-height: 1.14; letter-spacing: -.01em;
  text-wrap: balance;
}
.galerada__texto {
  font-family: var(--lectura); font-size: clamp(1.02rem, 3.3vw, 1.14rem);
  line-height: 1.78; max-width: 34em; color: var(--texto);
}

/* las marcas del corrector */
.tachado {
  color: var(--texto-2);
  text-decoration: line-through; text-decoration-thickness: 2px;
  text-decoration-color: transparent;
  transition: text-decoration-color .45s ease .25s;
}
.galerada.visible .tachado { text-decoration-color: var(--alto); }
.insertado {
  border-bottom: 1px solid var(--alto); opacity: 0;
  transition: opacity .4s ease .6s;
}
.galerada.visible .insertado { opacity: 1; }
.insertado::before {
  content: "\2038"; color: var(--alto-txt); font-family: var(--dato);
  font-size: .78em; margin-right: .18em;
}
.marcado {
  background: var(--alto-fondo); box-shadow: 0 0 0 1px var(--alto) inset;
  padding: .04em .22em; -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
.fuente { border-bottom: 1px dashed var(--acento); }

/* el ancla en el texto y su gemela en el margen */
.ancla, .n-nota {
  font-family: var(--dato); font-weight: 600; font-variant-numeric: tabular-nums;
  border: 1px solid currentColor; line-height: 1.1; letter-spacing: 0;
}
.ancla {
  display: inline-block; vertical-align: .42em; font-size: .56rem;
  padding: .12em .34em; margin-left: .12em;
}
.n-nota {
  width: 1.4rem; height: 1.4rem; display: grid; place-items: center;
  font-size: .64rem; flex: none;
}
.ancla[data-g="alto"], .n-nota[data-g="alto"] { color: var(--alto-txt); background: var(--alto-fondo); }
.ancla[data-g="info"], .n-nota[data-g="info"] { color: var(--acento); background: var(--acento-fondo); }

/* la columna de margen */
.galerada__margen {
  padding: clamp(1rem, 3.6vw, 1.4rem); background: var(--panel-alto);
  border-top: 1px solid var(--linea);
}
.galerada__margen ol { list-style: none; margin: .75rem 0 0; padding: 0; display: grid; gap: .9rem; }
.galerada__margen li { display: grid; grid-template-columns: 1.4rem minmax(0, 1fr); gap: .7rem; align-items: start; }
.galerada__margen li > div { min-width: 0; }
.galerada__margen b {
  display: block; font-family: var(--dato); font-size: .66rem;
  letter-spacing: .11em; text-transform: uppercase; margin-bottom: .16rem; color: var(--texto);
}
.galerada__margen li p { font-size: .92rem; line-height: 1.5; color: var(--texto-2); }

/* el sello: lo único de la página que no está a plomo */
.galerada__pie {
  display: grid; gap: 1rem; align-items: center;
  padding: clamp(1rem, 3.6vw, 1.5rem); border-top: 1px solid var(--linea); background: var(--panel-alto);
}
@media (min-width: 46rem) { .galerada__pie { grid-template-columns: auto minmax(0, 1fr); gap: 1.5rem; } }
.sello {
  justify-self: start; display: inline-grid; gap: .16rem; text-align: center;
  border: 2px solid var(--alto); background: var(--alto-fondo); color: var(--alto-txt);
  box-shadow: inset 0 0 0 3px var(--panel-alto), inset 0 0 0 4px var(--alto);
  padding: .6rem 1.15rem;
  opacity: 0; transform: rotate(-1.5deg) scale(1.16);
  transition: opacity .28s ease .85s, transform .5s cubic-bezier(.2, 1.3, .5, 1) .85s;
}
.galerada.visible .sello { opacity: 1; transform: rotate(-1.5deg) scale(1); }
.sello__t { font-family: var(--rotulo); font-weight: 700; text-transform: uppercase; font-size: clamp(1rem, 4.2vw, 1.26rem); letter-spacing: .13em; line-height: 1; }
.sello__s { font-family: var(--dato); font-size: .58rem; letter-spacing: .17em; text-transform: uppercase; }
.galerada__pie p { font-family: var(--dato); font-size: .74rem; line-height: 1.55; color: var(--texto-2); max-width: 52em; }

/* subcabecera dentro de una sección */
.sub { display: grid; gap: .5rem; margin-bottom: clamp(1.1rem, 3.5vw, 1.6rem); }
.sub h3 { font-size: clamp(1.28rem, 4.6vw, 1.75rem); text-transform: uppercase; font-weight: 700; letter-spacing: -.012em; }
.sub p { color: var(--texto-2); font-size: .98rem; max-width: 46em; }

/* nicho */
.doble { display: grid; gap: .6rem; }
@media (min-width: 50rem) { .doble { grid-template-columns: 1fr 1fr; } }
.doble ul { margin: .2rem 0 0; padding-left: 1.05rem; display: grid; gap: .35rem; color: var(--texto-2); font-size: .94rem; }
.doble li::marker { color: var(--acento); }

/* salidas */
.salidas { display: grid; gap: .5rem; }
@media (min-width: 40rem) { .salidas { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .salidas { grid-template-columns: repeat(3, 1fr); } }
.salida {
  display: flex; gap: .7rem; align-items: baseline;
  border: 1px solid var(--linea); padding: .8rem .9rem; background: var(--panel);
}
.salida b { font-family: var(--dato); font-size: .66rem; letter-spacing: .12em; color: var(--gris); text-transform: uppercase; flex: none; }
.salida span { font-family: var(--rotulo); font-weight: 600; font-size: 1rem; }

/* expediente honesto */
.expediente { border: 1px solid var(--linea-alta); background: var(--panel); padding: clamp(1.1rem, 4vw, 1.9rem); display: grid; gap: .9rem; }
.hueco {
  border: 1px dashed var(--linea-alta); padding: 1rem; text-align: center;
  font-family: var(--dato); font-size: .74rem; color: var(--gris); letter-spacing: .06em;
}

/* solicitud */
.sol { display: grid; gap: clamp(1.8rem, 5vw, 3rem); }
@media (min-width: 60rem) { .sol { grid-template-columns: minmax(0,.9fr) minmax(0,1.1fr); gap: 3.4rem; } }
.pasos-lista { display: grid; gap: .8rem; margin: 0; padding: 0; list-style: none; counter-reset: p; }
.pasos-lista li { display: grid; grid-template-columns: 1.7rem 1fr; gap: .8rem; align-items: start; color: var(--texto-2); font-size: .95rem; }
.pasos-lista li::before {
  counter-increment: p; content: counter(p, decimal-leading-zero);
  font-family: var(--dato); font-size: .7rem; color: var(--acento);
  border: 1px solid var(--linea); width: 1.7rem; height: 1.7rem; display: grid; place-items: center;
}
form { display: grid; gap: .95rem; }
.campo { display: grid; gap: .3rem; }
.campo label { font-family: var(--dato); font-size: .68rem; letter-spacing: .13em; text-transform: uppercase; color: var(--gris); }
.campo input, .campo select, .campo textarea {
  font-family: var(--lectura); font-size: 1rem; color: var(--texto);
  background: var(--hueco); border: 1px solid var(--borde-control); padding: .68rem .75rem; width: 100%;
  transition: border-color .15s ease;
}
.campo :is(input, textarea)::placeholder { color: var(--texto-2); opacity: 1; }
.campo textarea { min-height: 6rem; resize: vertical; }
.campo :is(input, select, textarea):focus { border-color: var(--acento); }
.campo .ayuda { font-family: var(--dato); font-size: .7rem; color: var(--gris); }
.pareja { display: grid; gap: .95rem; }
@media (min-width: 34rem) { .pareja { grid-template-columns: 1fr 1fr; } }
.compromiso { display: flex; gap: .7rem; align-items: flex-start; border: 1px solid var(--acento); background: var(--acento-fondo); padding: .85rem; }
.compromiso input { margin: .25rem 0 0; width: 1rem; height: 1rem; accent-color: var(--acento); flex: none; }
.compromiso label { font-size: .9rem; line-height: 1.5; color: var(--texto); }
.acuse { display: none; border: 1px solid var(--vivo); background: var(--vivo-fondo); padding: 1rem; gap: .4rem; }
.acuse[data-visible="true"] { display: grid; }
.acuse b { font-family: var(--rotulo); text-transform: uppercase; color: var(--vivo-txt); font-size: 1.05rem; letter-spacing: .03em; }
.acuse p { font-size: .93rem; color: var(--texto-2); }

/* pie */
.pie { border-top: 1px solid var(--linea); padding: 2.2rem 0 3rem; color: var(--gris); font-family: var(--dato); font-size: .76rem; }
.pie__fila { display: grid; gap: 1rem; }
@media (min-width: 44rem) { .pie__fila { grid-template-columns: 1fr auto auto; align-items: end; } }
/* LOS ENLACES A NUESTRAS LEGALES. El rótulo de cada uno es el TÍTULO de la página, que se escribe en el
   panel: ahí cabe cualquier cosa, así que la caja tiene que poder partirlo (`anywhere`) en vez de estirar el
   documento. Es la misma regla que en el panel («un desconocido no puede descuadrar una pantalla nuestra
   escribiendo una palabra larga»), aplicada aquí por el mismo motivo aunque quien escriba seamos nosotros. */
.pie__legales { display: flex; flex-wrap: wrap; gap: .35rem 1rem; min-width: 0; }
.pie__legales a { overflow-wrap: anywhere; text-decoration: underline; text-underline-offset: .18em; text-decoration-color: var(--linea-alta); }
.pie__legales a:hover { color: var(--texto); text-decoration-color: currentColor; }

/* ───────────── el molde de un DOCUMENTO ─────────────
   Un texto largo dentro de la concha del sitio. Lo estrenaron las legales —cuyo cuerpo lo escribe una
   persona en el panel y llega como HTML saneado, así que aquí no se sabe qué etiquetas traerá y se estilan
   TODAS las que el saneador deja pasar— y hoy lo comparte la página del rastreador. Se llama «doc» y no
   «legal» justamente por eso: el molde no es de las legales, es de cualquier página nuestra que se lea
   despacio. Sin él, `p { margin: 0 }` (la regla de la portada, donde cada bloque pone su propio ritmo)
   dejaría el documento entero como un solo muro de texto — que es exactamente lo que nadie lee. */
.doc { padding: clamp(1.6rem, 5vw, 3rem) 0 var(--aire); }
.doc__cuerpo { max-width: 42em; overflow-wrap: break-word; }
/* El titular de un documento NO es el de la portada: aquel ocupa una pantalla a propósito, y aquí sería un
   grito delante de un texto que se lee despacio. Misma familia y mismas mayúsculas —sigue siendo esta
   casa—, otra escala. */
.doc__titulo { font-size: clamp(1.7rem, 6.5vw, 2.6rem); line-height: 1.04; }
.doc__entradilla { color: var(--gris); margin: .7rem 0 0; }
.doc__cuerpo > h2 { font-size: clamp(1.12rem, 4vw, 1.34rem); line-height: 1.2; margin: 2.2rem 0 .5rem; }
.doc__cuerpo > h3 { font-size: 1rem; text-transform: uppercase; letter-spacing: .03em; margin: 1.6rem 0 .4rem; }
.doc__cuerpo p { margin: 0 0 1em; color: var(--texto-2); }
.doc__cuerpo ul, .doc__cuerpo ol { margin: 0 0 1em; padding-left: 1.4em; color: var(--texto-2); }
.doc__cuerpo li { margin: 0 0 .35em; }
/* El navegador le da a `<b>` un `font-weight: bolder`, que sobre un padre a 700 calcula 900. Aquí el
   énfasis tiene que pesar lo mismo escríbase como se escriba. */
.doc__cuerpo b, .doc__cuerpo strong { font-weight: 700; color: var(--texto); }
.doc__cuerpo a { text-decoration: underline; text-underline-offset: .18em; text-decoration-color: var(--acento); }
.doc__cuerpo table { width: 100%; border-collapse: collapse; margin: 0 0 1em; font-size: .92rem; }
.doc__cuerpo th, .doc__cuerpo td { border: 1px solid var(--linea); padding: .45rem .6rem; text-align: left; vertical-align: top; }
.doc__volver { margin: 2.4rem 0 0; font-family: var(--dato); font-size: .8rem; }
.doc__volver a { text-decoration: underline; text-underline-offset: .18em; color: var(--acento); }

/* UN LITERAL QUE SE COPIA TAL CUAL: la cabecera del rastreador, dos líneas de robots.txt. Monoespaciado,
   porque lo que se lee aquí se compara carácter a carácter con un registro de servidor.

   `pre-wrap` Y NO `pre`, medido a 360 px: la cabecera son 363 px de línea y la caja da 326, así que con
   `pre` se salían 37 px por la derecha —dentro de su propio deslizamiento, sí, pero ESCONDIDOS: quien abre
   esta página en el móvil vería «…goodnich.io/b» y tendría que adivinar que aquello se arrastra—. Con
   `pre-wrap` los saltos de línea de verdad se conservan (las dos del `robots.txt` siguen siendo dos) y el
   resto se acomoda por los espacios que la cadena ya tiene. Al copiar sale lo mismo: el salto visual no
   viaja en el portapapeles.

   Lo que NO se hace es partir por dentro de una palabra (`overflow-wrap: anywhere`): un identificador
   partido por la mitad es OTRO identificador, y éste se pega en un fichero de configuración. Por eso queda
   el `overflow-x` propio de red de seguridad —un token sin un solo espacio no se puede acomodar—, y el
   `tabindex` del marcado para que esa red también se pueda recorrer con el teclado (WCAG 2.1.1). */
.doc__literal {
  font-family: var(--dato); font-size: .82rem; line-height: 1.6;
  background: var(--hueco); border: 1px solid var(--linea);
  color: var(--texto); margin: 0 0 1em; padding: .7rem .85rem;
  overflow-x: auto; white-space: pre-wrap;
}
.doc__literal:focus-visible { outline: 2px solid var(--foco); outline-offset: 2px; }

/* ENTRADAS. El «opacity: 0» cuelga de «[data-js="1"]» —la marca que pone el guion en línea del <head>—
   y no de «.rev» a secas. Sin esa condición, un navegador con JavaScript desactivado (o un guion que no
   llega a cargar) sirve la página ENTERA invisible: titulares, reglas y, lo que de verdad importa, el
   formulario. Colgado de la marca, si el guion no corre no hay nada que ocultar y todo se ve de una pieza.
   El resto de la animación no cambia. */
[data-js="1"] .rev { opacity: 0; transform: translateY(12px); }
.rev.visible { opacity: 1; transform: none; transition: opacity .6s ease, transform .6s cubic-bezier(.2,.7,.3,1); }
.rev.visible.d1 { transition-delay: .07s; }
.rev.visible.d2 { transition-delay: .14s; }
.rev.visible.d3 { transition-delay: .21s; }

@media (prefers-reduced-motion: reduce) {
  .rev, .rev.visible { opacity: 1; transform: none; transition: none; }
  .pieza { transition: opacity .1s linear; }
  .compuerta i { transition: none; }
  .btn:hover, .tarjeta:hover { transform: none; }
  .galerada .tachado, .galerada.visible .tachado { text-decoration-color: var(--alto); transition: none; }
  .galerada .insertado, .galerada.visible .insertado { opacity: 1; transition: none; }
  .galerada .sello, .galerada.visible .sello { opacity: 1; transform: rotate(-1.5deg); transition: none; }
}


/* ══════════════════════════════════════════════════════════════════════════════════════════════════════
   LO QUE AÑADE EL SITIO SERVIDO sobre la maqueta aprobada.

   La maqueta llevaba varios «style=» en línea y no llevaba ni salto de accesibilidad, ni conmutador de
   idioma, ni señuelo, ni acuse de error: son piezas que solo existen cuando la página la sirve un worker
   de verdad. Van todas aquí abajo, juntas y con su porqué, para que se vea de un vistazo qué es diseño
   aprobado (todo lo de arriba) y qué es consecuencia de servirlo (esto).
   ══════════════════════════════════════════════════════════════════════════════════════════════════════ */

/* Los titulares de sección llevaban «style="margin-top:.6rem"» repetido seis veces. Es la misma decisión
   seis veces, así que es una regla. */
.sec__cabeza h2 { margin-top: .6rem; }
.entradilla--sec { font-size: 1rem; }
.entradilla--exp { max-width: 46em; }
.expediente__t { font-size: clamp(1.2rem, 4vw, 1.6rem); }
.rotulo--acento { color: var(--acento); }
.nota-consola { color: var(--gris); margin-top: .9rem; }
.nota-ymyl { color: var(--gris); margin-top: 1.2rem; line-height: 1.6; }

/* SALTO AL CONTENIDO. Fuera de pantalla hasta que recibe el foco: quien navega con teclado no tiene por
   qué recorrer la barra en cada página, y quien no lo usa no lo ve nunca. */
.salta {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--acento); color: var(--sobre-color);
  font-family: var(--rotulo); font-weight: 600; text-transform: uppercase;
  padding: .6rem 1rem; text-decoration: none;
}
.salta:focus { left: .5rem; top: .5rem; }

/* EL CONMUTADOR DE IDIOMA. Un enlace, no un botón: lleva a otra URL, que es exactamente lo que hace un
   enlace, y por eso funciona con el clic del medio, con «abrir en otra pestaña» y sin JavaScript. */
.idioma {
  font-family: var(--dato); font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--texto-2); text-decoration: none; border: 1px solid var(--linea);
  padding: .38rem .55rem; white-space: nowrap;
}
.idioma:hover { border-color: var(--texto); color: var(--texto); }

/* EN EL MÓVIL, EL CÓDIGO DE LA LENGUA Y NO SU NOMBRE. A 360 px la barra lleva ya la marca, el conmutador de
   tema y la llamada a la acción; con «English» entero, la llamada se parte en dos líneas y la barra fija se
   come el doble de pantalla en todas las pantallas. El nombre completo sigue estando para quien usa un
   lector —va en el «aria-label» del enlace—, así que lo que se acorta es el dibujo, no la información. */
.idioma__corto { display: none; }
@media (max-width: 34rem) {
  .idioma__largo { display: none; }
  .idioma__corto { display: inline; }
  .idioma { padding: .38rem .5rem; letter-spacing: .06em; }
}

/* Y ningún botón se parte por la mitad: antes de romper una línea, que apriete el texto. */
.btn { white-space: nowrap; }

/* LO QUE SOLO SE DICE SI SE PUEDE CUMPLIR. La entradilla invita a probar la demostración de la portada;
   sin JavaScript no hay demostración, así que sin JavaScript tampoco hay invitación. Es la misma marca
   «[data-js]» que gobierna las entradas, aplicada a una frase en vez de a una animación — porque el
   criterio de esta web es que no se afirma lo que no se puede comprobar, y eso incluye «pruébalo aquí». */
.solo-con-js { display: none; }
[data-js="1"] .solo-con-js { display: inline; }

/* EL SEÑUELO. Fuera de la vista pero PRESENTE para quien no mira: un «display:none» o un «type=hidden»
   no lo rellenaría ningún robot, y entonces no distinguiría a nadie de nadie. La combinación de tamaño
   cero, «clip-path» y «!important» sobrevive a un autorrelleno que intente hacerlo visible. */
.senuelo {
  position: absolute !important; width: 1px !important; height: 1px !important;
  overflow: hidden !important; clip-path: inset(50%) !important;
  white-space: nowrap !important; border: 0 !important; padding: 0 !important; margin: -1px !important;
}

/* EL ACUSE, EN SUS TRES CARAS. El verde ya estaba (solicitud guardada); el rojo es el fallo del envío y
   el neutro es la nota de «esto todavía no está abierto», que no es ni una cosa ni la otra. */
.acuse--error { border-color: var(--alto); background: var(--alto-fondo); }
.acuse--error b { color: var(--alto-txt); }
.acuse--nota { border-color: var(--linea-alta); background: var(--panel-alto); }
.acuse--nota b { color: var(--texto); }
.acuse p:only-child { margin: 0; }

/* ══════════════════════════════════════════════════════════════════════════════════════════════════════
   EL TRAZO A MANO — COPIADO DEL PANEL, NO REESCRITO.

   Vive en `apps/dashboard/src/styles.css` (la clase «filete-a-mano») y aquí está tal cual: el mismo
   mosaico de 160×7, la misma máscara, el mismo «background-color: var(--accent)». Es autocontenido y solo
   depende de esa variable, así que lo único que hace falta es que el sitio la defina — y la define como
   alias de su propio acento, de modo que el trazo cambia con el tema sin una segunda copia del dibujo.

   Reescribirlo habría sido tener DOS firmas de la casa, parecidas y distintas, que es peor que no tener
   ninguna. El porqué de cada decisión del dibujo (mosaico y no SVG estirado, máscara y no relleno, sin
   costura, cinta rellena y no línea) está escrito una sola vez, allí, y no se repite aquí.

   UNO POR PÁGINA, igual que en el panel: cierra el titular de la portada y no aparece en ningún otro
   sitio. Un separador que se repite deja de ser una firma y pasa a ser un motivo decorativo.
   ══════════════════════════════════════════════════════════════════════════════════════════════════════ */
:root {
  --accent: var(--acento);
  --trazo-a-mano-ancho: 160px;
  --trazo-a-mano-alto: 7px;
  --trazo-a-mano: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='7' viewBox='0 0 160 7'%3E%3Cpath d='M0 2.58 C2.67 2.6 5.33 2.5 8 2.53 C10.67 2.56 13.33 2.66 16 2.74 C18.67 2.83 21.33 3 24 3.04 C26.67 3.08 29.33 2.99 32 2.99 C34.67 2.99 37.33 2.91 40 3.04 C42.67 3.16 45.33 3.52 48 3.74 C50.67 3.95 53.33 4.34 56 4.32 C58.67 4.31 61.33 4.03 64 3.65 C66.67 3.28 69.33 2.52 72 2.08 C74.67 1.63 77.33 1.18 80 0.96 C82.67 0.74 85.33 0.74 88 0.76 C90.67 0.77 93.33 0.88 96 1.06 C98.67 1.25 101.33 1.51 104 1.86 C106.67 2.21 109.33 2.79 112 3.16 C114.67 3.52 117.33 3.96 120 4.03 C122.67 4.1 125.33 3.84 128 3.58 C130.67 3.32 133.33 2.72 136 2.47 C138.67 2.21 141.33 2.06 144 2.05 C146.67 2.03 149.33 2.29 152 2.38 C154.67 2.47 157.33 2.55 160 2.58L160 4.45 C157.33 4.43 154.67 4.39 152 4.34 C149.33 4.3 146.67 4.13 144 4.2 C141.33 4.27 138.67 4.49 136 4.76 C133.33 5.03 130.67 5.61 128 5.83 C125.33 6.04 122.67 6.21 120 6.05 C117.33 5.89 114.67 5.32 112 4.87 C109.33 4.42 106.67 3.75 104 3.36 C101.33 2.96 98.67 2.7 96 2.51 C93.33 2.33 90.67 2.26 88 2.26 C85.33 2.26 82.67 2.28 80 2.49 C77.33 2.7 74.67 3.11 72 3.51 C69.33 3.91 66.67 4.58 64 4.9 C61.33 5.22 58.67 5.44 56 5.43 C53.33 5.43 50.67 5.06 48 4.89 C45.33 4.72 42.67 4.45 40 4.42 C37.33 4.38 34.67 4.58 32 4.67 C29.33 4.76 26.67 4.94 24 4.94 C21.33 4.95 18.67 4.78 16 4.7 C13.33 4.61 10.67 4.47 8 4.43 C5.33 4.38 2.67 4.46 0 4.45Z' fill='%23000'/%3E%3C/svg%3E");
}

/* Dentro de un «@supports» a propósito, igual que en el panel: sin máscara, «background-color» pintaría el
   bloque entero — una BARRA MACIZA de 7px de acento donde tenía que haber un trazo, y encima justo debajo
   del titular. Declarado aquí dentro, un navegador sin máscaras no pinta nada y se queda el aire, que es
   lo que menos miente. Prefijado Y sin prefijar porque Safari sirvió «-webkit-mask-*» durante años. */
@supports (mask-image: none) or (-webkit-mask-image: none) {
  .filete-a-mano {
    background-color: var(--accent);
    height: var(--trazo-a-mano-alto);
    -webkit-mask-image: var(--trazo-a-mano);
            mask-image: var(--trazo-a-mano);
    -webkit-mask-size: var(--trazo-a-mano-ancho) var(--trazo-a-mano-alto);
            mask-size: var(--trazo-a-mano-ancho) var(--trazo-a-mano-alto);
    -webkit-mask-repeat: repeat-x;
            mask-repeat: repeat-x;
    -webkit-mask-position: left center;
            mask-position: left center;
  }
}
/* «border: 0» porque un «<hr>» trae el suyo del navegador y se sumaría al trazo. El ancho es corto y no
   del cien por cien: aquí firma un titular, no separa dos bloques. */
.filete-a-mano { display: block; width: min(100%, 14rem); border: 0; margin: .2rem 0 0; flex: none; }
