/* ============================================================================
   vista-aplicacion.css — lo que la APLICACIÓN necesita y el prototipo no tenía.
   Se carga después de app.css en todas las vistas con sesión iniciada.
   Nada de esto redefine tokens de color, tipografía ni espacio: sólo ajusta
   piezas que el prototipo resolvía con andamio.

   PENDIENTE DE PROMOVER a app.css:
     1. `--alto-navprot: 0` — el andamio del prototipo no existe en producto,
        pero app.css §17 le descuenta 3.5rem a `.app` de forma incondicional.
        Al promover: mover ese descuento a `.app:has(~ .navprot)`.
     2. El ÁRBOL PLEGABLE del rail (`.carpetas__rama` y compañía). El rail del
        prototipo era plano: ni anidaba ni se plegaba.
     3. `.renglon` como enlace de htmx (cursor y estado ocupado).
   ========================================================================= */

/* 1. El andamio del prototipo no forma parte del producto. */
:root { --alto-navprot: 0rem; }

/* ==========================================================================
   2. EL ÁRBOL DEL RAIL — anidado y plegable
   ==========================================================================
   El rail del prototipo era una lista plana y la sangría se pintaba con
   `padding-inline-start` por nivel. Ahora las hijas viven DENTRO de la rama,
   que es lo único que permite plegarlas con ella, y la sangría la pone el
   anidamiento.

   Cada renglón del rail es una rejilla de dos columnas: el mando del pliegue
   y la carpeta. El mando ocupa su columna aunque la carpeta no tenga hijas,
   para que los iconos de TODOS los renglones —Entrada, Operación TI,
   Certificados— caigan en la misma vertical. Un árbol con los iconos
   desalineados no se lee como un árbol.

   El <details> va en `display: contents`: desaparece como caja y deja que su
   <summary> y su contenido sean piezas de la rejilla de la rama. Así el orden
   del documento es el natural —mando, carpeta, hijas— sin sacar nada de su
   sitio con posicionamiento absoluto.                                       */

.carpetas {
  /* El ancho de la columna del mando. Es también el paso de la sangría, que
     así queda amarrado a lo que de verdad tiene que caber ahí. */
  --carpetas-mando: var(--e-4);
}

.carpetas__rama {
  display: grid;
  grid-template-columns: var(--carpetas-mando) minmax(0, 1fr);
  align-items: center;
}
.carpetas__rama > .carpeta { grid-area: 1 / 2; }

.carpetas__pliegue { display: contents; }

/* El mando: sólo el chevron. El nombre de la carpeta NO entra aquí, porque
   una rama también es una carpeta que se abre; si el renglón entero plegara,
   no habría forma de leerla. */
.carpetas__mando {
  grid-area: 1 / 1;
  display: grid;
  place-items: center;
  block-size: var(--e-8);
  border-radius: var(--radio-1);
  color: var(--txt-3);
  cursor: pointer;
  list-style: none;                 /* fuera el triángulo del navegador */
}
.carpetas__mando::-webkit-details-marker { display: none; }
.carpetas__mando:hover { color: var(--txt-1); background: var(--hover-fila); }
.carpetas__mando:focus-visible {
  outline: var(--foco-anillo) solid var(--foco);
  outline-offset: var(--foco-separacion);
}

/* El chevron del sprite apunta a la derecha: cerrado señala hacia donde va a
   salir el contenido y abierto le da un cuarto de vuelta para señalarlo. Es
   el único movimiento del mando, y dice en qué se convirtió la rama. */
.carpetas__chevron {
  rotate: 0deg;
  transition: rotate var(--dur-2) var(--curva-estandar);
}
.carpetas__pliegue[open] > .carpetas__mando .carpetas__chevron { rotate: 90deg; }

/* El pliegue llega a su ALTO REAL, sin `max-height` de mentiras:
   `interpolate-size: allow-keywords` está encendido en tokens.css §9.b y es
   lo que hace animable `block-size: auto`. `--dur-desplegar` existe para
   esto, y con movimiento reducido se va a 1 ms sola. */
.carpetas__pliegue::details-content {
  grid-area: 2 / 1 / 3 / 3;
  block-size: 0;
  overflow: clip;
  transition: block-size var(--dur-desplegar) var(--curva-estandar),
              content-visibility var(--dur-desplegar) allow-discrete;
}
.carpetas__pliegue[open]::details-content { block-size: auto; }

/* La sangría y su guía. La regla vertical cae bajo el centro del mando del
   padre, así que la mirada baja del chevron a las hijas por una sola línea.
   Es un filete de registro, del mismo tono que las demás reglas. */
.carpetas__hijas {
  /* Red de seguridad para el navegador que todavía no tiene
     `::details-content`: ahí la lista es ella misma la pieza de la rejilla y
     sin esto caería dentro de la columna del mando, de 16 px. Donde el
     pseudoelemento SÍ existe esta línea no hace nada —la lista deja de ser
     pieza de la rejilla— y el pliegue sigue funcionando, sólo que sin
     animación, que es la degradación correcta. */
  grid-column: 1 / -1;
  margin-inline-start: calc(var(--carpetas-mando) / 2);
  padding-inline-start: var(--e-1);
  border-inline-start: 1px solid var(--regla-fina);
}
/* Cuanto más adentro, más callado el icono: la jerarquía también se lee en
   el tono, no sólo en la sangría. */
.carpetas__hijas .carpeta__icono { opacity: .72; }

/* LA CIFRA DE LA RAMA PLEGADA. Plegar tiene que esconder renglones, no
   información: con «Operación TI» cerrada, sus 7 sin leer siguen a la vista.
   Las dos cifras viajan siempre en el HTML y `:has()` elige cuál se ve, así
   que no hace falta ni un guion ni un segundo viaje al servidor.
   Siempre hay exactamente UNA visible: la otra es `display: none` y sale de
   la rejilla del renglón, que sólo tiene tres columnas. */
.carpetas__suma { display: none; }
.carpetas__rama:has(> .carpetas__pliegue:not([open])) > .carpeta > .carpeta__conteo {
  display: none;
}
.carpetas__rama:has(> .carpetas__pliegue:not([open])) > .carpeta > .carpetas__suma {
  display: block;
}

/* El rail plegado a 4 rem (app.css §16) es una tira de iconos sin nombres.
   Ahí el pliegue se retira: sin nombres no hay nada que ahorrar, y esconder
   ramas dejaría carpetas inalcanzables sin un mando visible con el que
   volver a abrirlas. El árbol se enseña entero y la cifra vuelve a ser la
   propia de cada carpeta.

   `:not(:popover-open)` acota esto a la TIRA. Por debajo de 50 rem el rail ya
   no es una tira: es el cajón de §10.d, y ahí sí hay ancho para los nombres,
   para la sangría y para el mando —así que el pliegue y su estado guardado
   siguen valiendo en el teléfono igual que en el escritorio—. Sin esta
   condición el cajón heredaba el árbol aplanado de la tableta. */
@media (max-width: 68rem) {
  .panel--carpetas:not(:popover-open) .carpetas { --carpetas-mando: 0px; }
  .panel--carpetas:not(:popover-open) .carpetas__mando { display: none; }
  .panel--carpetas:not(:popover-open) .carpetas__pliegue::details-content {
    block-size: auto;
    content-visibility: visible;
  }
  .panel--carpetas:not(:popover-open) .carpetas__hijas {
    margin-inline-start: 0;
    padding-inline-start: 0;
    border-inline-start: 0;
  }
  .panel--carpetas:not(:popover-open) .carpetas__rama:has(> .carpetas__pliegue:not([open])) > .carpeta > .carpeta__conteo {
    display: block;
  }
  /* Va después y con el mismo peso que la de arriba: si no, la suma —que
     también lleva `.carpeta__conteo`— se colaría junto a la cifra propia. */
  .panel--carpetas:not(:popover-open) .carpetas__rama:has(> .carpetas__pliegue:not([open])) > .carpeta > .carpetas__suma {
    display: none;
  }
}

/* ==========================================================================
   2.b LA CIFRA DEL RAIL SÓLO SE PINTA DONDE HAY PENDIENTES
   ==========================================================================
   Se contaron trece números encendidos a la vez en la columna izquierda, y de
   los trece sólo el de Entrada se mira a diario. Los demás son censo —cuántos
   contactos hay, cuántas reglas hay, cuántos mensajes guarda Resueltos— y un
   censo nunca se puede poner feo.

   No se borran: bajan a la segunda altura de visibilidad. Con `opacity` y no
   con `display` a propósito, por dos razones: la cifra sigue en el árbol de
   accesibilidad —quien navega con lector de pantalla no pierde el dato— y el
   renglón no cambia de ancho al pasar el cursor. `data-sin-leer` es el mismo
   atributo con el que app.css ya sube su tono: una sola verdad.             */

.carpeta__conteo:not([data-sin-leer]) {
  opacity: 0;
  transition: opacity var(--dur-1) var(--curva-estandar);
}
.carpeta:hover .carpeta__conteo,
.carpeta:focus-visible .carpeta__conteo,
.carpetas__rama:focus-within .carpeta__conteo { opacity: 1; }

/* ==========================================================================
   2.c EL TINTE DE LA RAMA
   ==========================================================================
   Un color por división de la clasificación, en el trazo del icono y en nada
   más. Lo trae el enlace en `--color-carpeta` con el valor que guarda
   `carpetas.color`, que es el NOMBRE de un token de tokens.css §4.8.d y nunca
   un color literal: así el mismo dato sirve en las dos ediciones.

   Es una línea sobre la regla que ya existía en app.css §5, con la misma
   especificidad y más abajo en la cascada, así que la carpeta sin tinte —las
   seis del buzón y todas las hijas— sigue exactamente como estaba. Y el
   estado activo, `.carpeta[aria-current] .carpeta__icono`, tiene más
   especificidad y sigue ganando: dónde estás pesa más que de qué rama es.   */

.carpeta__icono { color: var(--color-carpeta, var(--txt-3)); }

/* 3. El renglón es accionable: lo abre htmx, no un <a>.
   La transición de opacidad vive en el renglón en reposo y con retardo CERO:
   es el camino de VUELTA, y hacer esperar a quien ya tiene su respuesta es la
   mitad del parpadeo. */
/* EL CURSOR ANUNCIA LO QUE EL RENGLÓN HACE (integración 2026-08-09).
   Los atributos de htmx bajaron de la celda del asunto al <li>, así que hoy
   abre el 98.9 % del área del renglón; el cursor seguía apuntando sólo a la
   celda, o sea el 55 %. Un renglón que se puede pulsar entero y sólo lo dice
   en la mitad enseña a no pulsar la otra mitad.
   El criterio es DOS cosas, porque el producto abre un renglón de dos maneras
   distintas: `.renglon__cuerpo` cubre al que lleva dentro un enlace o una
   celda que abre (mensaje y resultado de búsqueda), y `[hx-get]` cubre al que
   se abre a sí mismo desde el <li> (la bandeja, contactos y el retenido de
   cuarentena). Comprobado plantilla por plantilla: los renglones de
   administración no tienen ninguna de las dos —no se abren pulsándolos, se
   abren desde su botón— y conservan el cursor de siempre. */
.renglon { cursor: default; transition: opacity var(--dur-1) var(--curva-estandar) 0s; }
.renglon:has(> .renglon__cuerpo),
.renglon[hx-get] { cursor: pointer; }
.registro[aria-busy="true"] { opacity: .55; }

/* AQUÍ ESTABA `.renglon.htmx-request { opacity: .45 }` (retirada en la
   integración del 2026-08-09). Apagaba el renglón que acabas de pulsar
   mientras volvía el servidor: el único acuse que había, y era el contrario
   del que hace falta —lo que se toca se enciende, no se apaga—. Se quedó sin
   un solo usuario cuando el retenido de cuarentena pasó a apuntar su
   `hx-indicator` al panel de lectura, que fue el último que la disparaba.
   Comprobado: no queda ningún `hx-indicator` apuntando a un renglón en todo
   el repositorio (los tres que hay señalan a #panelLectura y a #listaPie). */

/* 4. Formulario de acceso: el prototipo lo resolvía con JS de demostración. */
.acceso__error { margin-block-start: var(--e-4); }

/* 5. El pie de la lista lleva la paginación del registro. */
.lista__pie { display: flex; align-items: center; gap: var(--e-3);
              justify-content: space-between; }

/* ============================================================================
   PROMOVIDO EN LA INTEGRACIÓN
   Reglas que dos áreas escribieron cada una en su hoja y que en realidad son
   del producto entero: se cargan aquí, desde `base.html`, y por lo tanto
   valen en las ocho secciones. Sigue pendiente promoverlas a `app.css`, que
   es la hoja del prototipo y se conserva tal cual salió de él.
   ========================================================================= */

/* 6. El error que llega del servidor.
      `app.css` sólo muestra `.campo__error` cuando su `.campo` tiene un
      control con `aria-invalid`. El error de un POST no viene dentro de un
      campo: viene solo. Lo emiten los manejadores de `main.py` (CSRF, 404 de
      fragmento, 500) y lo emiten cuatro de las ocho secciones. Sin esta línea
      el mensaje existe en el DOM y nadie lo ve.
      Venía de `vista-carpetas-cuenta.css`, donde sólo servía en dos vistas. */
.campo__error[data-visible="true"] { display: flex; }

/* 7. El cuerpo del renglón como enlace.
      En la bandeja lo abre htmx sobre un `<span>`; en los resultados de
      búsqueda es un `<a>` de verdad, porque cada resultado vive en su propia
      carpeta y hay que navegar hasta ella. El renglón es la pieza compartida
      del producto, así que las dos formas se visten igual.
      Venía de `vista-busqueda.css`. */
a.renglon__cuerpo { color: inherit; text-decoration: none; }
a.renglon__cuerpo:focus-visible {
  outline: 2px solid var(--marca-500);
  outline-offset: -2px;
  border-radius: var(--radio-1);
}

/* 8. Las pestañas son enlaces, no capas que se muestran con JS: cada una es
      una página con su propia dirección. Sólo hay que quitarles el subrayado;
      el estado activo lo sigue diciendo `aria-selected`.
      Venía de `vista-busqueda.css`. */
a.pestana { text-decoration: none; }

/* 9. La salida a la búsqueda desde la paleta de comandos.
      Lo escrito que no corresponde a ningún comando es una búsqueda: la
      última opción de la paleta la ejecuta. Va separada del resto por una
      regla para que se lea como lo que es, la salida y no un comando más. */
.paleta__opcion--buscar {
  border-block-start: 1px solid var(--regla-fina);
  margin-block-start: var(--e-2);
  padding-block-start: var(--e-3);
}
.paleta__opcion--buscar b { font-weight: var(--peso-medio); color: var(--txt-1); }

/* ============================================================================
   10. EL TELÉFONO — arreglado durante el recorrido de la aplicación
   --------------------------------------------------------------------------
   Dos defectos reales a 390 px, los dos del mismo tipo: mandos que existen en
   el DOM y no se pueden tocar.
   ========================================================================= */

/* 10.a `.solo-movil`: el gemelo de `.solo-escritorio`, que `app.css` declara
        y no acompaña. Lo pedía `view-contactos.css` para su vista; aquí vale
        para el producto entero, que es de donde salía la necesidad. */
.solo-movil { display: none; }

@media (max-width: 50rem) {
  .solo-movil { display: inline-flex; }

  /* 10.b La cabecera de lectura no cabía y no avisaba.
     Con «← Registro», «Responder», «Reenviar» y tres botones icónicos de
     44 px, la fila medía 547 px dentro de 390: archivar y borrar quedaban
     fuera de la pantalla, sin barra que corriera hasta ellos. Ahora esos
     mandos viven en el menú «…» —el mismo patrón de la bandeja— y la
     cabecera no se desborda. Por si acaso, se le permite ceder. */
  .panel__cabecera { flex-wrap: wrap; row-gap: var(--e-2); }
  .panel__cabecera > .grupo-btn { min-width: 0; }

  /* 10.c Nota, no regla. `app.css` §16 apaga en el teléfono tanto las
     acciones del renglón como su casilla, así que desde la lista no se
     archiva, no se borra y no se selecciona: la única vía es abrir el
     mensaje. Con 10.b esa vía ya lleva a todas las acciones. Queda
     pendiente el gesto de deslizar sobre el renglón, que es lo que un
     teléfono espera y esto todavía no tiene. */
}

/* ==========================================================================
   10.d LA PUERTA AL RAIL EN EL TELÉFONO      (defecto grave, corregido)
   --------------------------------------------------------------------------
   A 390 y a 360 px `app.css` §16 apaga `.app__carpetas` y no dejaba ningún
   mando que lo trajera: sin el rail no se llegaba a Enviados, ni a Archivo,
   ni a la Papelera, ni a una sola carpeta de clasificación. El teléfono se
   quedaba con Entrada y con el menú de la cuenta.

   EL MECANISMO ES EL DEL SISTEMA, no uno nuevo: el rail lleva `popover` y con
   eso el navegador da las cuatro cosas que hacían falta sin una línea de
   guion —Escape lo cierra, tocar fuera lo cierra, el foco vuelve al botón que
   lo abrió y el botón entra con el tabulador—. Es el mismo mando que ya usan
   los menús de la barra (DISENO-SPEC §6).

   Y ES EL MISMO ELEMENTO en las dos anchuras. No hay una segunda copia del
   árbol para el teléfono: eso habría duplicado `#railArbol`, y con dos
   elementos del mismo identificador el intercambio fuera de banda deja de
   saber a cuál de los dos le toca. En el escritorio la hoja lo devuelve al
   flujo de la rejilla, que es lo que hace el bloque de abajo.               */

/* El botón. `.solo-movil` (§10.a) le da el `display`; aquí sólo su sitio y su
   traza. Va al filo inferior de arranque, lejos del pulgar que desplaza y
   fuera de la barra, que no es de esta pieza. Mientras el botón viva aquí y
   no en la barra, sólo aparece en las cuatro secciones que dibujan este rail;
   está anotado para integración. */
.rail-puerta {
  position: fixed;
  inset-block-end: var(--e-4);
  inset-inline-start: var(--e-4);
  z-index: var(--z-flotante);
  align-items: center;
  gap: var(--e-2);
  min-height: var(--toque-min);
  padding-inline: var(--e-4);
  font: inherit;
  font-size: var(--txt-2xs);
  color: var(--txt-1);
  background: var(--superficie-3);
  border: 1px solid var(--regla-media);
  border-radius: var(--radio-2);
  box-shadow: var(--sombra-2);
  cursor: pointer;
}
.rail-puerta:focus-visible {
  outline: var(--foco-anillo) solid var(--foco);
  outline-offset: var(--foco-separacion);
}

/* Y el sitio que ocupa se le descuenta al panel. Un mando fijo encima de una
   lista que se desplaza tapa su último renglón para siempre; con esto el
   final de cualquier panel se puede subir por encima del botón. Sólo en el
   teléfono, que es donde el botón existe. */
@media (max-width: 50rem) {
  .app .panel__cuerpo { padding-block-end: calc(var(--toque-min) + var(--e-4)); }
}

/* ESCRITORIO: el rail vuelve a ser una pieza de la rejilla. El navegador le
   pone a todo `[popover]` una caja centrada y flotante; estas líneas la
   deshacen. Se escriben todas a mano y no se confía en la cascada porque son
   reglas de la hoja del navegador, y ésas no se pueden leer desde aquí. */
@media (min-width: 50.0625rem) {
  .app__carpetas[popover] {
    display: flex;
    position: static;
    inset: auto;
    inline-size: auto;
    block-size: auto;
    max-inline-size: none;
    max-block-size: none;
    margin: 0;
    padding: 0;
    border: 0;
    overflow: hidden;
    color: inherit;
    background: var(--lienzo);
  }
}

/* TELÉFONO: cajón lateral. Entra deslizando desde el filo de arranque y sale
   por donde entró —«todo lo que se abre, se cierra»—, con `--dur-3` y las
   curvas del sistema, así que movimiento reducido lo apaga solo. */
@media (max-width: 50rem) {
  .app__carpetas[popover] {
    position: fixed;
    inset-block: 0;
    inset-inline: 0 auto;
    inline-size: min(19rem, 84vw);
    max-inline-size: none;
    max-block-size: none;
    margin: 0;
    padding: 0;
    border: 0;
    border-inline-end: 1px solid var(--regla-fina);
    color: inherit;
    background: var(--lienzo);
    translate: -100% 0;
    transition: translate var(--dur-3) var(--curva-entrada),
                display var(--dur-3) allow-discrete,
                overlay var(--dur-3) allow-discrete;
  }
  .app__carpetas[popover]:popover-open {
    display: flex;
    translate: 0 0;
    transition-timing-function: var(--curva-salida);
  }
  @starting-style {
    .app__carpetas[popover]:popover-open { translate: -100% 0; }
  }
  .app__carpetas[popover]::backdrop {
    background: var(--velo);
    opacity: 0;
    transition: opacity var(--dur-3) var(--curva-entrada),
                display var(--dur-3) allow-discrete,
                overlay var(--dur-3) allow-discrete;
  }
  .app__carpetas[popover]:popover-open::backdrop { opacity: 1; }
  @starting-style {
    .app__carpetas[popover]:popover-open::backdrop { opacity: 0; }
  }

  /* Dentro del cajón el rail se enseña entero: no es la tira de iconos de la
     tableta (app.css §16 lo pliega a 4rem por debajo de 68rem, y el teléfono
     también entra en esa consulta). Aquí hay ancho para los nombres. */
  .app__carpetas[popover] .carpeta__nombre,
  .app__carpetas[popover] .carpetas__titulo,
  .app__carpetas[popover] .cuota__texto { display: block; }
  .app__carpetas[popover] .carpeta {
    grid-template-columns: 1.125rem minmax(0, 1fr) auto;
    justify-items: start;
    padding-inline: var(--e-3);
  }
  .app__carpetas[popover] .carpeta__conteo {
    position: static;
    margin: 0;
    font-size: var(--txt-2xs);
  }
}

/* ==========================================================================
   5. EL SEGMENTADO — elegir una de pocas opciones excluyentes
   ==========================================================================
   Lo estrena el conmutador de apariencia del menú de la cuenta. Es un grupo
   de botones de envío, no un <select> ni un interruptor: las opciones son
   pocas, todas caben a la vista, y así funciona sin JavaScript.

   Cuál está puesta se dice con `aria-pressed`, que es lo que lee un lector
   de pantalla, y el CSS se cuelga de ESE atributo en vez de una clase: una
   sola verdad, imposible que la vista y la semántica se desincronicen.     */

.menu__apariencia {
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  padding: var(--e-1) var(--e-3) var(--e-3);
}

.apariencia {
  display: flex;
  padding: 2px;
  background: var(--superficie-hundida);
  border: 1px solid var(--regla-fina);
  border-radius: var(--radio-2);
}

.apariencia__opcion {
  flex: 1;
  padding: var(--e-1) var(--e-2);
  font: inherit;
  font-size: var(--txt-2xs);
  color: var(--txt-3);
  background: transparent;
  border: 0;
  border-radius: var(--radio-1);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur-1) var(--curva-estandar),
              color var(--dur-1) var(--curva-estandar);
}
.apariencia__opcion:hover { color: var(--txt-1); background: var(--hover-fila); }
.apariencia__opcion:focus-visible {
  outline: var(--foco-anillo) solid var(--foco);
  outline-offset: var(--foco-separacion);
}
.apariencia__opcion[aria-pressed="true"] {
  color: var(--txt-1);
  background: var(--superficie-3);
  box-shadow: var(--sombra-1);
}

/* ==========================================================================
   6. DENSIDAD DEL REGISTRO
   ==========================================================================
   `--renglon-aire` y `--renglon-previa` los declara tokens.css §10.c. Aquí
   sólo se enganchan al renglón que ya existe. En compacta el registro pierde
   la tercera línea —la vista previa— y se queda en dos: remitente y asunto.

   En pantalla táctil NO se aplica el recorte: el renglón tiene que seguir
   midiendo --toque-min de alto. Se detecta con `pointer: coarse`, no con el
   ancho: una tableta ancha también se toca con el dedo.                    */

@media (pointer: fine) {
  /* El aire del renglón NO se engancha aquí: vive en las celdas y, cuando el
     renglón se pliega a dos líneas, en celdas concretas del pliegue. Las
     siete declaraciones de app.css ya piden `--renglon-aire` en vez de
     `--e-3`, así que la densidad manda desde el token y esta hoja sólo
     resuelve lo que app.css no contempla: la vista previa y el rail.

     Se descubrió midiendo: con el gancho puesto sobre `.renglon__cuerpo`, el
     paso entre renglones no se movía ni un pixel, porque el pliegue de
     escritorio pone ese relleno a cero y lo reparte entre las dos líneas. */
  :root[data-densidad="compacta"] .renglon__previa { display: var(--renglon-previa); }
  :root[data-densidad="compacta"] .carpeta { padding-block: var(--rail-aire); }
}
