/* Hoja de estilo de la web generada de LGM-OS (portada, novedades, instalación y docs).
 *
 * Es EL MISMO lenguaje que el portal (web/app/static/estilo.css): la píldora de cristal
 * flotante, el vidrio con canto degradado, las sombras en capas y un solo azul de acción.
 * Son dos hojas porque son dos cosas distintas —el portal lo sirve Jinja y esto lo genera
 * generar.py como HTML plano—, pero el visitante las ve como una sola web, así que las
 * recetas son las mismas traducidas a los tokens de aquí.
 *
 * Sin librerías a propósito: el panel usa Tailwind, pero una página estática que necesita
 * seis componentes no justifica arrastrar un compilador. Lo que sí se copia son los valores.
 *
 * Orden de la hoja: tokens → lienzo → cristal → barra → héroe → botones → componentes de
 * contenido → documentación → pie → movimiento → quietud. Nada de capas de «refinamiento»
 * que se pisan entre sí: cada cosa está una vez, en su sitio.
 */

/* ================================================================ tokens */

:root {
  color-scheme: light;

  /* Un solo azul para todo lo que es «acción»: botones, foco, enlaces y selección. */
  --acento: #2563eb;
  --acento-fuerte: #1d4ed8;
  --acento-suave: rgba(37, 99, 235, 0.14);

  --texto: #1e293b;
  --texto-fuerte: #0f172a;
  --texto-suave: #475569;
  --texto-tenue: #64748b;
  --borde: rgba(15, 23, 42, 0.09);
  --codigo-fondo: #0f172a;

  --cristal: rgba(255, 255, 255, 0.72);
  --cristal-borde: rgba(255, 255, 255, 0.55);

  /* ---------------------------------------------------------- cristal de verdad
     Un `backdrop-filter` a secas no es cristal: es una mancha borrosa. El cristal se
     reconoce por tres cosas más, y son las que van aquí.

     · SATURACIÓN. Detrás del cristal los colores se avivan, no se apagan.
     · BRILLO DE CANTO. Un borde plano parece pegatina. El de verdad se enciende arriba
       —donde le da la luz— y se apaga abajo: un degradado, no un color.
     · LUZ INTERIOR. Una sombra interior clarísima en el borde superior da grosor de
       lámina en vez de recorte. */
  --vidrio-filtro: saturate(180%) blur(22px);
  --vidrio-canto: linear-gradient(150deg,
                    rgba(255, 255, 255, .85), rgba(255, 255, 255, .18) 42%,
                    rgba(255, 255, 255, .06));
  --vidrio-luz: inset 0 1px 0 rgba(255, 255, 255, .75);

  /* Sombras en capas: contacto, cuerpo y ambiente. Una sola sombra grande es una nube
     gris; tres cortas y una larga es como cae la luz de verdad. */
  --sombra-1: 0 1px 2px rgba(15, 23, 42, .06), 0 3px 8px -2px rgba(15, 23, 42, .08);
  --sombra-2: 0 2px 4px rgba(15, 23, 42, .05), 0 8px 20px -6px rgba(15, 23, 42, .12),
              0 24px 48px -20px rgba(15, 23, 42, .18);
  --sombra-3: 0 4px 8px rgba(15, 23, 42, .06), 0 16px 40px -12px rgba(15, 23, 42, .16),
              0 48px 96px -32px rgba(15, 23, 42, .28);
  /* Debajo de un botón azul, una sombra gris ensucia; una azul lo levanta. */
  --sombra-acento: 0 2px 6px rgba(37, 99, 235, .24), 0 12px 28px -8px rgba(37, 99, 235, .38);

  /* Escala tipográfica fluida: el titular crece con la ventana en vez de pegar un tirón
     al cruzar un breakpoint. Los grandes van apretados y con interlineado corto. */
  --t-h1: clamp(2.1rem, 1.1rem + 3.6vw, 3.6rem);
  --t-h2: clamp(1.45rem, 1rem + 1.8vw, 2.1rem);
  --t-h3: clamp(1.08rem, .95rem + .5vw, 1.3rem);
  --t-cuerpo: clamp(1rem, .96rem + .2vw, 1.08rem);

  /* Aire. Lo que más separa una página cara de una barata no es el color: es cuánto
     hueco se atreve a dejar. */
  --aire-seccion: clamp(3.2rem, 7vw, 6rem);
  --radio: 16px;
  --radio-g: 24px;

  /* Movimiento: una curva de salida suave tipo iOS y dos duraciones. Todo lo que se mueve
     en la hoja usa esto, y todo se apaga con una sola regla al final. */
  --curva: cubic-bezier(.22, 1, .36, 1);
  --rapido: .18s;
  --medio: .32s;
}

[data-theme="dark"] {
  color-scheme: dark;
  --acento: #3b82f6;
  --acento-fuerte: #2563eb;
  --acento-suave: rgba(59, 130, 246, 0.25);

  --texto: #cbd5e1;
  --texto-fuerte: #e2e8f0;
  --texto-suave: #94a3b8;
  --texto-tenue: #7c8aa0;
  --borde: rgba(148, 163, 184, 0.18);
  --codigo-fondo: #060b16;

  --cristal: rgba(30, 41, 59, 0.6);
  --cristal-borde: rgba(148, 163, 184, 0.16);

  /* En oscuro el cristal no se aclara: se ilumina el CANTO. Subir la opacidad del relleno
     da un plástico lechoso; dejarlo oscuro y encender el borde da vidrio ahumado. */
  --vidrio-canto: linear-gradient(150deg,
                    rgba(255, 255, 255, .28), rgba(255, 255, 255, .06) 42%,
                    rgba(255, 255, 255, .02));
  --vidrio-luz: inset 0 1px 0 rgba(255, 255, 255, .10);

  --sombra-1: 0 1px 2px rgba(0, 0, 0, .4), 0 3px 8px -2px rgba(0, 0, 0, .45);
  --sombra-2: 0 2px 4px rgba(0, 0, 0, .35), 0 8px 20px -6px rgba(0, 0, 0, .5),
              0 24px 48px -20px rgba(0, 0, 0, .6);
  --sombra-3: 0 4px 8px rgba(0, 0, 0, .4), 0 16px 40px -12px rgba(0, 0, 0, .55),
              0 48px 96px -32px rgba(0, 0, 0, .7);
  --sombra-acento: 0 2px 6px rgba(37, 99, 235, .35), 0 12px 28px -8px rgba(37, 99, 235, .5);
}

/* Sin JavaScript no hay quien ponga data-theme: que al menos el sistema mande. Son los
   mismos valores de arriba, y es duplicación a sabiendas —CSS no permite reutilizar un
   bloque en dos selectores sin preprocesador, y esta web no carga ninguno—. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --acento: #3b82f6;
    --acento-fuerte: #2563eb;
    --acento-suave: rgba(59, 130, 246, 0.25);
    --texto: #cbd5e1;
    --texto-fuerte: #e2e8f0;
    --texto-suave: #94a3b8;
    --texto-tenue: #7c8aa0;
    --borde: rgba(148, 163, 184, 0.18);
    --codigo-fondo: #060b16;
    --cristal: rgba(30, 41, 59, 0.6);
    --cristal-borde: rgba(148, 163, 184, 0.16);
    --vidrio-canto: linear-gradient(150deg,
                      rgba(255, 255, 255, .28), rgba(255, 255, 255, .06) 42%,
                      rgba(255, 255, 255, .02));
    --vidrio-luz: inset 0 1px 0 rgba(255, 255, 255, .10);
    --sombra-1: 0 1px 2px rgba(0, 0, 0, .4), 0 3px 8px -2px rgba(0, 0, 0, .45);
    --sombra-2: 0 2px 4px rgba(0, 0, 0, .35), 0 8px 20px -6px rgba(0, 0, 0, .5),
                0 24px 48px -20px rgba(0, 0, 0, .6);
    --sombra-3: 0 4px 8px rgba(0, 0, 0, .4), 0 16px 40px -12px rgba(0, 0, 0, .55),
                0 48px 96px -32px rgba(0, 0, 0, .7);
    --sombra-acento: 0 2px 6px rgba(37, 99, 235, .35), 0 12px 28px -8px rgba(37, 99, 235, .5);
  }
}

/* ================================================================ lienzo */

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  color: var(--texto);
  font-family: "SF Pro Display", Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: var(--t-cuerpo);
  line-height: 1.65;
  letter-spacing: -0.006em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  -webkit-text-size-adjust: 100%;
  /* Solo el color base: el degradado entero vive en el ::before de abajo. */
  background: #e8ecf5;
  position: relative;
}
[data-theme="dark"] body { background: #0d1424; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body { background: #0d1424; }
}

/* Nada de desbordes laterales, pase lo que pase: una animación que asoma un píxel por el
   borde regala una barra de scroll horizontal en el móvil. `clip` y no `hidden`: `hidden`
   convierte el elemento en contenedor de scroll y ROMPE los position:sticky de dentro. */
html, body { overflow-x: clip; }

/* El lienzo entero —la luz del escritorio del panel— pintado en un pseudo-elemento con
   `position: fixed`, NO con `background-attachment: fixed`: los navegadores del móvil
   implementan `attachment` a medias y el fondo se corta al primer alto de pantalla, con
   toda la página en blanco de ahí para abajo. Un elemento fijo de verdad no tiene ese
   problema en ninguno. */
body::before {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(46vw 46vw at 12% 4%, color-mix(in srgb, var(--acento) 11%, transparent), transparent 70%),
    radial-gradient(38vw 38vw at 92% 18%, color-mix(in srgb, #8b5cf6 9%, transparent), transparent 70%),
    radial-gradient(ellipse 90% 70% at 12% 0%, rgba(99, 132, 199, 0.22), transparent 62%),
    radial-gradient(ellipse 80% 60% at 88% 8%, rgba(129, 140, 202, 0.18), transparent 62%),
    radial-gradient(ellipse 100% 60% at 50% 100%, rgba(100, 150, 170, 0.16), transparent 68%),
    linear-gradient(165deg, #eef2f8 0%, #e8ecf5 45%, #e6eef1 100%);
}
[data-theme="dark"] body::before {
  background:
    radial-gradient(46vw 46vw at 12% 4%, color-mix(in srgb, var(--acento) 13%, transparent), transparent 70%),
    radial-gradient(38vw 38vw at 92% 18%, color-mix(in srgb, #8b5cf6 10%, transparent), transparent 70%),
    radial-gradient(ellipse 90% 70% at 12% 0%, rgba(37, 99, 235, 0.18), transparent 62%),
    radial-gradient(ellipse 80% 60% at 88% 8%, rgba(99, 102, 241, 0.14), transparent 62%),
    radial-gradient(ellipse 100% 60% at 50% 100%, rgba(13, 148, 136, 0.12), transparent 68%),
    linear-gradient(165deg, #0b1220 0%, #111827 50%, #0f1a1f 100%);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body::before {
    background:
      radial-gradient(46vw 46vw at 12% 4%, color-mix(in srgb, var(--acento) 13%, transparent), transparent 70%),
      radial-gradient(38vw 38vw at 92% 18%, color-mix(in srgb, #8b5cf6 10%, transparent), transparent 70%),
      radial-gradient(ellipse 90% 70% at 12% 0%, rgba(37, 99, 235, 0.18), transparent 62%),
      radial-gradient(ellipse 80% 60% at 88% 8%, rgba(99, 102, 241, 0.14), transparent 62%),
      radial-gradient(ellipse 100% 60% at 50% 100%, rgba(13, 148, 136, 0.12), transparent 68%),
      linear-gradient(165deg, #0b1220 0%, #111827 50%, #0f1a1f 100%);
  }
}

h1, h2, h3, h4 { color: var(--texto-fuerte); letter-spacing: -0.018em; }

/* Las cifras, en columna: en un NAS casi todo lo que se lee son tamaños y fechas. */
table, td, th, time, code, .tabular { font-variant-numeric: tabular-nums; }

.envoltorio { max-width: 1040px; margin: 0 auto; padding: 0 20px 72px; }

a { color: var(--acento); text-decoration-color: color-mix(in srgb, var(--acento) 40%, transparent); }
a:hover { color: var(--acento-fuerte); }

/* La selección, del azul de la casa y translúcida: no toca el color del texto, así que lo
   seleccionado se sigue leyendo igual en claro y en oscuro. */
::selection { background: color-mix(in srgb, var(--acento) 30%, transparent); }

/* El foco NUNCA se quita: es como se navega con teclado. Se dibuja bonito y se acabó.
   El anillo no toca el radio del elemento: sigue la forma que ya tenga. */
a[href]:focus-visible,
button:focus-visible,
input:focus-visible,
summary:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 2px;
}

/* `hidden` en un elemento con `display` propio no esconde nada: la propiedad gana al
   atributo. El filtro de guías se apoya en `hidden`, así que se dice explícitamente. */
[hidden] { display: none !important; }

/* Con la barra pegajosa delante, un enlace a #seccion aterrizaba con el título DEBAJO de
   ella. Todo lo que tiene ancla se frena antes. */
[id] { scroll-margin-top: 5.5rem; }

/* ================================================================ cristal */

.glass {
  background:
    linear-gradient(var(--cristal), var(--cristal)) padding-box,
    var(--vidrio-canto) border-box;
  border: 1px solid transparent;
  border-radius: var(--radio-g);
  -webkit-backdrop-filter: var(--vidrio-filtro);
  backdrop-filter: var(--vidrio-filtro);
  box-shadow: var(--sombra-2), var(--vidrio-luz);
}

.panel { padding: 20px 24px; margin-bottom: 14px; }
/* Los paneles llevan su hueco propio: lo primero y lo último no suman el suyo. */
.panel > :first-child { margin-top: 0; }
.panel > :last-child { margin-bottom: 0; }

/* ================================================================ la barra
   La misma píldora flotante del portal. Pegada al canto superior parece parte del
   navegador; flotando parece parte del producto. */

.barra-superior {
  position: sticky; top: .75rem; z-index: 50;
  display: flex; align-items: center; gap: .5rem;
  /* Fuera del envoltorio (la abre generar.py antes que él) y con LA MISMA anchura que la
     barra del portal: si midieran distinto, al pasar de la landing a la documentación la
     barra «encogería» y delataría que son dos plantillas. */
  margin: .75rem auto 0; max-width: min(1180px, calc(100% - 1.5rem));
  padding: .55rem clamp(.9rem, 2vw, 1.3rem);
  border-radius: 999px;
  background:
    linear-gradient(var(--cristal), var(--cristal)) padding-box,
    var(--vidrio-canto) border-box;
  border: 1px solid transparent;
  -webkit-backdrop-filter: var(--vidrio-filtro);
  backdrop-filter: var(--vidrio-filtro);
  box-shadow: var(--sombra-2), var(--vidrio-luz);
  transition: padding var(--medio) var(--curva), box-shadow var(--medio) var(--curva);
}
/* Al bajar, la barra se encoge y gana sombra: la página «arranca». La clase la pone el
   script al pasar de 24 px de scroll. */
html.rodando .barra-superior { padding-block: .3rem; box-shadow: var(--sombra-3), var(--vidrio-luz); }

.marca {
  display: inline-flex; align-items: center; gap: .55rem;
  font-size: 1.1rem; font-weight: 800; letter-spacing: -.02em;
  color: var(--texto-fuerte); text-decoration: none; white-space: nowrap;
}
.marca:hover { text-decoration: none; }
.marca-icono { width: 26px; height: 26px; border-radius: 8px; box-shadow: var(--sombra-1); }
.marca-nombre { display: inline; }
.marca-os { color: var(--acento); }

/* Tres pesos en la barra, no uno: los enlaces de sección son discretos, «Comprar» es un
   botón sólido y el tema es un icono. Si los siete pesan igual, la acción que paga la web
   se pierde entre «Inicio» y «Documentación». */
nav.menu { display: flex; align-items: center; gap: .15rem; margin-left: auto; }

.nav-enlace {
  display: inline-flex; align-items: center; white-space: nowrap;
  padding: .42rem .7rem; border-radius: 9px;
  font-size: .9rem; font-weight: 500;
  color: var(--texto-suave); text-decoration: none;
  transition: background-color var(--rapido) var(--curva), color var(--rapido) var(--curva);
}
.nav-enlace:hover {
  text-decoration: none; color: var(--texto-fuerte);
  background: color-mix(in srgb, var(--texto-fuerte) 7%, transparent);
}
/* Dónde estás. Se cuelga de aria-current, que es el atributo que ya lo dice de verdad. */
.nav-enlace[aria-current="page"] {
  color: var(--texto-fuerte); font-weight: 650;
  background: color-mix(in srgb, var(--acento) 12%, transparent);
}

.nav-fijo { display: flex; align-items: center; gap: .5rem; margin-left: .6rem; }

.portal-cta {
  display: inline-flex; align-items: center; white-space: nowrap;
  padding: .45rem .95rem; border-radius: 999px;
  font-size: .9rem; font-weight: 650; color: #fff; text-decoration: none;
  background: linear-gradient(180deg, var(--acento), var(--acento-fuerte));
  box-shadow: 0 1px 2px rgba(15, 23, 42, .18), inset 0 1px 0 rgba(255, 255, 255, .22);
  transition: transform var(--rapido) var(--curva), box-shadow var(--rapido) var(--curva),
              filter var(--rapido) var(--curva);
}
.portal-cta:hover {
  text-decoration: none; color: #fff; filter: brightness(1.06);
  box-shadow: 0 4px 12px -2px color-mix(in srgb, var(--acento) 55%, transparent),
              inset 0 1px 0 rgba(255, 255, 255, .22);
}
.portal-cta:active { transform: translateY(1px); }

/* El interruptor de tema: un icono tranquilo. Cada tema enseña el icono del OTRO, que es
   a lo que se va a cambiar. */
.cambiar-tema {
  width: 34px; height: 34px; padding: 0;
  display: grid; place-items: center;
  border-radius: 10px; border: 0; background: none;
  color: var(--texto-suave); cursor: pointer;
  transition: background-color var(--rapido) var(--curva), color var(--rapido) var(--curva);
}
.cambiar-tema:hover { background: color-mix(in srgb, var(--texto-fuerte) 8%, transparent); color: var(--texto-fuerte); }
.cambiar-tema:active { transform: translateY(1px); }
.cambiar-tema svg { width: 17px; height: 17px; }
.cambiar-tema .luna { display: block; }
.cambiar-tema .sol { display: none; }
[data-theme="dark"] .cambiar-tema .luna { display: none; }
[data-theme="dark"] .cambiar-tema .sol { display: block; }

/* El botón de menú solo existe en pantallas estrechas. */
.nav-abrir { display: none; }

/* Por debajo de esto los enlaces ya no caben al lado de la marca, así que se pliegan.
   «Comprar» y el tema se quedan a la vista: son la venta y un ajuste de una pulsación. */
@media (max-width: 800px) {
  .barra-superior { flex-wrap: wrap; border-radius: var(--radio-g); }
  .nav-abrir {
    display: inline-flex; align-items: center; justify-content: center;
    order: 3; margin-left: auto;
    width: 38px; height: 38px; padding: 0; border-radius: 10px;
    background: none; border: 1px solid var(--cristal-borde); color: var(--texto-fuerte);
    cursor: pointer;
  }
  .nav-abrir svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; }
  .nav-fijo { order: 2; margin-left: auto; }
  nav.menu {
    order: 4; display: none; width: 100%;
    flex-direction: column; align-items: stretch; gap: .1rem;
    margin: .35rem 0 .15rem; padding-top: .5rem;
    border-top: 1px solid var(--borde);
  }
  .barra-superior.menu-abierto nav.menu { display: flex; }
  .nav-enlace { width: 100%; justify-content: flex-start; padding: .6rem .7rem; font-size: .95rem; }
}

/* ================================================================ héroe */

.hero {
  text-align: center;
  padding: clamp(3rem, 8vw, 5.5rem) 0 clamp(1.8rem, 4vw, 3rem);
  /* El aire de sección de abajo NO se suma: el héroe ya trae el suyo en el padding, y las
     dos cosas juntas eran nueve rem de página vacía antes del primer contenido. */
  margin-bottom: 0;
}
.hero h1 {
  margin: .9rem 0 .6rem;
  font-size: var(--t-h1); font-weight: 750; line-height: 1.04; letter-spacing: -.035em;
}
.hero .entradilla {
  margin: 0 auto;
  max-width: 62ch;
  font-size: clamp(1.02rem, .95rem + .5vw, 1.2rem);
  line-height: 1.55;
  color: var(--texto-suave);
}
.hero nav.principal {
  display: flex; flex-wrap: wrap; justify-content: center; gap: .7rem;
  margin-top: 1.5rem;
}
/* El héroe compacto de las guías: el título lo pone el propio documento. */
.hero.compacta { padding: clamp(1.6rem, 4vw, 2.6rem) 0 1.2rem; }
.hero.compacta .entradilla { font-size: 1.02rem; margin-top: .5rem; }
.hero.compacta nav.principal { margin-top: 1.1rem; }

/* ================================================================ pegatinas (chips) */

.chip {
  display: inline-flex; align-items: center; gap: 4px;
  border-radius: 999px; padding: 3px 10px;
  font-size: 11.5px; font-weight: 600; line-height: 1.15rem;
  letter-spacing: .01em; white-space: nowrap;
}
.chip-blue  { color: #1d4ed8; background: rgba(37, 99, 235, 0.12); }
.chip-amber { color: #b45309; background: rgba(217, 119, 6, 0.14); }
.chip-slate { color: #475569; background: rgba(71, 85, 105, 0.12); }
[data-theme="dark"] .chip-blue  { color: #93c5fd; background: rgba(59, 130, 246, 0.18); }
[data-theme="dark"] .chip-amber { color: #fcd34d; background: rgba(245, 158, 11, 0.18); }
[data-theme="dark"] .chip-slate { color: #cbd5e1; background: rgba(148, 163, 184, 0.18); }

/* ================================================================ botones
   Un botón se levanta al acercarse y se HUNDE al pulsarlo. Lo segundo es lo que casi nadie
   pone y lo que hace que se sienta físico: sin el hundido, pulsar no confirma nada. */

.btn-primary, .btn-secondary {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  border-radius: 999px; padding: 10px 20px;
  font-size: 14.5px; font-weight: 600; letter-spacing: -.01em; line-height: 1.25rem;
  text-decoration: none; border: 1px solid transparent; cursor: pointer;
  transition: transform var(--rapido) var(--curva), box-shadow var(--medio) var(--curva),
              background-color var(--rapido) var(--curva), border-color var(--rapido) var(--curva),
              color var(--rapido) var(--curva);
  will-change: transform;
}
.btn-primary svg, .btn-secondary svg { width: 1.1em; height: 1.1em; }

.btn-primary {
  background: linear-gradient(180deg, var(--acento), var(--acento-fuerte));
  color: #fff;
  box-shadow: var(--sombra-acento), inset 0 1px 0 rgba(255, 255, 255, .22);
}
.btn-primary:hover {
  color: #fff; transform: translateY(-2px);
  box-shadow: var(--sombra-acento), 0 20px 40px -12px rgba(37, 99, 235, .45),
              inset 0 1px 0 rgba(255, 255, 255, .22);
}

.btn-secondary {
  color: var(--texto-suave);
  background: color-mix(in srgb, var(--cristal) 80%, transparent);
  border-color: var(--borde);
  box-shadow: var(--sombra-1);
}
.btn-secondary:hover {
  transform: translateY(-2px);
  color: var(--texto-fuerte); border-color: color-mix(in srgb, var(--texto-fuerte) 16%, transparent);
  box-shadow: var(--sombra-2);
}

.btn-primary:active, .btn-secondary:active {
  transform: translateY(0) scale(.985); transition-duration: .06s;
}
/* Un botón apagado no promete nada: ni sombra, ni salto, ni cursor de acción. */
.btn-primary:disabled, .btn-secondary:disabled,
.btn-primary[aria-disabled="true"], .btn-secondary[aria-disabled="true"] {
  opacity: .5; cursor: not-allowed; transform: none;
  box-shadow: none; filter: none; pointer-events: none;
}
.btn-primary:focus-visible, .btn-secondary:focus-visible {
  outline: 2px solid var(--acento); outline-offset: 3px;
}

.acciones { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 1.2rem; }

/* ================================================================ secciones */

section { margin-bottom: var(--aire-seccion); }

h2 { font-size: var(--t-h2); line-height: 1.12; letter-spacing: -.025em; margin: 0 0 4px; }
h3 { font-size: var(--t-h3); letter-spacing: -.015em; }
h2 + .sub { margin: 0 0 18px; color: var(--texto-tenue); font-size: 15.5px; }
.sub.aparte { margin-top: 1rem; color: var(--texto-tenue); font-size: 15.5px; }

.rejilla { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
/* «dos» son DOS columnas de verdad, no «las que quepan»: con auto-fit, cuatro tarjetas a
   ancho de escritorio salían 3+1, con la cuarta huérfana junto a un hueco doble. */
.rejilla.dos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.rejilla.tres { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
@media (max-width: 700px) {
  .rejilla.dos { grid-template-columns: minmax(0, 1fr); }
}

.dato { font-size: 15px; margin: 0; }
.dato dt { font-weight: 600; color: var(--texto-fuerte); margin-bottom: 2px; }
.dato dd { margin: 0; color: var(--texto-suave); }

.destacado h3 { margin: 0 0 6px; font-size: 16px; }
.destacado p { margin: 0; color: var(--texto-suave); font-size: 15px; }

/* ================================================================ código */

pre, code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }

pre {
  background: var(--codigo-fondo);
  color: #e2e8f0;
  border: 1px solid rgba(148, 163, 184, 0.18);
  border-radius: 12px;
  padding: 14px 16px;
  overflow-x: auto;
  font-size: 13.5px;
  line-height: 1.6;
  margin: 12px 0;
  box-shadow: var(--sombra-1);
}

/* Dentro de un bloque, los saltos de línea son parte de la orden. */
pre code { background: none; padding: 0; color: inherit; font-size: inherit; white-space: pre; }

code {
  background: var(--acento-suave);
  color: var(--acento-fuerte);
  padding: 1px 6px;
  border-radius: 6px;
  font-size: 0.88em;
  font-variant-ligatures: none;
  /* Una orden partida en dos líneas se lee como dos cosas distintas. */
  white-space: nowrap;
}
[data-theme="dark"] code { color: #93c5fd; }

/* ================================================================ avisos */

.aviso, .peligro {
  border-radius: 12px;
  padding: 13px 16px;
  margin: 16px 0;
  font-size: 15px;
  border: 1px solid;
}
.aviso {
  color: #b45309;
  background: rgba(217, 119, 6, 0.1);
  border-color: rgba(217, 119, 6, 0.28);
}
.peligro {
  color: #b91c1c;
  background: rgba(220, 38, 38, 0.09);
  border-color: rgba(220, 38, 38, 0.28);
}
[data-theme="dark"] .aviso {
  color: #fcd34d;
  background: rgba(245, 158, 11, 0.14);
  border-color: rgba(245, 158, 11, 0.3);
}
[data-theme="dark"] .peligro {
  color: #fecaca;
  background: rgba(248, 113, 113, 0.14);
  border-color: rgba(248, 113, 113, 0.32);
}

/* ================================================================ novedades */

.version { padding: 18px 22px; margin-bottom: 14px; transition: box-shadow var(--medio) var(--curva); }
.version:hover { box-shadow: var(--sombra-3), var(--vidrio-luz); }

.version h3 {
  display: inline-flex; align-items: baseline; gap: 10px;
  margin: 0; font-size: 18px;
}
.version .num { font-variant-numeric: tabular-nums; }
.version .fecha { font-size: 12px; font-weight: 400; color: var(--texto-tenue); }

.version h4 { margin: 18px 0 6px; font-size: 14px; font-weight: 600; color: var(--acento-fuerte); }
[data-theme="dark"] .version h4 { color: #93c5fd; }

.version .entradilla-version { margin: 10px 0 4px; color: var(--texto-suave); font-size: 15px; }
.version ul { margin: 0; padding-left: 20px; }
.version li { margin-bottom: 8px; color: var(--texto-suave); }
.version li strong { color: var(--texto-fuerte); font-weight: 600; }

details.version summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: 8px; padding: 2px 0;
}
details.version summary::-webkit-details-marker { display: none; }
/* El signo gira al abrir: la animación más barata que existe y la que más se nota. */
details.version summary::before {
  content: "▸"; color: var(--texto-tenue); font-size: 12px;
  transition: transform var(--rapido) var(--curva);
}
details.version[open] summary::before { transform: rotate(90deg); }
details.version summary:hover { color: var(--acento-fuerte); }

/* ================================================================ pasos */

ol.pasos { counter-reset: paso; list-style: none; padding: 0; margin: 0; }

ol.pasos > li {
  counter-increment: paso;
  position: relative;
  padding: 0 0 18px 40px;
  border-left: 2px solid var(--borde);
  margin-left: 13px;
}
ol.pasos > li:last-child { border-left-color: transparent; padding-bottom: 0; }

ol.pasos > li::before {
  content: counter(paso);
  position: absolute; left: -14px; top: -1px;
  width: 26px; height: 26px; border-radius: 50%;
  background: linear-gradient(160deg, #60a5fa, var(--acento));
  color: #fff; font-size: 12px; font-weight: 700;
  display: grid; place-items: center;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), var(--sombra-1);
}

ol.pasos h3 { margin: 0 0 4px; font-size: 16px; }
ol.pasos p { margin: 0 0 8px; color: var(--texto-suave); font-size: 15px; }

/* ================================================================ tablas */

.tabla-envuelta { overflow-x: auto; }

table { border-collapse: collapse; width: 100%; font-size: 15px; min-width: 460px; }

th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--borde); vertical-align: top; }
tr:last-child td { border-bottom: 0; }

th {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--texto-tenue); font-weight: 600;
}
td { color: var(--texto-suave); }
td:first-child { font-weight: 600; color: var(--texto-fuerte); white-space: nowrap; }

/* ================================================================ capturas */

.captura { margin: 0 0 16px; padding: 12px; }
.captura img {
  display: block; width: 100%; height: auto;
  border-radius: 12px; border: 1px solid var(--borde);
}
.captura figcaption {
  margin-top: 12px; font-size: 14.5px; color: var(--texto-suave); line-height: 1.6;
}
.captura figcaption strong { color: var(--texto-fuerte); }

/* Dos capturas por app, una por tema: se enseña la del tema puesto. */
[data-theme="light"] .captura .oscuro,
[data-theme="light"] .captura-movil .oscuro,
[data-theme="dark"] .captura .claro,
[data-theme="dark"] .captura-movil .claro { display: none; }

.moviles { display: flex; flex-wrap: wrap; gap: 22px; justify-content: center; }

.captura-movil { margin: 0; max-width: 240px; }
.captura-movil img {
  display: block; width: 100%; height: auto;
  /* El radio y el borde bastan para que se lea como un móvil sin dibujar una carcasa. */
  border-radius: 26px;
  border: 1px solid var(--borde);
  box-shadow: var(--sombra-3);
}
.captura-movil figcaption {
  margin-top: 10px; text-align: center; font-size: 13.5px; color: var(--texto-tenue);
}
.pie-movil { margin: 20px 0 0; font-size: 14.5px; color: var(--texto-suave); }

/* ================================================================ áreas (qué sabe hacer) */

.area { padding: 18px 22px; margin-bottom: 14px; }
.area h3 { margin: 0 0 10px; font-size: 17px; }
.area ul { margin: 0; padding-left: 20px; }
.area li { margin-bottom: 7px; color: var(--texto-suave); font-size: 15px; }
.area li strong { color: var(--texto-fuerte); }

/* ================================================================ documentación: portada
   Quien llega a una documentación trae UNA pregunta y necesita saber cuál de las ocho
   guías la responde, sin abrir tres para averiguarlo. De ahí el buscador, los grupos y la
   línea de «cuándo» de cada tarjeta. */

.doc-buscar { margin: 0 0 clamp(2rem, 4.5vw, 2.8rem); }
.doc-buscador {
  display: flex; align-items: center; gap: .7rem;
  max-width: 34rem; margin: 0 auto; padding: .1rem .3rem .1rem 1.1rem;
  border-radius: 999px;
  background:
    linear-gradient(var(--cristal), var(--cristal)) padding-box,
    var(--vidrio-canto) border-box;
  border: 1px solid transparent;
  -webkit-backdrop-filter: var(--vidrio-filtro);
  backdrop-filter: var(--vidrio-filtro);
  box-shadow: var(--sombra-2), var(--vidrio-luz);
  transition: box-shadow var(--rapido) var(--curva);
}
/* El anillo de foco va en el contenedor, no en el campo: si no, salen dos. */
.doc-buscador:focus-within { box-shadow: var(--sombra-3), 0 0 0 3px var(--acento-suave); }
.doc-lupa { width: 17px; height: 17px; flex: 0 0 auto; color: var(--texto-tenue); }
.doc-buscador input {
  flex: 1; min-width: 0; border: 0; outline: 0; background: transparent;
  color: inherit; font: inherit; padding: .8rem .4rem .8rem 0;
}
.doc-buscador input::placeholder { color: var(--texto-tenue); }
.doc-nada { text-align: center; margin-top: 1.2rem; color: var(--texto-tenue); font-size: .95rem; }

.doc-grupo { margin-bottom: clamp(2rem, 4.5vw, 2.8rem); }
/* Los títulos de grupo son rótulos de un índice, no titulares: a tamaño de titular, cuatro
   grupos gritando convertían la página en una escalera de letras enormes. */
.doc-grupo > h2 { font-size: 1.28rem; letter-spacing: -.015em; margin-bottom: .15rem; }
.doc-grupo > .sub { margin-top: 0; margin-bottom: 12px; font-size: 14.5px; }

/* La guía es una FILA: peana con el icono, texto y un chevrón. Compacta a propósito —esto
   es un índice, y en el móvil ocho bloques verticales eran seis pantallas de scroll—. */
.guia {
  position: relative; display: flex; align-items: flex-start; gap: .95rem;
  padding: 1.05rem 1.1rem;
  border-radius: 18px;
  text-decoration: none;
  transition: transform var(--medio) var(--curva), box-shadow var(--medio) var(--curva);
}
/* Un grupo con una sola guía ocupa el ancho entero: media rejilla vacía parece un fallo. */
.rejilla.dos > .guia:only-child { grid-column: 1 / -1; }

.guia-ico {
  flex: 0 0 auto; width: 42px; height: 42px;
  display: grid; place-items: center;
  border-radius: 12px;
}
.guia-ico svg { width: 22px; height: 22px; }
/* El tinte de la peana lo decide el grupo (lo pone generar.py): azul para leer con calma,
   ámbar para los apuros, pizarra para la referencia. */
.t-azul    { background: color-mix(in srgb, var(--acento) 12%, transparent); color: var(--acento); }
.t-ambar   { background: rgba(217, 119, 6, 0.14); color: #b45309; }
.t-pizarra { background: rgba(71, 85, 105, 0.12); color: #475569; }
[data-theme="dark"] .t-azul    { color: #93c5fd; }
[data-theme="dark"] .t-ambar   { background: rgba(245, 158, 11, 0.16); color: #fcd34d; }
[data-theme="dark"] .t-pizarra { background: rgba(148, 163, 184, 0.16); color: #cbd5e1; }

.guia-cuerpo { flex: 1 1 auto; min-width: 0; }
.guia h3 { margin: 0 0 .15rem; font-size: 1.02rem; letter-spacing: -.012em; color: var(--texto-fuerte); }
.guia p { margin: 0; font-size: .9rem; line-height: 1.5; color: var(--texto-suave); }
/* El «cuándo» es la línea que responde «¿esta es la mía?». En texto quieto, no en píldora:
   ocho píldoras azules parecían ocho botones desactivados. */
.guia-cuando {
  display: block; margin-top: .4rem;
  font-size: .8rem; line-height: 1.4; font-weight: 550;
  color: var(--acento);
}
[data-theme="dark"] .guia-cuando { color: #93c5fd; }

/* El chevrón promete que la fila lleva a algún sitio; al acercarse, empuja. */
.guia-flecha {
  flex: 0 0 auto; align-self: center;
  width: 17px; height: 17px;
  color: var(--texto-tenue); opacity: .55;
  transition: transform var(--rapido) var(--curva), opacity var(--rapido) var(--curva),
              color var(--rapido) var(--curva);
}
.guia:hover, .guia:focus-visible { transform: translateY(-2px); box-shadow: var(--sombra-3), var(--vidrio-luz); }
.guia:hover h3 { color: var(--acento-fuerte); }
.guia:hover .guia-flecha, .guia:focus-visible .guia-flecha {
  color: var(--acento); opacity: 1; transform: translateX(3px);
}

/* ================================================================ documentación: guías */

.con-lateral {
  display: grid; gap: 18px;
  grid-template-columns: 230px minmax(0, 1fr);
  align-items: start;
}

/* El índice se queda a la vista mientras se baja: en un documento de dos mil palabras,
   perder de vista dónde estás es perder el hilo. */
.lateral { position: sticky; top: 5.2rem; align-self: start; max-height: calc(100vh - 6.5rem); overflow-y: auto; }
.lateral h4 { margin: 0 0 8px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--texto-tenue); }
.lateral ul { margin: 0; padding: 0; list-style: none; }
.lateral li { margin-bottom: 2px; }
.lateral a {
  display: block; padding: 6px 10px; border-radius: 10px;
  font-size: 14px; text-decoration: none; color: var(--texto-suave);
  transition: background-color var(--rapido) var(--curva), color var(--rapido) var(--curva);
}
.lateral a:hover { background: rgba(37, 99, 235, 0.1); color: var(--acento-fuerte); }
[data-theme="dark"] .lateral a:hover { background: rgba(59, 130, 246, 0.22); color: #dbeafe; }

/* La guía en sí se lee como un documento, no como una interfaz. La medida de línea es LO
   que decide si se lee o se abandona: por encima de ~75 caracteres el ojo pierde el
   renglón al volver, y en una guía técnica eso es cerrar la pestaña. */
.documento { padding: 26px 30px; --medida: 72ch; }
.documento p, .documento li { max-width: var(--medida); line-height: 1.7; color: var(--texto-suave); }
.documento h1 { font-size: clamp(1.9rem, 1.1rem + 2.6vw, 2.9rem); line-height: 1.06; letter-spacing: -.035em; margin: 0 0 14px; }
.documento h2 {
  font-size: clamp(1.35rem, 1rem + 1.4vw, 1.9rem); line-height: 1.15; letter-spacing: -.025em;
  margin: 2.4em 0 8px; padding-top: .9em; border-top: 1px solid var(--borde);
}
/* El primer h2 no lleva raya: una línea justo debajo del título no separa nada. */
.documento h2:first-of-type { border-top: 0; padding-top: 0; margin-top: 1.4em; }
.documento h3 { font-size: 16.5px; margin: 1.9em 0 6px; letter-spacing: -.015em; }
.documento h4 { font-size: 15px; margin: 18px 0 6px; color: var(--acento-fuerte); }
[data-theme="dark"] .documento h4 { color: #93c5fd; }
.documento li { margin-bottom: 6px; }
.documento li strong, .documento p strong { color: var(--texto-fuerte); }
.documento ul, .documento ol { padding-left: 22px; }
.documento blockquote {
  margin: 14px 0; padding: 10px 16px;
  border-left: 3px solid var(--acento);
  background: var(--acento-suave);
  border-radius: 0 10px 10px 0;
  color: var(--texto-suave);
}
.documento hr { border: 0; border-top: 1px solid var(--borde); margin: 26px 0; }
/* El código no se parte por estética: si no cabe, se desliza él. */
.documento pre { max-width: none; }

/* Los enlaces del cuerpo se subrayan, con el subrayado despegado de las colas de las
   letras: un enlace que solo cambia de color no se distingue si eres daltónico. */
.documento a {
  text-decoration: underline; text-decoration-thickness: 1px;
  text-underline-offset: .18em;
  text-decoration-color: color-mix(in srgb, var(--acento) 45%, transparent);
  transition: text-decoration-color var(--rapido) var(--curva);
}
.documento a:hover { text-decoration-color: var(--acento); }

/* Ancla junto a cada título: la forma de mandarle a alguien EL punto exacto de la guía.
   Aparece al pasar por encima y no estorba al leer. */
.documento h2, .documento h3 { position: relative; }
.documento h2:hover::after, .documento h3:hover::after {
  content: '#'; position: absolute; left: -.85em; top: 0;
  color: color-mix(in srgb, var(--acento) 55%, transparent); font-weight: 400;
}

/* ================================================================ pie */

footer.principal {
  border-top: 1px solid var(--borde);
  padding-top: 22px;
  text-align: center;
  color: var(--texto-tenue);
  font-size: 14px;
}
.pie-enlaces { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 18px; margin-bottom: .5rem; }
.pie-enlaces a { color: var(--texto-tenue); text-decoration: none; }
.pie-enlaces a:hover { color: var(--texto-fuerte); text-decoration: underline; }
footer.principal p { margin: 0; }

/* ================================================================ movimiento
   Pocas piezas y bien cronometradas; todas se apagan con `prefers-reduced-motion`. Y NADA
   de esto oculta contenido si el script no corre: la clase que esconde («armada») la pone
   él, nunca el HTML. Ocultar desde el CSS y confiar en JavaScript para revelar es como se
   acaba con una web en blanco. */

/* --- 1. Aparecer al llegar. Solo en vertical y con poco recorrido: los deslizamientos
   laterales asomaban por los bordes de la pantalla del móvil. El ritmo lo pone el
   escalonado (lo cronometra el script), no el recorrido. */
.aparece { transition: opacity .55s var(--curva), transform .55s var(--curva); }
.aparece.armada { opacity: 0; transform: translateY(14px); }
.aparece.armada.visible { opacity: 1; transform: none; }

/* --- 2. El reflejo que sigue al puntero. Es LO que hace que una superficie parezca
   vidrio y no una caja con desenfoque: la luz se mueve con quien mira. Las coordenadas
   las pone el script en --mx/--my; sin él, se queda centrado y no pasa nada. */
.guia, .version {
  --mx: 50%; --my: 0%;
  isolation: isolate;
}
.version { position: relative; }
.guia::before, .version::before {
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  background: radial-gradient(16rem 16rem at var(--mx) var(--my),
              color-mix(in srgb, var(--acento) 22%, transparent), transparent 70%);
  opacity: 0; transition: opacity .35s var(--curva);
}
.guia:hover::before, .version:hover::before { opacity: 1; }

/* ================================================================ estrecho */

@media (max-width: 900px) {
  /* El índice de la guía, de columna pegada a TIRA horizontal: en un teléfono robaba 659
     de los 812 px de pantalla antes de la primera línea de texto. */
  .con-lateral { grid-template-columns: minmax(0, 1fr); }
  .lateral {
    position: static; max-height: none; overflow: visible;
    padding: .8rem .9rem;
  }
  .lateral h4 { margin: 0 0 .55rem; font-size: .72rem; letter-spacing: .06em; opacity: .7; }
  .lateral ul {
    display: flex; gap: .45rem; margin: 0; padding: 0 .2rem .3rem;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none;                 /* la barra estorba en una tira de fichas */
    scroll-snap-type: x proximity;
  }
  .lateral ul::-webkit-scrollbar { display: none; }
  .lateral li { flex: 0 0 auto; scroll-snap-align: start; margin: 0; }
  .lateral a {
    white-space: nowrap; padding: .42rem .8rem; border-radius: 999px;
    border: 1px solid var(--borde); font-size: .85rem;
  }
  .documento { padding-left: 1rem; padding-right: 1rem; }
  .documento h2 { margin-top: 1.8em; }
}

@media (max-width: 700px) {
  /* Las tablas de las guías, a lo ancho del teléfono. La alternativa era un scroll lateral
     que nada anunciaba: la columna derecha quedaba cortada a media palabra y parecía un
     fallo, no un gesto.

     `table-layout: fixed` porque con el reparto automático las columnas se las reparte el
     contenido: una ruta larga engordaba la suya, aplastaba la primera a 60 px y las
     palabras salían guillotinadas letra a letra. Fijo, cada columna sabe lo que mide, el
     texto envuelve por palabras y los guiones (`hyphens`, el HTML ya declara lang="es")
     parten con criterio lo que no quepa. */
  table { min-width: 0; width: 100%; table-layout: fixed; }
  td, th { overflow-wrap: break-word; hyphens: auto; }
  td:first-child { white-space: normal; width: 28%; }
}

@media (max-width: 560px) {
  .panel, .version { padding: 16px; }
  .hero { padding-top: 2.2rem; }
  .hero nav.principal .btn-primary, .hero nav.principal .btn-secondary { flex: 1 1 auto; }
  /* El índice de guías, pegado y al grano: en 375 px cada aire de más es medio codo de
     scroll. Las filas se estrechan, la rejilla junta y la peana un punto más pequeña. */
  .rejilla.dos { gap: 12px; }
  .guia { padding: .9rem .95rem; gap: .8rem; }
  .guia-ico { width: 38px; height: 38px; border-radius: 11px; }
  .guia-ico svg { width: 20px; height: 20px; }
  .doc-buscador input { padding-block: .72rem; }
  /* Un `código` EN LÍNEA largo —una ruta, una orden— lleva `white-space: nowrap`, y en una
     pantalla estrecha eso empuja la página fuera. Se parte antes que desbordar; los
     bloques (`pre code`) se quedan: ahí los saltos SÍ importan y el `pre` ya se desliza. */
  code { white-space: normal; overflow-wrap: anywhere; }
  pre code { white-space: pre; overflow-wrap: normal; }
}

/* ================================================================ quietud
   Una sola regla apaga TODO el movimiento de la hoja. Va la última para que nada se le
   escape por especificidad: hay gente a la que una animación de entrada le provoca mareo
   de verdad, y ahí lo correcto es que no exista, no que sea más corta. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .aparece.armada { opacity: 1 !important; transform: none !important; }
  .guia::before, .version::before { display: none; }
  .guia:hover, .btn-primary:hover, .btn-secondary:hover, .portal-cta:active,
  .btn-primary:active, .btn-secondary:active { transform: none !important; }
}
