/* La interfaz del gestor.
 *
 * ===========================================================================
 * DE DONDE SALE ESTO (`docs/19`)
 *
 * La identidad de Amura ya existia y el gestor de hoy no la usaba: corre sobre
 * un theme de Bootstrap comprado, con el verde pegado encima como acento. Acá se
 * hace al reves — la marca manda y la estructura sale de ella.
 *
 * Dos cosas que dice el logo (`assets/marca/`):
 *   1. La marca son DOS PLANOS DIAGONALES que se cruzan. "Amura" es la parte del
 *      velero donde el viento entra en la vela. **La diagonal es la forma de la
 *      marca**, no un adorno: acá es el borde entre la herramienta y los datos.
 *   2. El color no es un verde, son CUATRO, y el logo los usa juntos para dar
 *      profundidad. Se usan como familia, no como un acento sobre grises.
 *
 * Es una HERRAMIENTA DE TRABAJO: densa, precisa, con la informacion cerca. Quien
 * la usa entra todos los dias, apurado, y muchas veces en una maquina vieja.
 * Por eso el gesto fuerte va en UN solo lugar —el plano diagonal— y todo lo
 * demas se calla.
 *
 * TIPOGRAFIAS (`docs/19`, corregido por Hernan: **el logo esta hecho en Futura
 * Round**). Eso fija la voz de la marca: geometrica, circular, de trazo parejo.
 * Con esa pista el sistema son tres papeles y no uno:
 *
 *   DISPLAY  la voz de la marca. Geometrica como el logo. Se usa POCO y grande:
 *            el nombre del diario, las cifras, los titulos de pantalla. Una
 *            geometrica tiene la x chica — a 13px en una tabla se lee peor que
 *            una humanista, asi que no baja de ahi.
 *   TEXTO    la letra de trabajo: formularios, listados, botones. Tiene que
 *            aguantar densidad y pantallas viejas de redaccion.
 *   DATO     lo que se alinea en columna: fechas, dominios, permisos, numeros.
 *
 * Futura Round es de PAGO y no tenemos licencia web, asi que el papel de display
 * lo cubre **Nunito** (SIL OFL), elegida por Hernan sobre Jost y Quicksand. Es la
 * que tiene las terminaciones REDONDEADAS del logo —lo que le da el "Round"— a
 * cambio de proporciones mas humanistas que geometricas: se lee mejor y se
 * parece un poco menos a la construccion de la marca. El dia que haya licencia
 * se cambia UNA linea —la familia de `--display`— y no se toca nada mas.
 * Ver `assets/tipografias/README.md`.
 * =========================================================================== */

/* Las fuentes se sirven desde `assets/tipografias/`. El token `FUENTE:` lo
 * resuelve el servidor a la URL con el hash del ARCHIVO adentro, igual que hace
 * con esta hoja: si cambia la fuente, cambia la URL, y no hay que purgar nada.
 * Un nombre mal escrito revienta al arrancar en vez de caer al font del sistema
 * sin que nadie lo note. */
@font-face {
  font-family: "Nunito";
  font-style: normal;
  font-weight: 300 800;   /* variable: un solo archivo para toda la escala */
  font-display: swap;
  src: url("/tipografias/nunito-variable.ba344451.woff2") format("woff2");
}
@font-face {
  font-family: "Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/tipografias/plex-sans-400.3b646991.woff2") format("woff2");
}
@font-face {
  font-family: "Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/tipografias/plex-sans-600.8960851d.woff2") format("woff2");
}
@font-face {
  font-family: "Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/tipografias/plex-mono-400.08949f72.woff2") format("woff2");
}
@font-face {
  font-family: "Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/tipografias/plex-mono-600.0d1f0b8d.woff2") format("woff2");
}

:root {
  /* la familia Amura, del logo */
  --verde-claro: #0fcea9;
  --verde: #00a78a;
  --verde-medio: #0c7762;
  --verde-hondo: #075b4b;

  /* la tinta no es negra: es la familia llevada al fondo */
  --tinta: #04211c;
  --tinta-suave: #0d3b32;
  --apagado: #5d6b68;
  --linea: #dbe3e0;
  --papel: #ffffff;
  --fondo: #eef2f1;

  /* La linea de abajo es el punto de cambio: con licencia de Futura Round, entra
     primera y el resto queda de respaldo. */
  --display: "Futura Round", "Nunito", "Futura", "Century Gothic", system-ui, sans-serif;
  --texto: "Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --dato: "Plex Mono", ui-monospace, "Cascadia Mono", "Consolas", monospace;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--fondo);
  color: var(--tinta);
  font-family: var(--texto);
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

/* --- los enlaces ----------------------------------------------------------
 * UNA REGLA BASE, y faltaba. Todo enlace sin clase propia —la URL publica de la
 * ficha, los avisos, los textos de ayuda— caia en el azul del navegador y, peor,
 * en el VIOLETA de visitado. Dos colores que no son de la marca y que ademas
 * cambian solos segun por donde paso la persona: la misma pantalla se ve
 * distinta en dos maquinas sin que nada haya cambiado.
 *
 * `:visited` se iguala a proposito. En un sitio sirve —dice que paginas ya
 * leiste—; en una aplicacion no se explora, se trabaja, y lo unico que hace es
 * tenir de violeta la mitad de las pantallas que uno mas usa.
 *
 * Es un PISO, no una imposicion: lo que tiene color propio (botones, acciones,
 * chips, el lateral) lo pisa por especificidad. Y no se toca `:hover` acá, justo
 * por eso — un `a:hover` con color le ganaria a `.acc` y le cambiaria el color a
 * los iconos de accion al pasar por encima. */
a { color: var(--verde-hondo); }
/* `:where(:visited)` y no `:visited` a secas: una pseudoclase suma especificidad
   —(0,1,1)— y le ganaria a `.btn { color: #fff }`, que es una clase. Se vio en el
   acto: el boton "Nueva nota", una vez visitado, quedaba con la letra verde
   sobre el verde del boton, o sea vacio. `:where()` aporta cero, asi que esto
   pesa lo mismo que `a` y cualquier componente lo pisa. */
a:where(:visited) { color: var(--verde-hondo); }

/* --- la marca ------------------------------------------------------------- */
.logo { display: block; width: 2.2rem; height: auto; }
.logo .plano-claro { fill: var(--verde-claro); }
.logo .plano-base  { fill: var(--verde); }
.logo .plano-medio { fill: var(--verde-medio); }
.logo .plano-hondo { fill: var(--verde-hondo); }

/* --- rotulo: la etiqueta chica que ordena cada bloque ---------------------
 * Va en la GEOMETRICA aunque sea chica, y es el unico lugar donde eso funciona:
 * el problema de una geometrica en tamano chico es la x baja, y en versalita no
 * hay minusculas. Las mayusculas anchas con tracking abierto son ademas lo que
 * mejor hace una Futura. La marca aparece dos veces por pantalla —el nombre del
 * diario y estas etiquetas— y en el medio no molesta. */
.rotulo {
  font-family: var(--display);
  font-size: .7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .18em;
  color: var(--apagado);
}

/* =========================================================================
   ENTRADA
   ========================================================================= */
.entrada {
  min-height: 100vh;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 25rem);
  background: var(--papel);
}

.entrada__form {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 3rem clamp(1.5rem, 6vw, 5rem);
}

.entrada__caja { width: 100%; max-width: 23rem; margin-inline: auto; }

.entrada__marca { display: flex; align-items: center; gap: .7rem; margin-bottom: 2.2rem; }
.entrada__marca .rotulo { margin: 0; }

/* El nombre del diario, en la voz de la marca. El tracking es el del logo: muy
   cerrado. Una geometrica lo aguanta —las letras son circulos y rectas— donde
   una humanista se empastaria. */
.sitio {
  font-family: var(--display);
  font-size: clamp(1.8rem, 3.6vw, 2.3rem);
  font-weight: 700;
  letter-spacing: -.035em;
  line-height: 1.05;
  margin: 0;
}

.regla {
  height: 4px;
  width: 3.5rem;
  margin: 1rem 0 1.7rem;
  /* los cuatro verdes, en el orden del logo */
  background: linear-gradient(90deg,
    var(--verde-claro) 0 25%, var(--verde) 25% 50%,
    var(--verde-medio) 50% 75%, var(--verde-hondo) 75% 100%);
}

h2.titulo-form {
  font-size: .95rem;
  font-weight: 600;
  margin: 0 0 1.4rem;
  color: var(--apagado);
}

/* --- campos ---------------------------------------------------------------
 * OTRA VEZ EL `>`, y ya son tres veces la misma historia (ver `docs/22`):
 * `.campo label` (sin `>`) alcanzaba TODOS los labels de adentro, así que los de la lista
 * de autores —que son `<label>` con su casillero— heredaban `display: block` y
 * el nombre se iba al renglón siguiente, pegado a la derecha. Se veía roto y lo
 * marcó Hernán.
 *
 * La regla habla de **la etiqueta de este campo**, no de cualquier `<label>` que
 * cuelgue abajo. Lo mismo pasó con `select` (la barra del editor) y con el
 * `background` de la caja de recuperar. */
.campo { margin-bottom: 1rem; }
.campo > label {
  display: block;
  font-size: .77rem;
  font-weight: 600;
  letter-spacing: .02em;
  margin-bottom: .3rem;
}
/* ===========================================================================
 * LOS CONTROLES DE FORMULARIO, definidos UNA vez y sobre el elemento.
 *
 * Estaban definidos TRES veces —`.campo >`, `.ficha .campo >` y `.buscar`— con
 * tres paddings distintos, y ninguna de las tres alcanzaba a un control que no
 * estuviera envuelto en un campo. O sea que un `<select>` suelto en una tabla
 * salía crudo del navegador, con su borde negro y su flecha, al lado de inputs
 * del sistema. Lo marcó Hernán: *"¿no tenemos los estilos para que todos los
 * input y todos los select se vean iguales?"*.
 *
 * Ahora la regla vive en el ELEMENTO y las variantes solo cambian lo que de
 * verdad cambia (el tamaño del buscador, el ancho de un campo). Es la misma
 * lección que ya estaba escrita acá abajo y que se había aplicado a medias: si
 * una regla aparece dos veces en dos pantallas, el lugar donde va es este.
 *
 * La lista de exclusiones es fea y es la única forma que da CSS de decir "un
 * campo donde se escribe": no existe un selector para eso.
 *
 * ⚠️ VA ENVUELTA EN `:where()` Y ESO NO ES ESTILO. `:not()` **suma la
 * especificidad de su argumento**: con los ocho `:not([type=…])` sueltos, esta
 * regla pesaba (0,8,1) y le ganaba a cualquier clase — o sea que un widget que
 * resetea su input interno (`.tags__nuevo { border: 0 }`) dejaba de poder
 * hacerlo, y los tags aparecían con doble borde. `:where()` aporta cero, así
 * que el selector vuelve a pesar (0,0,1): lo que tiene que pesar una regla que
 * define el aspecto POR DEFECTO de un elemento. */
input:not(:where([type="checkbox"], [type="radio"], [type="file"], [type="color"],
            [type="range"], [type="submit"], [type="button"], [type="reset"])),
select,
textarea {
  font: inherit;
  color: inherit;
  padding: .5rem .65rem;
  border: 1px solid var(--linea);
  border-radius: 2px;
  /* `background-color` Y NO `background`. El atajo escribe las OCHO propiedades,
     asi que le borra la flecha al `<select>` de mas abajo — ver el comentario del
     `:focus-visible`, que es donde esto se veia. */
  background-color: var(--papel);
  transition: border-color .12s, box-shadow .12s;
}
textarea { resize: vertical; }

input:not(:where([type="checkbox"], [type="radio"], [type="file"], [type="color"],
            [type="range"], [type="submit"], [type="button"], [type="reset"])):focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 0;
  border-color: var(--verde);
  box-shadow: 0 0 0 3px rgba(0, 167, 138, .18);
  /* ⚠️ ACÁ DECÍA `background: #fff` Y SE LLEVABA PUESTAS LAS FLECHAS.
   *
   * Lo vio Hernán en Chrome —usa Firefox, y ahí no pasa—: *"cuando desplegás el
   * select de «Trabajando en» se ven muchas flechas, está raro"*.
   *
   * `background` es un ATAJO: escribe las ocho propiedades, y las que no se
   * nombran vuelven a su valor inicial. Así que este `#fff` no cambiaba un
   * color: apagaba `background-image` y devolvía `background-repeat` y
   * `background-size` a `repeat` y `auto`, pisando la regla del `<select>` de
   * más abajo. Y le gana porque pesa (0,1,1) contra (0,0,1).
   *
   * Se veía de dos formas, las dos por lo mismo:
   *   - un select cualquiera: al enfocarlo **se le iba la flecha**, y volvía al
   *     salir. Chico, y por eso no lo reportó nadie en un año.
   *   - el del lateral: `.lateral__cab select` pesa (0,1,1) y viene DESPUÉS, así
   *     que reponía la flecha clara... pero sólo `background-image`. `repeat` y
   *     `size` quedaban en su valor inicial, o sea la flecha a tamaño natural y
   *     **repetida a lo ancho de la caja**. Eso son las muchas flechas.
   *
   * Y que se vea en un navegador y no en el otro no es cosa del dibujo: Chrome
   * hace coincidir `:focus-visible` en un `<select>` al que se le hizo clic con
   * el mouse, y Firefox no. Con el teclado se ve en los dos. */
  background-color: #fff;
}

/* EL DESPLEGABLE, con su propia flecha.
 *
 * `appearance: none` apaga el control nativo —que es el que traía el borde negro
 * y el triángulo del sistema— y la flecha se dibuja de fondo. Va en SVG embebido
 * y no en una fuente de iconos: es un archivo menos que pedir y no depende de que
 * cargue nada para que el desplegable se vea completo.
 *
 * `select[multiple]` y `select[size]` vuelven al nativo: ahí no hay flecha que
 * dibujar y apagar la apariencia rompe la lista. */
select {
  appearance: none;
  padding-right: 1.9rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%235d6b68' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .65rem center;
  background-size: .7rem;
  cursor: pointer;
}
select[multiple], select[size] {
  appearance: auto;
  padding-right: .65rem;
  background-image: none;
}

/* CASILLAS Y RADIOS PROPIOS.
 *
 * Eran los del navegador —azules, de 13 px, distintos en cada sistema— adentro de
 * una interfaz que cuida el resto. Y en una tabla como la de "Publicar en" son el
 * control que más se mira.
 *
 * Se dibujan con `appearance: none` y una marca de `::before`, NO con una imagen
 * de fondo: así heredan el color del sistema y no hay un archivo que cargar. Lo
 * que NO se toca es el comportamiento — siguen siendo un `input` de verdad, con
 * su foco, su navegación por teclado y su lectura de pantalla. */
input[type="checkbox"], input[type="radio"] {
  appearance: none;
  flex: 0 0 auto;
  width: 1.05rem;
  height: 1.05rem;
  margin: 0;
  display: inline-grid;
  place-content: center;
  border: 1px solid #b9c6c2;
  background: var(--papel);
  cursor: pointer;
  transition: background-color .12s, border-color .12s, box-shadow .12s;
}
input[type="checkbox"] { border-radius: 3px; }
input[type="radio"] { border-radius: 50%; }

input[type="checkbox"]:checked, input[type="radio"]:checked {
  background: var(--verde);
  border-color: var(--verde);
}
/* El tilde es un ángulo girado, no un carácter: una tipografía que no tenga el
 * glifo dejaría la casilla marcada y vacía. */
input[type="checkbox"]:checked::before {
  content: "";
  width: .3rem; height: .55rem;
  margin-top: -.12rem;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
/* NI MARCADA NI VACIA: la casilla de un grupo con ALGUNOS adentro puestos.
 *
 * ⚠️ HAY QUE DIBUJARLA A MANO. Con `appearance: none` el navegador deja de
 * dibujar el guioncito nativo, asi que sin esta regla el estado intermedio se ve
 * EXACTAMENTE igual que vacio. Lo destapo la pantalla de roles: la cabecera de la
 * seccion decia «1/5» con la casilla en blanco — dos cosas contradiciendose en el
 * mismo renglon, y la unica pista de que la casilla hace algo.
 *
 * Va con el resto de los controles y no en el bloque de roles: es del kit. La
 * proxima casilla de grupo que aparezca la hereda sin acordarse de nada. */
input[type="checkbox"]:indeterminate {
  background: var(--verde);
  border-color: var(--verde);
}
input[type="checkbox"]:indeterminate::before {
  content: "";
  width: .5rem;
  border-top: 2px solid #fff;
}
input[type="radio"]:checked::before {
  content: "";
  width: .42rem; height: .42rem;
  border-radius: 50%;
  background: #fff;
}
input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible {
  outline: 0;
  border-color: var(--verde);
  box-shadow: 0 0 0 3px rgba(0, 167, 138, .25);
}
input[type="checkbox"]:disabled, input[type="radio"]:disabled {
  opacity: .5;
  cursor: not-allowed;
}
/* ======================================================================== */

/* El campo los estira y les da un poco más de aire que un control suelto. */
.campo > input, .campo > select, .campo > textarea {
  width: 100%;
  font: inherit;
  padding: .64rem .75rem;
  border: 1px solid var(--linea);
  border-radius: 2px;
  /* La MISMA trampa del `:focus-visible` de arriba, y acá era peor: como pesa
     (0,1,2), le ganaba a la regla del `<select>` SIEMPRE, no sólo al enfocar.
     O sea que **un desplegable dentro de un campo no tenía flecha nunca** —con
     `appearance: none` puesto, un desplegable que no parece un desplegable—. Se
     comprobó midiendo en el gestor: `.campo > select` daba `background-image:
     none` y un select suelto daba la flecha. Toca la ficha, etiquetas y
     navegación, que son las tres pantallas que ponen un select en un campo. */
  background-color: #fbfdfc;
  color: inherit;
  transition: border-color .12s, box-shadow .12s;
}
.campo > textarea { resize: vertical; }
.campo > input:focus-visible, .campo > select:focus-visible, .campo > textarea:focus-visible {
  outline: 0;
  border-color: var(--verde);
  box-shadow: 0 0 0 3px rgba(0, 167, 138, .18);
  background-color: #fff;
}

/* La ayuda va DEBAJO del control, no al costado.
 *
 * Sin esto el `<small>` queda en línea y se lee como parte del control de al
 * lado. Estaba escrito —igual— en `.ficha` y en `.media__form`; acá vale para
 * todos, incluida la pantalla que se escriba mañana. */
.campo > small { display: block; margin-top: .25rem; font-size: .78rem; color: var(--apagado); }

/* La misma ayuda, pero de un GRUPO y no de un campo: la que explica un
   formulario entero o un juego de opciones. `.ayuda` se venia usando en
   Publicidad y en Portada SIN NINGUNA REGLA —era un `<p>` comun—, asi que salia
   del tamaño y del color del texto principal y competia con lo que explica. Con
   tope de ancho por lo mismo que `.pest__ayuda`: un renglon de noventa
   caracteres se lee dos veces. */
.ayuda {
  margin: .4rem 0 1rem; font-size: .82rem; color: var(--apagado); max-width: 44rem;
}
.ayuda b, .ayuda strong { color: var(--tinta); font-weight: 600; }

/* El error no se disculpa y no dice cual de los dos campos fallo. */
.error {
  border-left: 3px solid #a3231f;
  background: #fdf4f3;
  color: #8d1e1a;
  padding: .55rem .75rem;
  margin-bottom: 1.1rem;
  font-size: .88rem;
}

.pie-form {
  margin-top: 1.7rem;
  padding-top: 1rem;
  border-top: 1px solid var(--linea);
  font-size: .8rem;
  color: var(--apagado);
}

/* =========================================================================
   EL PULSO — el plano diagonal, y lo que hace distinta a esta pantalla
   Un editor abre el gestor a la manana y lo primero que quiere saber es hace
   cuanto publico el sitio. Son datos que ya son publicos: no aparece nada que
   no se vea entrando al diario.
   ========================================================================= */
.pulso {
  position: relative;
  background:
    linear-gradient(157deg, var(--tinta-suave) 0%, var(--tinta) 55%, #021512 100%);
  color: #dfeae7;
  padding: 3rem 2rem 2.5rem 0;
  display: flex;
  flex-direction: column;
  gap: 1.7rem;
  /* LA DIAGONAL: el borde izquierdo no es recto. Es la forma del logo. */
  clip-path: polygon(3.2rem 0, 100% 0, 100% 100%, 0 100%);
  margin-left: -3.2rem;
}

/**
 * Los bloques ESCALONAN con la pendiente, como los planos de la marca.
 *
 * El filo se corre a la izquierda al bajar, asi que un margen fijo dejaria el
 * hueco creciendo de arriba hacia abajo. Y hacer que el texto siga la diagonal
 * linea por linea (`shape-outside`) seria peor: un borde izquierdo irregular es
 * mas dificil de escanear, y estos son bloques sueltos, no parrafos que fluyen —
 * quedaria accidental en vez de deliberado.
 *
 * Escalonando, cada bloque queda alineado adentro (legible) y el conjunto sigue
 * la pendiente (deliberado). Los valores bajan al ritmo de la diagonal.
 */
.pulso > :nth-child(1) { padding-left: 5.2rem; }
.pulso > :nth-child(2) { padding-left: 4.3rem; }
.pulso > :nth-child(3) { padding-left: 3.1rem; }
.pulso .rotulo { color: #6f8b84; }

/* el filo de la diagonal, en el verde vivo */
.pulso::before {
  content: "";
  position: absolute;
  inset: 0;
  clip-path: polygon(3.2rem 0, 3.4rem 0, .2rem 100%, 0 100%);
  background: var(--verde);
}

.pulso__dominio { font-family: var(--dato); font-size: .75rem; color: #6f8b84; }

.estado { display: flex; align-items: center; gap: .5rem; margin-top: .5rem; }
.punto {
  width: .45rem; height: .45rem; border-radius: 50%;
  background: var(--verde-claro);
  box-shadow: 0 0 0 0 rgba(15, 206, 169, .5);
  animation: latir 2.8s ease-out infinite;
}
.estado span { font-size: .82rem; color: #b6cbc6; }

@keyframes latir {
  0%   { box-shadow: 0 0 0 0 rgba(15, 206, 169, .45); }
  70%  { box-shadow: 0 0 0 .55rem rgba(15, 206, 169, 0); }
  100% { box-shadow: 0 0 0 0 rgba(15, 206, 169, 0); }
}
@media (prefers-reduced-motion: reduce) { .punto { animation: none; } }

.ultima { border-top: 1px solid rgba(255, 255, 255, .1); padding-top: 1.2rem; }
.pulso > .ultima { padding-left: 4.3rem; }
.ultima__hace {
  font-family: var(--display);
  font-size: 2.1rem;
  font-weight: 800;
  letter-spacing: -.04em;
  line-height: 1;
  margin: .4rem 0 .5rem;
  color: #fff;
}
.ultima__titulo { font-size: .87rem; color: #b6cbc6; }
.ultima__vacio { font-size: .87rem; color: #6f8b84; }

.cifras { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; margin-top: auto; }
.cifra__n {
  font-family: var(--dato);
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--verde-claro);
  display: block;
}

/* =========================================================================
   PANEL (despues de entrar)
   ========================================================================= */
/* --- el menu, al costado -------------------------------------------------
 * La primera version fue una barra arriba y la corrigio Hernan con lo que ya le
 * paso en Amura: arriba se llena. Un menu horizontal tiene el ancho de la
 * pantalla y nada mas; uno vertical crece hacia abajo. Y el submenu, que arriba
 * obliga a un desplegable —estado oculto, hover, JavaScript—, acá se abre EN
 * LINEA y lo abre la ruta. El razonamiento completo esta en `ui/armazon.ts`. */
.tablero {
  display: grid;
  grid-template-columns: 15rem minmax(0, 1fr);
  min-height: 100vh;
  /* Corta, porque es respuesta a un click y no un efecto: si tarda, molesta. */
  transition: grid-template-columns .16s ease;
}
@media (prefers-reduced-motion: reduce) { .tablero { transition: none; } }

/* EL LATERAL ES UNA COLUMNA FIJA, DE LA ALTURA DE LA PANTALLA.
 * Lo marco Hernan: antes crecia con la pagina, asi que en un listado largo el
 * nombre, Salir y Minimizar quedaban a tres pantallas de scroll — o sea que las
 * acciones que estan SIEMPRE disponibles dejaban de estarlo justo donde mas se
 * navega. Ahora se queda pegado arriba (`sticky`) y mide `100dvh`: el pie
 * apoya en el borde de abajo de la pantalla, no en el del documento.
 * `align-self: start` es lo que lo hace posible — sin eso la grilla lo estira a
 * lo alto de la pagina y no queda nada contra que pegarse.
 * El que se desborda es el MENU, no el lateral, asi que el filo y el pie no se
 * van con el scroll. */
.lateral {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100dvh;
  background: var(--tinta);
  color: #dfeae7;
  padding: 1.4rem 1rem 1.2rem;
  display: flex;
  flex-direction: column;
  gap: 1.3rem;
}
/* El filo: los cuatro verdes del logo, de pie. Es la misma regla de la entrada
   puesta a lo largo del borde — la marca firma el borde, no el fondo. */
.lateral::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0; right: 0;
  width: 3px;
  background: linear-gradient(180deg,
    var(--verde-claro) 0 25%, var(--verde) 25% 50%,
    var(--verde-medio) 50% 75%, var(--verde-hondo) 75% 100%);
}

.lateral__marca {
  display: flex; align-items: center; gap: .55rem;
  text-decoration: none; color: inherit;
}
.lateral .logo { width: 1.6rem; }
.lateral .sitio { font-size: 1.15rem; color: #fff; }
.lateral__marca:focus-visible { outline: 2px solid var(--verde-claro); outline-offset: 3px; }

/* El menu se queda con el hueco del medio y es EL UNICO que se desborda: si el
 * dia de mañana hay quince destinos, scrollea el menu y el pie no se mueve.
 * `min-height: 0` porque un item flex no achica por debajo de su contenido y sin
 * eso el desborde se lo comeria la pagina entera. */
.menu { display: flex; flex-direction: column; gap: 1.3rem;
  flex: 1; min-height: 0; overflow-y: auto; }
.menu__grupo { display: flex; flex-direction: column; gap: .1rem; }
.menu__titulo { color: #55706b; margin: 0 0 .35rem .55rem; }

.menu__item {
  position: relative;
  display: block;
  font-size: .9rem;
  font-weight: 600;
  color: #b6cbc6;
  text-decoration: none;
  padding: .38rem .55rem;
  border-radius: 2px;
}
.menu__item:hover { color: #fff; background: rgba(255, 255, 255, .05); }
.menu__item:focus-visible { outline: 2px solid var(--verde-claro); outline-offset: -2px; }

/* El activo lleva el filo a la izquierda: el mismo gesto del borde, en chico. */
.menu__item[aria-current="page"] { color: #fff; background: rgba(255, 255, 255, .06); }
.menu__item[aria-current="page"]::before {
  content: "";
  position: absolute;
  left: -1rem; top: 0; bottom: 0;
  width: 3px;
  background: var(--verde-claro);
}

/* El submenu no se despliega: esta abierto cuando estas adentro. Sin estado que
   recordar, sin hover, sin una linea de JavaScript. */
.menu__hijos {
  display: flex; flex-direction: column;
  margin: .1rem 0 .3rem .55rem;
  padding-left: .7rem;
  border-left: 1px solid #23433d;
}
.menu__item--hijo { font-size: .84rem; font-weight: 400; padding: .28rem .55rem; }

/* Lo que todavia no existe se muestra apagado en vez de mentir con un link roto.
   Va desapareciendo solo a medida que entra cada pantalla. */
.menu__item--pronto { color: #55706b; cursor: default; }
.menu__item--pronto:hover { background: none; color: #55706b; }

/* Lo unico verde del lateral. Si hubiera tres acciones destacadas no habria
   ninguna: "nueva nota" es lo que mas se hace en el dia. */
.accion {
  display: block;
  text-align: center;
  font-size: .87rem;
  font-weight: 600;
  color: #fff;
  text-decoration: none;
  background: var(--verde-hondo);
  border: 1px solid var(--verde-medio);
  border-radius: 2px;
  padding: .45rem .8rem;
}
.accion:hover { background: var(--verde-medio); border-color: var(--verde); }
.accion:focus-visible { outline: 2px solid var(--verde-claro); outline-offset: 2px; }

.lateral__pie {
  margin-top: auto;
  padding-top: 1rem;
  border-top: 1px solid #23433d;
  display: flex; flex-direction: column; gap: .15rem;
}
.lateral__pie .quien { font-size: .87rem; font-weight: 600; color: #fff; margin: 0; }
.lateral__pie .rotulo { margin: 0 0 .4rem; }
/* Sin subrayado (lo pidio Hernan): un subrayado permanente los hacia parecer dos
 * links sueltos abajo de todo. El aviso de "esto se puede tocar" lo da el fondo
 * al pasar por encima, que es lo mismo que hacen los destinos del menu. */
.lateral__pie button { display: flex; align-items: center; gap: .5rem;
  font: inherit;
  font-size: .84rem;
  align-self: flex-start;
  background: none;
  border: 0;
  border-radius: 2px;
  color: #9fb5b0;
  padding: .25rem .4rem;
  margin-left: -.4rem;
  cursor: pointer;
}
.lateral__pie button:hover { background: #23433d; color: #fff; }

/* --- que algo esta pasando -------------------------------------------------
 * Con la navegacion por fetch, un pedido lento se veria como "el click no hizo
 * nada", que es la peor forma de fallar. Esta barra aparece recien a los 150ms:
 * lo que tarda poco no tiene que parpadear. */
.cargando::before {
  content: "";
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--verde-claro);
  transform-origin: 0 50%;
  animation: avanzar 8s cubic-bezier(.1, .8, .2, 1) 150ms both;
  z-index: 99;
}
@keyframes avanzar {
  0% { transform: scaleX(0); opacity: 1; }
  100% { transform: scaleX(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .cargando::before { animation: none; } }

/* --- los iconos ------------------------------------------------------------ */
.ico { width: 1.15rem; height: 1.15rem; flex: none; }
.menu__item, .accion, .plegar button { display: flex; align-items: center; gap: .6rem; }
.menu__item--hijo .ico { display: none; }

/* =========================================================================
   MINIMIZADO
   Amura lo tiene y hace falta: es la valvula del ancho. El estado vive en una
   galleta, asi que el servidor ya manda la pagina plegada y no hay parpadeo.
   El texto no se borra del HTML —se esconde de la VISTA— para que el menu siga
   sirviendo con lector de pantalla.
   ========================================================================= */
.lateral--min { padding: 1.4rem .6rem 1.2rem; align-items: center; }
.tablero:has(.lateral--min) { grid-template-columns: 3.6rem minmax(0, 1fr); }

/* Fuera de la vista, dentro del arbol de accesibilidad. */
.lateral--min .menu__texto,
.lateral--min .lateral__pie .quien,
.lateral--min .lateral__pie .rotulo,
.lateral--min .menu__titulo,
.lateral--min .sitio {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip-path: inset(50%);
  white-space: nowrap;
}
.lateral--min .menu__item, .lateral--min .accion, .lateral--min .plegar button {
  justify-content: center;
  gap: 0;
  padding: .5rem 0;
  width: 2.4rem;
}
.lateral--min .menu { gap: .9rem; }
.lateral--min .menu__grupo { gap: .15rem; }
/* Los grupos siguen separandose, pero con una linea en vez de un rotulo. */
.lateral--min .menu__grupo + .menu__grupo { border-top: 1px solid #23433d; padding-top: .9rem; }
.lateral--min .menu__item[aria-current="page"]::before { left: -.6rem; }
.lateral--min .lateral__pie { align-items: center; gap: .5rem; }
.lateral--min .lateral__pie button { border: 0; }
.lateral--min .logo { width: 1.5rem; }

/* Los dos iconos viven en el HTML y los intercambia el CSS. Asi el script puede
   plegar con una sola clase, sin tocar el contenido del boton. */
.ico-desplegar { display: none; }
.lateral--min .ico-plegar { display: none; }
.lateral--min .ico-desplegar { display: inline-flex; }

.plegar { margin-top: .2rem; }
.plegar button {
  font: inherit;
  font-size: .8rem;
  background: none;
  border: 0;
  color: #55706b;
  padding: .3rem 0;
  cursor: pointer;
}
.plegar button:hover { color: var(--verde-claro); }
.plegar button:focus-visible { outline: 2px solid var(--verde-claro); outline-offset: 2px; }

/* --- el encabezado de cada pantalla --------------------------------------- */
.encabezado { margin-bottom: 1.6rem; }
.encabezado h1 {
  font-family: var(--display);
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: -.03em;
  margin: .2rem 0 0;
}

/* SIN TOPE: la pantalla de trabajo usa todo el ancho que hay (decision de
 * Hernan). Una herramienta no es un texto — el monitor grande de la redaccion
 * esta para que entren mas notas y mas columnas, no para dejar la mitad en
 * blanco. Lo que si va a llevar un ancho propio, mas angosto, es el formulario
 * de nota: ahi se ESCRIBE, y una linea de 1900px no se lee. */
.panel { padding: 2rem clamp(1rem, 3vw, 2.2rem) 4rem; }

.tarjetas { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 1rem; }
.tarjeta {
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: 3px;
  padding: 1.15rem 1.25rem;
}
.tarjeta h3 { margin: .45rem 0 .8rem; font-size: 1.05rem; letter-spacing: -.015em; }

.permisos { display: flex; flex-wrap: wrap; gap: .3rem; list-style: none; padding: 0; margin: 0; }
.permisos li {
  font-family: var(--dato);
  font-size: .71rem;
  padding: .14rem .42rem;
  border: 1px solid var(--linea);
  border-radius: 2px;
  color: var(--apagado);
}

.actividad { list-style: none; padding: 0; margin: .6rem 0 0; }
.actividad li {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: .8rem;
  padding: .5rem 0;
  border-top: 1px solid var(--linea);
  font-size: .87rem;
}
.actividad time { font-family: var(--dato); font-size: .77rem; color: var(--apagado); }

.pendiente {
  margin-top: 2rem;
  border-left: 3px solid var(--verde);
  background: var(--papel);
  padding: .85rem 1.1rem;
  font-size: .87rem;
  color: var(--apagado);
}
.pendiente strong { color: var(--tinta); }

/* --- responsive ------------------------------------------------------------
 * Abajo de 60rem el lateral pasa a ser una banda arriba. Es la unica pantalla
 * donde el menu vuelve a ser horizontal, y ahi se justifica: no hay ancho para
 * las dos columnas. Los submenus siguen abriendose en linea. */
@media (max-width: 60rem) {
  .tablero { grid-template-columns: 1fr; }
  /* Acá el lateral es una banda ARRIBA, asi que la altura de pantalla y el
     pegado no van: no hay columna que acompañe al scroll. */
  .lateral { padding: 1rem 1.2rem; position: static; height: auto; }
  .menu { flex: initial; overflow: visible; }
  .lateral::after { top: auto; height: 3px; width: auto; left: 0; right: 0; bottom: 0;
    background: linear-gradient(90deg,
      var(--verde-claro) 0 25%, var(--verde) 25% 50%,
      var(--verde-medio) 50% 75%, var(--verde-hondo) 75% 100%); }
  .menu { flex-direction: row; flex-wrap: wrap; gap: .3rem 1.4rem; }
  .menu__grupo { flex-direction: row; flex-wrap: wrap; align-items: center; gap: .1rem .2rem; }
  .menu__titulo { margin: 0 .4rem 0 0; }
  .menu__hijos { flex-direction: row; margin: 0; padding-left: .5rem; }
  .menu__item[aria-current="page"]::before { left: 0; top: auto; bottom: 0; width: auto;
    right: 0; height: 2px; }
  .lateral__pie { margin-top: .6rem; flex-direction: row; align-items: baseline; gap: .8rem; }
  .accion { max-width: 12rem; }
}

/* --- responsive: el plano pasa arriba, en banda ---------------------------- */
@media (max-width: 54rem) {
  .entrada { grid-template-columns: 1fr; }
  .pulso {
    order: -1;
    margin-left: 0;
    clip-path: none;
    padding: 1.4rem 1.5rem;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .9rem 2rem;
    border-bottom: 3px solid var(--verde);
  }
  .pulso::before { display: none; }
  .pulso > :nth-child(1),
  .pulso > :nth-child(2),
  .pulso > :nth-child(3) { padding-left: 0; }
  .pulso .cifras { margin-top: 0; }
  .ultima { border-top: 0; padding-top: 0; }
  .ultima__hace { font-size: 1.4rem; }
  .entrada__form { padding: 2.5rem 1.5rem 3.5rem; }
}

/* =========================================================================
   LISTADO DE NOTAS
   Se escanea, no se lee: una fila por nota, densa. Que entren doce en pantalla
   o cuatro cambia el trabajo de todos los dias.
   ========================================================================= */

.oculto {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.vacio { color: var(--apagado); font-style: italic; }

/* --- filtros: viven en la URL, no en la memoria del navegador ------------- */
.filtros {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: .8rem 1.5rem;
  margin-bottom: 1.2rem;
}
.chips { display: flex; flex-wrap: wrap; gap: .3rem; }
.chip {
  display: flex; align-items: center; gap: .45rem;
  font-size: .85rem; font-weight: 600;
  color: var(--apagado);
  text-decoration: none;
  padding: .3rem .7rem;
  border: 1px solid var(--linea);
  border-radius: 2rem;
  background: var(--papel);
}
.chip:hover { border-color: var(--verde); color: var(--tinta); }
.chip:focus-visible { outline: 2px solid var(--verde); outline-offset: 2px; }
.chip--puesto { background: var(--tinta); border-color: var(--tinta); color: #fff; }
.chip__n { font-family: var(--dato); font-size: .75rem; opacity: .75; }

.buscar { display: flex; gap: .4rem; }
/* El buscador es la variante CHICA, y eso es lo único que declara. */
.buscar input, .buscar select { font-size: .87rem; padding: .35rem .6rem; }
.buscar select { padding-right: 1.7rem; }
.buscar input { min-width: 12rem; }

/* --- las filas ------------------------------------------------------------ */
.listado {
  list-style: none; margin: 0; padding: 0;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: 3px;
}
.fila {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr) 16rem 9rem;
  align-items: center;
  gap: 1rem;
  padding: .7rem 1rem;
  border-bottom: 1px solid var(--linea);
}
.fila:last-child { border-bottom: 0; }
.fila:hover { background: #f7faf9; }

.fila__volanta {
  display: block;
  font-size: .72rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .07em;
  color: var(--verde-medio);
  margin-bottom: .1rem;
}
.fila__titulo a {
  color: var(--tinta);
  font-weight: 600;
  text-decoration: none;
  /* El titulo entero es el destino: es el objetivo mas grande de la fila y el
     unico link, asi que no hay donde errarle. */
  display: block;
}
.fila__titulo a:hover { color: var(--verde-hondo); text-decoration: underline; }
.fila__titulo a:focus-visible { outline: 2px solid var(--verde); outline-offset: 2px; }

.fila__meta { display: flex; flex-direction: column; gap: .1rem; font-size: .82rem; }
.fila__seccion { font-weight: 600; }
.fila__autores { color: var(--apagado); }

.fila__fecha { display: flex; flex-direction: column; gap: .1rem; text-align: right; }
.fila__fecha .rotulo { font-size: .6rem; }
.fila__fecha time { font-family: var(--dato); font-size: .8rem; }

/* --- las acciones de la fila ----------------------------------------------
 * Una columna propia al final, con iconos. Es la unica forma de entrar a una
 * nota SIN titulo, que era el agujero: el titulo era el unico destino y una nota
 * recien creada no tiene ninguno.
 *
 * `auto` y no una medida fija: hoy son uno o dos iconos y manana son cuatro
 * (previsualizar, autores). La columna crece con lo que haya adentro sin que
 * nadie tenga que volver a contar rem.
 *
 * Los iconos NO se esconden hasta el hover. Es la tentacion obvia —la fila queda
 * mas limpia— y es exactamente el problema que esto viene a arreglar: una accion
 * que aparece cuando el mouse pasa por encima no existe en una tablet y no se
 * puede buscar con la vista. */
.fila--notas { grid-template-columns: 6.5rem minmax(0, 1fr) 16rem 9rem auto; }
.fila__acciones { display: flex; align-items: center; gap: .15rem; }
/**
 * `.acc` SE ESCRIBIO PARA `<a>`, y desde `docs/30` también lo usa `<button>`.
 *
 * Un `<a>` no tiene borde, ni fondo, ni tipografía propia; un `<button>` sin
 * declarar trae el cromado del navegador: **`border: 2px outset black` y fondo
 * `#f0f0f0`**. Como esta regla nunca los apagó, cada acción que pasó a ser botón
 * —los menús de Navegación, y la × de las relacionadas— salió metida en un
 * cajoncito gris con relieve, al lado de los iconos pelados de las otras
 * pantallas. Lo marcó Hernán: *"es muy feo este botón, el estilo lo vi también
 * en la sección Navegación"*.
 *
 * O sea que no era una decisión de diseño que hubiera que rediscutir: era el
 * estilo por defecto de 1996 asomando por abajo. Las dos formas de `.acc` tienen
 * que verse igual, porque **para quien las mira son la misma cosa** — que una
 * navegue y la otra envíe es de adentro, y eso ya estaba escrito en `kit.ts`.
 */
/**
 * UN BOTON SIN ASPECTO DE BOTON. Lo pone `botonPlano()` siempre, y `.acc` lo
 * repite porque también lo usan `<a>` y `<span>`, que no pasan por ahí.
 *
 * Es una sola cosa —apagar el cromado del navegador— y tiene nombre propio para
 * que no haya que acordarse: un `<button>` sin declarar trae `border: 2px outset
 * black`, fondo `#f0f0f0` y su propia tipografía.
 */
.btn-plano, .acc {
  border: 0; background: none; padding: 0;
  font: inherit; color: inherit; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.acc {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.9rem; height: 1.9rem;
  border-radius: 3px;
  color: var(--apagado);
}
.acc .ico { width: 1.15rem; height: 1.15rem; }
.acc:hover { background: #e8f0ee; color: var(--verde-hondo); }
.acc:focus-visible { outline: 2px solid var(--verde); outline-offset: 1px; }
/* El lugar de la accion que esta fila no tiene. Mide lo mismo y no hace nada:
   es lo que mantiene el lapiz en la misma columna en todas las filas. */
.acc--hueco { pointer-events: none; }

/* El estado se lee por forma y por color, no solo por color: a la velocidad a
   la que se mira esto, un borrador y una publicada no se pueden confundir. */
.pill {
  display: inline-block;
  font-size: .68rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  padding: .18rem .5rem;
  border-radius: 2px;
  border: 1px solid;
}
.pill--1 { color: #7a6a1f; background: #fdf8e3; border-color: #e8dca5; }  /* borrador */
.pill--2 { color: #1f5a7a; background: #eaf4fa; border-color: #a9cfe3; }  /* programada */
.pill--3 { color: var(--verde-hondo); background: #e8f7f3; border-color: #a7ddd0; }
.pill--4 { color: var(--apagado); background: #f1f4f3; border-color: var(--linea); }

.vacio-caja {
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: 3px;
  padding: 2rem 1.2rem;
  text-align: center;
  color: var(--apagado);
}
.vacio-caja a { color: var(--verde-hondo); }

.paginacion {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-top: 1rem;
  font-size: .87rem;
}
.pagina {
  color: var(--verde-hondo); text-decoration: none; font-weight: 600;
  padding: .35rem .7rem; border: 1px solid var(--linea); border-radius: 2px;
  background: var(--papel);
}
.pagina:hover { border-color: var(--verde); }
.pagina--no { color: var(--apagado); border-color: transparent; background: none; }
.paginacion__donde { color: var(--apagado); font-family: var(--dato); font-size: .8rem; }

@media (max-width: 60rem) {
  .fila { grid-template-columns: 5.5rem minmax(0, 1fr); grid-template-areas: none; }
  /* Las acciones se quedan en la primera fila de la grilla, a la derecha del
     titulo: son el destino, y en pantalla chica el destino no se va al final. */
  .fila--notas { grid-template-columns: 5.5rem minmax(0, 1fr) auto; }
  .fila--notas .fila__titulo { grid-column: 2; }
  .fila--notas .fila__acciones { grid-column: 3; grid-row: 1; }
  .fila__meta, .fila__fecha { grid-column: 2; text-align: left; }
  .fila__fecha { flex-direction: row; gap: .5rem; align-items: baseline; }
}


/* =========================================================================
   LA FICHA DE NOTA
   Pestañas en el area principal + riel derecho fijo, como Amura (`docs/20`).
   El riel lleva lo que se toca en TODAS las notas; las pestañas, lo que se toca
   en algunas. Y todos los campos estan siempre en el formulario: la pestaña solo
   cambia cual se ve, asi que un solo Guardar manda todo.
   ========================================================================= */

.ficha__barra {
  position: sticky; top: 0; z-index: 5;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  padding: .6rem 0 .7rem;
  background: var(--fondo);
  border-bottom: 1px solid var(--linea);
}
.ficha__que { display: flex; align-items: center; gap: .9rem; }
.volver { color: var(--apagado); text-decoration: none; font-size: .85rem; }
.volver:hover { color: var(--verde-hondo); }
.ficha__acciones { display: flex; align-items: center; gap: .6rem; }
.guardado { font-size: .78rem; color: var(--apagado); font-family: var(--dato); }

/* Sin banda muerta: la principal se estira y el riel es fijo y angosto.
 *
 * SIN TOPE DE ANCHO. Probe capar el contenedor para que lo que sobra quedara
 * como margen de pagina, y Hernan lo rechazo en el acto: *"seguis sin usar el
 * 100% del ancho en pantallas grandes, no se aprovecha nada"*. Es la misma
 * respuesta que da Amura, que no capa nada: `col-md-8` + `col-md-4` y los
 * campos se estiran. El ancho no se administra recortando la pagina sino
 * poniendo campos EN FILA adentro (ver `.escribir__fila`), que es lo que
 * convierte el sobrante en algo util en vez de en aire. */
.ficha__cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 19rem;
  gap: 1.2rem;
  align-items: start;
  margin-top: 1.2rem;
}
.ficha__riel { display: flex; flex-direction: column; gap: .8rem; position: sticky; top: 4.2rem; }

/* Quién escribió la nota y quién la tocó último. Información de consulta: se
   mira cuando hace falta y no se toca nunca, así que va abajo del riel, chica y
   apagada. Con el peso de un bloque competiría con lo que sí se decide. */
.quienes { margin: 0; font-size: .76rem; line-height: 1.5; color: var(--apagado); }

/* --- las solapas ----------------------------------------------------------
 * Radios + CSS: andan sin JavaScript, y los campos de todas las pestañas siguen
 * en el DOM — que es lo que permite guardar todo de una sola vez. */
.pest__radio { position: absolute; opacity: 0; pointer-events: none; }
.pest__solapas { display: flex; gap: .15rem; border-bottom: 1px solid var(--linea); }
.pest__solapa {
  position: relative;
  display: flex; align-items: center; gap: .4rem;
  font-size: .87rem; font-weight: 600;
  color: var(--apagado);
  padding: .55rem 1rem;
  cursor: pointer;
  border: 1px solid transparent; border-bottom: 0;
  border-radius: 3px 3px 0 0;
  margin-bottom: -1px;
}
.pest__solapa:hover { color: var(--tinta); }
.pest__radio:checked + .pest__solapa {
  background: var(--papel);
  border-color: var(--linea);
  color: var(--tinta);
}
.pest__radio:focus-visible + .pest__solapa { outline: 2px solid var(--verde); outline-offset: -2px; }

/* El punto es lo que responde a la objecion contra las pestañas: lo que esta
   escondido avisa cuando tiene algo pendiente. */
.pest__punto { width: .45rem; height: .45rem; border-radius: 50%; background: #c8a93a; }

.pest__panel {
  display: none;
  background: var(--papel);
  border: 1px solid var(--linea); border-top: 0;
  border-radius: 0 3px 3px 3px;
}
/**
 * CUAL SE VE: la que tiene su `radio` marcado.
 *
 * LA REGLA ES GENERICA y no una lista de ids, que es como estaba. Antes había una
 * línea por solapa —`nota`, `multimedia`, `relacionadas`, `seo`— y eso significa
 * que **una pantalla nueva con solapas no funciona hasta que alguien se acuerde
 * de tocar esta hoja**; el síntoma es un panel que no abre nunca, sin error.
 *
 * Se empareja POR POSICION y no por id: el enésimo `radio` con el enésimo panel.
 * Ese emparejamiento lo garantiza `pestañas()` de `kit.ts`, que emite los dos de
 * la misma lista y en el mismo orden — no hay forma de que se desalineen sin
 * romper esa función.
 *
 * EL PRECIO ES UN TOPE DE SEIS, porque `nth-of-type` no acepta una variable. Seis
 * solapas ya es más de lo que una pantalla debería tener; si alguna vez hacen
 * falta siete, la línea a agregar está a la vista y el panel séptimo no se ve
 * hasta entonces — que es un error ruidoso, no uno callado.
 */
.pests:has(.pest__radio:nth-of-type(1):checked) > .pest__panel:nth-of-type(1),
.pests:has(.pest__radio:nth-of-type(2):checked) > .pest__panel:nth-of-type(2),
.pests:has(.pest__radio:nth-of-type(3):checked) > .pest__panel:nth-of-type(3),
.pests:has(.pest__radio:nth-of-type(4):checked) > .pest__panel:nth-of-type(4),
.pests:has(.pest__radio:nth-of-type(5):checked) > .pest__panel:nth-of-type(5),
.pests:has(.pest__radio:nth-of-type(6):checked) > .pest__panel:nth-of-type(6) { display: block; }

.pest__cuerpo { padding: 1.2rem 1.4rem 1.6rem; }
.pest__encabezado { display: flex; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; }
.pest__ayuda { font-size: .85rem; color: var(--apagado); margin: 0 0 1rem; max-width: 44rem; }
.pest__pendiente { font-size: .8rem; color: var(--apagado); font-style: italic; margin: 0 0 1rem; }
.dos-columnas { display: grid; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr)); gap: 1.5rem; }
/* SEO: Google a un lado, redes al otro. Antes la segunda columna era la revisión
   —que se fue al riel, porque no es SEO— y los campos se apilaban todos en la
   primera dejando media solapa vacía. Se apila solo cuando no entran: un campo
   de texto en una columna de 15rem es peor que dos secciones una abajo de otra. */
.seo__cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr)); gap: 1.5rem 2.5rem; }


/* HIJOS DIRECTOS, no descendientes — y el `>` es la corrección de un bug real.
 *
 * Escrita como `.ficha .campo select` (sin `>`), alcanzaba TODO lo que hubiera
 * adentro de un campo, por hondo que estuviera: los desplegables de la barra del
 * editor —que viven dentro del campo Cuerpo— salían con `width: 100%` y la barra
 * se partía en cinco filas. Es la misma historia del "Recuperar en blanco sobre
 * blanco" (`docs/22`): una regla escrita para una cosa que termina pintando otra.
 *
 * Con `>` la regla dice lo que quería decir: **el control de este campo**. Lo que
 * arma su propia estructura adentro (la fecha partida, las fichas de tags, el
 * editor) se pinta solo. */
/* SÓLO EL ANCHO. El borde, el fondo, el padding y el foco los pone la regla del
 * elemento — eran una copia idéntica.
 *
 * Y que acá quede sólo `width` NO es cosmético: mientras esta regla declaraba
 * `font` y `padding`, su especificidad (dos clases) le ganaba a
 * `.campo--titulo textarea` (una), así que **el estilo del título estaba escrito
 * y muerto**. Se veía como un campo cualquiera. Cuanto menos declare una regla
 * de contexto, menos estilos de detalle mata sin que nadie se entere. */
.ficha .campo > textarea, .ficha .campo > input, .ficha .campo > select {
  width: 100%;
}
.ficha .campo small { display: block; margin-top: .25rem; font-size: .78rem; color: var(--apagado); }
.ficha .campo small strong { color: #8d1e1a; }

/* EL TÍTULO SE VE COMO UN TÍTULO. Es lo que estaba escrito acá desde el
 * principio y no se aplicaba nunca: una regla de contexto con más especificidad
 * le ganaba el `font` (ver `.ficha .campo > textarea`). Al destapar el estilo, lo
 * primero que dijo Hernán fue que había quedado gigante — y tenía razón: 1.6rem
 * en un `rows="2"` es una caja de cinco centímetros para un campo de una línea.
 *
 * 1.28rem es la medida que hace que el título SE LEA como el título de la nota
 * —que es lo que ayuda a escribirlo— sin convertirse en el elemento más grande
 * de una pantalla donde lo importante es el cuerpo. */
/* De la regla que estaba muerta se queda LA TIPOGRAFÍA y se tira el borde.
 *
 * Declaraba además `border-color: transparent` y sin padding lateral, o sea el
 * título y la bajada como texto suelto sobre la página. Eso tendría sentido si la
 * columna entera fuera una superficie de escritura, y no lo es: el cuerpo es una
 * caja con barra de herramientas y los tags son cajas. Sin bordes, esos dos
 * campos se leen como un error —Hernán: *"los textbox perdieron los bordes"*—
 * y no como una decisión.
 *
 * Lo que sí hace falta es que el título SE VEA como el título de la nota, y eso
 * lo da la tipografía, no la ausencia de caja. */
.campo--titulo textarea {
  font-family: var(--display);
  font-size: 1.28rem; font-weight: 700; letter-spacing: -.02em; line-height: 1.3;
}
.campo--bajada textarea {
  font-size: 1.02rem; line-height: 1.5;
}
.campo--cuerpo { margin-top: 1.2rem; }
.editor__fuente { font-family: var(--dato); font-size: .8rem; line-height: 1.5; }

/* --- el riel ---------------------------------------------------------------- */
.bloque {
  background: var(--papel); border: 1px solid var(--linea); border-radius: 3px;
  padding: .85rem .95rem .95rem;
}
.bloque .rotulo { margin: 0 0 .7rem; }
.bloque .campo { margin-bottom: .75rem; }
.bloque .campo:last-child { margin-bottom: 0; }
.bloque .campo > label { font-size: .74rem; }
.bloque small { display: block; margin-top: .4rem; font-size: .75rem; color: var(--apagado); }

.chk { display: flex; align-items: center; gap: .45rem; font-size: .86rem; margin: .3rem 0; }
/* El tamaño lo pone la regla del elemento; acá sólo que no se estire. */
.chk input { width: 1.05rem; }
/* La ayuda de un casillero va DEBAJO y alineada con su texto, no al lado: al
   lado compite con la etiqueta y se lee como parte de ella. */
.chk__ayuda {
  display: block; margin: -.1rem 0 .6rem 1.35rem;
  font-size: .78rem; color: var(--apagado); line-height: 1.4;
}
.chk__ayuda code { font-family: var(--dato); font-size: .92em; }
/* --- dónde se publica, con varias cabeceras ---------------------------------
 *
 * UNA FILA POR CABECERA. Antes era un bloque apilado por cabecera —casilla,
 * selector y radio, uno debajo del otro— dentro de la columna de 22rem: con dos
 * cabeceras eran seis controles en vertical. Hernán lo miró y dijo "está
 * bastante grotesco", y tenía razón.
 *
 * La forma es la de Amura (`noticias/new.col.medias.html`), que lleva años de
 * uso: una tabla chica, `Media | Principal`, una fila cada una. Acá hay una
 * columna más —la sección, que en Lite es por cabecera (`docs/12`)— y por eso
 * el bloque sale de la columna angosta y toma el ancho entero. */
.bloque--donde { margin-bottom: 1rem; }

.donde { width: 100%; border-collapse: collapse; }
.donde th {
  text-align: left;
  font-size: .7rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--apagado);
  padding: 0 .6rem .35rem 0;
  border-bottom: 1px solid var(--linea);
}
.donde th:last-child { text-align: center; padding-right: 0; }
.donde td { padding: .5rem .6rem .5rem 0; border-bottom: 1px solid var(--linea); }
.donde tr:last-child td { border-bottom: 0; }
.donde td:last-child { padding-right: 0; }

/* La cabecera manda: es lo que se lee primero y lo que decide todo lo demás. */
.donde__cab { width: 38%; }
.donde__cab .chk { margin: 0; }
/* Que la nota YA esté publicada ahí no es un detalle: destildar la saca de ese
 * sitio. Amura lo avisa con un `data-state` y un mensaje; acá se dice antes. */
.donde__ya {
  display: block; margin: .15rem 0 0 1.7rem;
  font-size: .7rem; color: var(--apagado);
}
/* El selector NO se estira al ancho de la columna: adentro va una palabra
 * ("Política"), y un desplegable de 500 px para eso es el mismo hueco que la
 * regla de `.escribir__fila` evita del otro lado. */
.donde__sec select { width: 100%; max-width: 18rem; }
.donde__pral { width: 6rem; text-align: center; }


@media (max-width: 40rem) {
  /* En pantalla angosta la tabla se rompe: cada cabecera vuelve a ser un bloque,
   * que ahí sí es la forma correcta. */
  .donde thead { display: none; }
  .donde, .donde tbody, .donde tr, .donde td { display: block; width: auto; }
  .donde tr { padding: .6rem 0; border-bottom: 1px solid var(--linea); }
  .donde td { border: 0; padding: .25rem 0; }
  .donde__pral { text-align: left; }
  .donde__pral::before {
    content: "Principal"; font-size: .75rem; color: var(--apagado); margin-right: .5rem;
  }
}

/* --- la grilla de fotos ----------------------------------------------------
 * Elegir una imagen es MIRAR IMAGENES: nadie reconoce una foto por su nombre de
 * archivo. Las miniaturas salen por el mismo camino que las del sitio, asi que
 * si el recorte se ve mal acá, se va a ver mal publicado. */
.fotos { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: .8rem; }
.foto {
  position: relative;
  display: block; cursor: pointer;
  border: 2px solid var(--linea); border-radius: 3px;
  overflow: hidden;
  background: #f2f5f4;
  transition: border-color .12s;
}
.foto:hover { border-color: var(--verde); }
.foto input { position: absolute; opacity: 0; pointer-events: none; }
.foto__img { display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover; background: #e3eae8; }
.foto__nombre {
  display: block; font-size: .76rem; line-height: 1.3;
  padding: .4rem .5rem;
  color: var(--apagado);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.foto--puesta { border-color: var(--verde-hondo); }
.foto--puesta::after {
  content: "Elegida";
  position: absolute; top: .4rem; left: .4rem;
  font-size: .65rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  background: var(--verde-hondo); color: #fff;
  padding: .1rem .4rem; border-radius: 2px;
}
.foto--ninguna {
  display: flex; align-items: center; justify-content: center;
  min-height: 8rem; border-style: dashed;
}
.foto--ninguna .foto__nombre { white-space: normal; text-align: center; }

/* El foco: el pixel que se conserva al recortar. Lo posiciona el guion, porque
   la coordenada es un DATO y no un estilo — y en la hoja no entran estilos por
   fila. Sin JavaScript queda al centro, que ademas es el valor por defecto. */
.foto__foco {
  position: absolute; top: 50%; left: 50%;
  width: .6rem; height: .6rem; margin: -.3rem 0 0 -.3rem;
  border-radius: 50%;
  background: var(--verde-claro);
  box-shadow: 0 0 0 2px rgba(4, 33, 28, .55);
  pointer-events: none;
}
.foto__falta {
  position: absolute; top: .4rem; right: .4rem;
  font-size: .62rem; font-weight: 700; text-transform: uppercase;
  background: #fdf4f3; color: #8d1e1a; border: 1px solid #e3bebc;
  padding: .05rem .3rem; border-radius: 2px;
}

/* --- relacionadas y revision ------------------------------------------------ */
.relacionadas { list-style: none; margin: 0; padding: 0; }

/* La lista de puestas es VERTICAL, una debajo de la otra, porque asi salen al
   pie de la nota: la solapa muestra la forma que van a tener. Las ultimas de la
   seccion son otra cosa —horizontales y con foto grande— y por eso no comparten
   ni el estilo ni el nombre. */
.rel__item {
  display: flex; align-items: center; gap: .5rem;
  padding: .4rem .5rem; border: 1px solid var(--linea); border-radius: 2px;
  margin-bottom: .35rem; background: #fff;
}
.rel__titulo { flex: 1; font-size: .88rem; line-height: 1.35; }
.rel__item .acc { flex: 0 0 auto; font-size: 1rem; line-height: 1; }
.rel [data-elegir-nota] { margin-top: .2rem; }

/* El selector de notas se lee, no se mira: es una lista densa y no una grilla.
   Por eso reusa `.fila` del listado en vez del `.mm` de la mediateca. */
.selector__lista { flex: 1; min-height: 0; overflow-y: auto; padding-top: .2rem; }

/* `.fila` ES UN GRID DE CUATRO COLUMNAS —estado, título, meta, fecha— y la fila
   del selector tiene UN solo hijo: el botón. Sin este `block` el botón caía en la
   primera columna, que mide 6.5rem, y el título salía en una tira vertical de una
   palabra por renglón. Lo vio Hernán apenas abrió el modal.
   La fila del selector no necesita el grid: no tiene columnas que alinear entre
   filas, tiene un bloque que se aprieta entero. */
.fila--elegir { display: block; padding: 0; }
.fila__elegir {
  display: flex; flex-direction: column; gap: .15rem; width: 100%;
  text-align: left; background: none; border: 0; cursor: pointer;
  padding: .55rem .8rem; font: inherit; color: inherit;
}
.fila__elegir:hover, .fila__elegir:focus-visible { background: var(--fondo); }
.fila__elegir .fila__titulo { font-weight: 600; line-height: 1.35; }
/* En fila y no en columna: `.fila__meta` del listado apila sección y firma porque
   ahí son dos columnas de una tabla. Acá son un renglón de contexto. */
.fila__elegir .fila__meta {
  flex-direction: row; align-items: baseline; gap: .6rem;
  font-size: .8rem; color: var(--apagado);
}
.fila__elegir .fila__fecha { display: inline; text-align: left; }

/* YA PUESTA: se queda en la lista y se marca, no desaparece. Sacarla haría que
   la lista salte bajo el dedo justo después de apretar — y además esconde la
   respuesta a "¿ya la puse?", que es lo que uno mira al volver a abrir. */
.fila__elegir[data-puesta] { color: var(--apagado); cursor: default; }
.fila__elegir[data-puesta]:hover { background: none; }
.fila__elegir[data-puesta] .fila__titulo { font-weight: 500; }
.fila__elegir[data-puesta] .fila__titulo::after {
  content: " ✓ ya está"; font-size: .75rem; font-weight: 600; color: var(--verde-medio);
  white-space: nowrap;
}
.selector__lista .mas { list-style: none; padding: .6rem 0; text-align: center; }
.selector__pie {
  display: flex; align-items: center; justify-content: space-between;
  gap: .8rem; padding-top: .6rem; border-top: 1px solid var(--linea);
}
.selector__cuenta { margin: 0; font-size: .84rem; color: var(--apagado); }

.revision { list-style: none; margin: .6rem 0 0; padding: 0; }
.revision li {
  font-size: .85rem; line-height: 1.45;
  padding: .5rem .7rem; margin-bottom: .4rem;
  border-radius: 2px; border-left: 3px solid;
}
.revision--alta { background: #fdf4f3; border-color: #a3231f; }
.revision--media { background: #fdf8e3; border-color: #c8a93a; }
.revision li strong { display: block; }
.revision--bien { font-size: .87rem; color: var(--verde-hondo); }

/* --- avisos ------------------------------------------------------------------ */
.recuperar {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1.5rem; flex-wrap: wrap;
  background: #fdf8e3; border: 1px solid #e8dca5; border-left: 3px solid #c8a93a;
  border-radius: 3px; padding: .9rem 1.1rem; margin-bottom: 1rem;
}
/* El bloque de texto se lleva todo el ancho que sobra; las acciones, lo suyo.
   Sin esto la caja de diferencias quedaba tan angosta como su contenido más
   corto, que es de donde salía lo "apretado". */
.recuperar > div:first-child { flex: 1; min-width: 0; }
.recuperar p { margin: 0 0 .3rem; font-size: .9rem; }
.recuperar__ayuda { color: #7a6a1f; font-size: .82rem; }

/* QUÉ CAMBIA EL BORRADOR, plegado.
 *
 * Arriba va una línea que se lee sin querer; el detalle se abre a un clic. Lo
 * marcó Hernán: la lista de campos suelta *"no ayuda, porque te dice título pero
 * si no lo veo, cómo me arriesgo"* — ocupaba lugar arriba sin alcanzar para
 * decidir. Es un `<details>` y no un modal porque el contenido es corto y así
 * anda sin JavaScript, que en la caja que salva el trabajo del periodista no es
 * un detalle. */
.recuperar__difs { margin-top: .35rem; }
.recuperar__difs > summary {
  cursor: pointer; font-size: .85rem; font-weight: 600; color: #6b5e1c;
  display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
}
.recuperar__difs > summary:hover { color: #4a4114; }
.recuperar__cuantas { font-weight: 400; opacity: .8; }

/* La comparación: UN BLOQUE POR CAMPO, no una tabla de tres columnas.
 *
 * Era una tabla y Hernán la marcó dos veces —*"la primera columna donde están
 * los nombres queda apretada"* y *"así no sirve de mucho"*—, que son el mismo
 * problema: con el nombre del campo ocupando una columna, a cada versión le
 * quedaba un tercio del ancho, así que un título entraba en cuatro renglones
 * angostos y encontrar la diferencia era leer los dos y comparar a mano.
 *
 * Ahora el nombre va arriba y cada versión toma el ancho entero. Lo que cambió
 * va resaltado, que es lo que hace que la caja se pueda leer de un vistazo.
 *
 * Se apila y no va lado a lado a propósito: dos columnas se comparan bien
 * cuando los valores son cortos, y acá el caso que importa —un título, una
 * bajada— es justo el largo. Apilados, las dos versiones arrancan en la misma
 * columna, que es lo que hace saltar la parte distinta. */
.dif { margin-top: .6rem; font-size: .85rem; }
.dif__campo { padding: .5rem 0; border-top: 1px solid #e8dca5; }
.dif__campo:first-child { border-top: 0; }
.dif__que {
  margin: 0 0 .25rem; font-weight: 600; color: #4a4114;
  font-size: .72rem; text-transform: uppercase; letter-spacing: .04em;
}
.dif__que small { font-weight: 400; text-transform: none; letter-spacing: 0; opacity: .75; }
.dif__lado { display: flex; gap: .6rem; align-items: baseline; padding: .1rem 0; }
.dif__rotulo {
  flex: none; width: 5.5rem; text-align: right;
  font-size: .72rem; color: #7a6a1f; opacity: .85;
}
.dif__valor { min-width: 0; }
/* El borrador es lo que se está por traer, así que pesa más que lo guardado. */
.dif__antes .dif__valor { color: #7a6a1f; }
.dif__ahora .dif__valor { color: #2f2a0c; font-weight: 500; }
.dif__nada { opacity: .55; font-style: italic; }
/* LO QUE CAMBIÓ. Amarillo sobre el fondo crema de la caja: es el mismo resaltador
   que el editor usa en el cuerpo, así que se lee como "mirá acá" y no como un
   estado nuevo que hay que aprender. */
.dif__marca { background: #f7e9a8; color: inherit; border-radius: 2px; padding: 0 .12em; }
.dif__antes .dif__marca { background: #f1e3c2; }
/* QUÉ CAMBIA EL BORRADOR. Es lo que convierte el aviso en una decisión: sin esto
   decía cuándo se guardó, que es el dato que menos ayuda a elegir.
   Se lee de un vistazo —columna angosta, una línea por campo— y el nombre del
   campo pesa más que el detalle, porque es lo que se busca al mirar. */
/* Solo la DISPOSICION. Como se ven los botones lo decide `.btn`, y nada de acá
   lo pisa — es la regla de `docs/22`, y esta caja es la prueba de por que existe:
   antes habia un `.recuperar__acciones button { background: papel }` que, por ser
   mas especifico, le ganaba a `.btn--principal` y dejaba **Recuperar en blanco
   sobre blanco**. Un boton ilegible en la caja que salva el trabajo del
   periodista, escrito por una regla puesta con la mejor intencion. */
.recuperar__acciones { display: flex; gap: .5rem; }

.ocupada {
  background: #fdf4f3; border: 1px solid #e3bebc; border-left: 3px solid #a3231f;
  border-radius: 3px; padding: .8rem 1.1rem; margin-bottom: 1rem; font-size: .9rem;
}
.ocupada p { margin: 0; }
/* =========================================================================
   AVISOS — uno solo, para siempre
   Hernan: "estos mensajes que aparecen por todos lados normalicemoslos, y creo
   que lo mejor es el mensaje que aparece flotando de costado asi no roba
   pantalla; hagamos que para siempre sea el mismo".

   Eran cinco redacciones del mismo parrafo, y ademas EMPUJABAN el contenido: el
   listado se corria una linea y la nota de arriba aparecia un renglon mas abajo
   que la vez anterior. Flotando, la pantalla es la misma con aviso y sin aviso.

   DOS GRUPOS, y la diferencia no es de estilo (ver `kit.ts`):
     .aviso   RESULTADO de algo que hiciste. Flota, no ocupa lugar, se va.
     .nota    ESTADO de lo que estas mirando. Va en la pagina y se queda.
   ========================================================================= */
.avisos {
  position: fixed;
  right: 1.2rem; bottom: 1.2rem;
  z-index: 60;
  display: flex; flex-direction: column-reverse; gap: .5rem;
  /* No tapa lo que hay debajo cuando esta vacia. Cada aviso lo vuelve a
     habilitar para si mismo: sin esto, la franja se comeria los clicks de toda
     la esquina inferior derecha de la pantalla. */
  pointer-events: none;
  max-width: min(26rem, calc(100vw - 2.4rem));
}
.aviso {
  pointer-events: auto;
  display: flex; align-items: flex-start; gap: .5rem;
  background: var(--tinta); color: #eaf3f1;
  border-left: 3px solid var(--verde);
  border-radius: 3px;
  padding: .7rem .5rem .7rem .9rem;
  font-size: .88rem;
  box-shadow: 0 8px 28px rgba(4, 33, 28, .28);
  animation: aviso-entra .18s ease-out;
}
.aviso__texto { margin: 0; flex: 1; }
.aviso__texto strong { color: #fff; }
/* La × hereda de `.btn btn--texto`; acá solo se aclara sobre fondo oscuro. */
.aviso__cerrar { color: #9fb5b0; font-size: 1.1rem; line-height: 1; padding: 0 .35rem; }
.aviso__cerrar:hover { color: #fff; background: rgba(255, 255, 255, .1); }

/* EL TONO SE TIENE QUE VER SIN LEER.
 *
 * Acá los tres tonos se distinguian solo por 3px de borde izquierdo sobre el
 * mismo fondo oscuro: "Guardado" y "No se pudo guardar" eran, de reojo, la misma
 * caja verde. Lo marco Hernan y tiene razon — un aviso que hay que LEER para
 * saber si algo salio bien no esta avisando nada.
 *
 * Ahora cambia el fondo entero, y ademas hay un simbolo: el color solo no alcanza
 * para quien no lo distingue, y es la mitad de los hombres con daltonismo rojo-
 * verde justo en el par que mas se usa. El simbolo va por CSS y no en el HTML
 * porque es decoracion: quien usa un lector de pantalla ya recibe `role="alert"`
 * en los errores y `role="status"` en el resto, que es la señal de verdad. */
.aviso::before {
  content: "✓";
  flex: 0 0 auto;
  font-weight: 700;
  line-height: 1.35;
}

.aviso--error {
  background: #4a1f1c;
  border-left-color: #ff8a80;
  color: #ffe3e0;
}
.aviso--error::before { content: "!"; color: #ff8a80; }
.aviso--error .aviso__cerrar { color: #e8b4af; }

.aviso--atencion {
  background: #4a3a10;
  border-left-color: #ffcf4d;
  color: #fdf0cf;
}
.aviso--atencion::before { content: "•"; color: #ffcf4d; }
.aviso--atencion .aviso__cerrar { color: #ddc68a; }

/* Se va solo, salvo los errores (ver `kit.ts`: lo bueno se va, lo malo espera). */
.aviso--yendose { animation: aviso-sale .25s ease-in forwards; }

@keyframes aviso-entra {
  from { opacity: 0; transform: translateX(1rem); }
  to { opacity: 1; transform: none; }
}
@keyframes aviso-sale {
  to { opacity: 0; transform: translateX(1rem); }
}
@media (prefers-reduced-motion: reduce) {
  .aviso, .aviso--yendose { animation: none; }
}

/* Abajo de 40rem la esquina no alcanza: ocupa el ancho, pegado abajo. */
@media (max-width: 40rem) {
  .avisos { left: .8rem; right: .8rem; bottom: .8rem; max-width: none; }
}

/* --- las notas de estado, que SI van en la pagina ------------------------- */
.nota {
  background: var(--papel); border-left: 3px solid var(--verde);
  padding: .7rem 1rem; margin-bottom: 1rem; font-size: .87rem; color: var(--apagado);
}
.nota--error { border-left-color: #a3231f; background: #fdf4f3; color: #8d1e1a; }
.nota--atencion { border-left-color: #c8a93a; background: #fdf8e3; color: #7a6a1f; }

@media (max-width: 66rem) {
  .ficha__cols { grid-template-columns: minmax(0, 1fr); }
  .ficha__riel { position: static; }
}

/* --- la pestaña de escribir, en UNA columna --------------------------------
 * La columna del medio (seccion, firma, foto, contador) se fue: en un monitor
 * normal se llevaba 17rem que le hacian falta al texto — ver el comentario de
 * `pestañaNota` en `ficha.ts` para la cuenta. Lo que tenia se repartio en el
 * flujo, en el orden en que se usa. */
/* SIN `padding` PROPIO: se lo pone `.pest__cuerpo`, que ahora lo pone `pestañas()`
   para todas. Tenerlo acá también daba el margen dos veces —y era la única
   solapa del gestor con un margen distinto del resto sin motivo. */
.escribir { min-width: 0; }

/* Sin `max-width`: titulo, bajada y cuerpo toman TODO el ancho de la columna,
   como el `col-md-8` de Amura. Es lo que pidio Hernan y es lo que hace que en un
   monitor grande no sobre nada. */
.escribir__hoja { min-width: 0; }

/* LA FILA DE ARRIBA es lo que aprovecha el ancho de verdad: seccion, firma y
   temas son tres controles chicos, y uno abajo del otro desperdician una
   pantalla ancha dos veces (dejan aire a la derecha Y empujan el texto para
   abajo). En fila, el monitor grande los muestra los tres de una y el chico los
   apila solo — `auto-fit` decide sin media query. Es la fila de Amura
   (`Sección | Tema`, `Autor | Fecha | Hora`) con nuestros campos. */
/* DOS COLUMNAS, no tres. Con tres, un `<select>` de sección compartía ancho con
 * dos campos que crecen y la del medio siempre sobraba — el "quedan huecos" que
 * marcó Hernán. Los tags se fueron abajo del cuerpo, al ancho entero.
 *
 * La sección no necesita más de lo que mide su nombre más largo, así que se le da
 * lo justo y la firma se queda con el resto: estirar un desplegable a media
 * pantalla es otra forma de hueco, sólo que adentro del control. */
.escribir__fila {
  display: grid;
  grid-template-columns: minmax(14rem, 22rem) minmax(0, 1fr);
  gap: 0 1.6rem;
  align-items: start;
}
/* Al reves: el campo largo primero y el corto atras. Es el caso de la etiqueta
 * —Nombre y despues Que es—, donde estirar el desplegable a media tarjeta seria
 * el mismo hueco que la regla de arriba evita, solo que del otro lado. */
.escribir__fila--invertida { grid-template-columns: minmax(0, 1fr) minmax(11rem, 15rem); }
@media (max-width: 62rem) {
  .escribir__fila,
  .escribir__fila--invertida { grid-template-columns: minmax(0, 1fr); }
}

/* --- un slot de multimedia ------------------------------------------------
 * Tira ancha y baja, no tarjeta: la solapa es una LISTA de slots (principal,
 * y mañana portada y video), asi que cada uno tiene que costar poco alto para
 * que se vean todos juntos. */
.slot {
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr) auto;
  gap: 1rem;
  align-items: center;
  border: 1px solid var(--linea); border-radius: 3px;
  background: #fbfdfc;
  padding: .8rem 1rem;
  margin-bottom: .8rem;
}
.slot__img, .slot__sin {
  display: block; width: 100%; height: auto; aspect-ratio: 16 / 10;
  object-fit: cover; border-radius: 2px; background: #e3eae8;
}
.slot__sin { border: 1px dashed var(--linea); background: none; }
.slot__que { min-width: 0; }
.slot__rol {
  margin: 0 0 .15rem; font-size: .72rem; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--apagado);
}
.slot__nombre {
  margin: 0; font-size: .92rem; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.slot__ayuda { margin: .25rem 0 0; font-size: .8rem; color: var(--apagado); }
.slot__ayuda strong { color: #8d1e1a; }
.slot__acciones { display: flex; gap: .4rem; align-items: center; }
/* Un slot que reemplaza a la principal esta apagado hasta que haya principal.
 * El boton se emite igual y se esconde acá: destrabarlo es sacar el atributo. */
.slot[data-bloqueado] { opacity: .55; }
.slot[data-bloqueado] .slot__accion { display: none; }

/* Lo que ESTA NOTA le escribe a la foto: epigrafe, credito y alt.
 *
 * Fila propia de borde a borde (`1 / -1`) porque la tira de arriba es
 * miniatura + nombre + acciones y meterlos ahi los dejaria en una columna de
 * pocos centimetros — un epigrafe es una frase, no una etiqueta.
 *
 * Sin foto y bloqueado no se muestran, y el marcado esta igual: mostrarlos
 * cuando el guion elige la imagen es sacar un atributo, no construir HTML desde
 * el JavaScript. Misma decision que el boton de arriba. */
.slot__textos {
  grid-column: 1 / -1;
  border-top: 1px solid var(--linea);
  padding-top: .8rem;
}
.slot__textos .campo { margin-bottom: .6rem; }
.slot__textos .campo:last-child { margin-bottom: 0; }
.slot__dos { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.slot[data-sin-foto] .slot__textos,
.slot[data-bloqueado] .slot__textos { display: none; }

@media (max-width: 40rem) {
  .slot__dos { grid-template-columns: 1fr; gap: 0; }
}


/* --- la medida del texto, pegada abajo del editor -------------------------- */
.medida {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem; flex-wrap: wrap;
  margin: .35rem 0 0;
  font-size: .78rem; color: var(--apagado);
  font-variant-numeric: tabular-nums;
}

/* --- el editor de cuerpo (TipTap) ------------------------------------------
 * El textarea con los bloques sigue existiendo debajo: es el que viaja en el
 * formulario, asi que guardar, autoguardar y el "sin JavaScript" comparten un
 * solo camino. Cuando el editor monta, se esconde. */
.editor { border: 1px solid var(--linea); border-radius: 2px; background: var(--papel); }
.editor:focus-within { border-color: var(--verde); box-shadow: 0 0 0 3px rgba(0, 167, 138, .18); }

/* LA BARRA, acercada a `ideas/tiptap/interface`.
   Lo que la separaba de un editor de verdad no era el color: eran los dos
   `<select>` nativos —cajas con borde que leen como formulario— y unos botones
   apretados. Ahora es fondo blanco, area de click cuadrada y holgada, iconos
   parejos y grupos separados por una linea fina. */
.editor__barra {
  display: flex; flex-wrap: wrap; align-items: center; gap: .1rem;
  padding: .3rem .45rem;
  border-bottom: 1px solid var(--linea);
  background: #fff;
  position: sticky; top: 3.4rem; z-index: 2;
}
.editor__boton {
  font: inherit; font-size: .9rem; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center; gap: .05rem;
  min-width: 2.1rem; height: 2.1rem;
  border: 1px solid transparent; border-radius: .375rem;
  background: none; color: #4a5a57; cursor: pointer;
}
/* Los iconos de la barra son los mismos del menu, un punto mas chicos. */
.editor__boton .ico { width: 1.1rem; height: 1.1rem; }
/* Gris neutro y no verdoso: el hover de una barra de herramientas no tiene que
   opinar, solo decir "esto se puede apretar". */
.editor__boton:hover { background: #f0f2f1; color: var(--tinta); }
/* ACTIVO SUAVE, no invertido. Antes era fondo `--tinta` con el icono en blanco:
   con cuatro marcas puestas la barra quedaba con cuatro manchas negras. Un fondo
   tenue con el icono oscuro dice lo mismo sin gritar — es lo que hace la
   referencia. */
.editor__boton--activo,
.editor__boton--abierto { background: #e3ebe9; color: var(--tinta); }
.editor__boton--activo:hover, .editor__boton--abierto:hover { background: #d8e3e0; }
.editor__boton:focus-visible { outline: 2px solid var(--verde); outline-offset: 1px; }
.editor__boton[disabled] { opacity: .35; cursor: default; }
.editor__boton[disabled]:hover { background: none; color: #4a5a57; }

/* El caret de un desplegable acompaña al icono: mas chico y mas apagado, si no
   compite con el dibujo que dice de que se trata. */
.editor__boton--desp { padding: 0 .3rem; }
.editor__boton--desp .ico:last-child { width: .8rem; height: .8rem; opacity: .55; }

/* --- el menu de un desplegable (`imagen2.png` de la referencia) --------------
   Icono + etiqueta por fila. La etiqueta es lo que un `<select>` daba gratis y
   un boton con dibujo solo no da: sin ella, "viñetas" y "numerada" son dos
   dibujos parecidos y hay que adivinar. */
.editor__desp { position: relative; display: inline-flex; }
.editor__desp-menu {
  position: absolute; top: calc(100% + .3rem); left: 0; z-index: 5;
  min-width: 11rem; padding: .3rem;
  background: #fff; border: 1px solid var(--linea); border-radius: .5rem;
  box-shadow: 0 10px 30px rgba(4, 33, 28, .14);
  display: grid; gap: .1rem;
}
.editor__desp-menu[hidden] { display: none; }
.editor__desp-item {
  font: inherit; font-size: .86rem; text-align: left;
  display: flex; align-items: center; gap: .55rem;
  padding: .4rem .5rem; border: 0; border-radius: .375rem;
  background: none; color: var(--tinta); cursor: pointer; width: 100%;
}
.editor__desp-item .ico { width: 1.05rem; height: 1.05rem; flex: none; opacity: .75; }
.editor__desp-item:hover { background: #f0f2f1; }
.editor__desp-item:focus-visible { outline: 2px solid var(--verde); outline-offset: -2px; }
.editor__desp-item--puesta { background: #e3ebe9; font-weight: 600; }
.editor__desp-item--puesta .ico { opacity: 1; }

.editor__sep { width: 1px; height: 1.3rem; margin: 0 .35rem; background: var(--linea); }

/* Lo que se inserta y no es texto. Se ve como va a salir, no como un marcador. */
.editor__img { margin: 1rem 0; }
.editor__img img,
.editor__img video { max-width: 100%; border-radius: 2px; display: block; }
.editor__img figcaption { font-size: .82rem; color: var(--apagado); margin-top: .3rem; }
/* El embebido en el editor dice DE QUIÉN es, no sólo la URL. Es el acuse de
   recibo del catálogo: si dice "YouTube · …", el sistema lo reconoció y va a
   salir publicado. Si el link no se reconoce, no llega a insertarse. */
.editor__embed {
  margin: 1rem 0; padding: .8rem 1rem;
  border: 1px dashed var(--linea); border-left: 3px solid var(--verde); border-radius: 2px;
  background: var(--papel); color: var(--apagado);
  font-family: var(--dato); font-size: .82rem;
  overflow-wrap: anywhere;
}
/* UNA RELACIONADA EN MEDIO DEL TEXTO (`docs/32`).
   Se parece a como va a salir publicada —un aparte con su rótulo— sin copiar la
   hoja del sitio: el editor no la tiene, y fingirla sería prometer un aspecto
   que después no se cumple. Lo que sí tiene que coincidir es la FORMA: un bloque
   aparte con rótulo y titular, para que se lea igual acá y allá. */
.editor__rel {
  display: block;
  margin: 1rem 0; padding: .7rem .9rem;
  border-left: 3px solid var(--verde);
  background: var(--fondo); border-radius: 0 2px 2px 0;
}
.editor__rel-rotulo {
  display: block;
  font-size: .7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .07em;
  color: var(--verde-hondo); margin-bottom: .2rem;
}
.editor__rel-titulo { font-weight: 600; line-height: 1.3; }
.editor .ProseMirror-selectednode { outline: 2px solid var(--verde); outline-offset: 2px; }
/* Los colores del resaltado. LA FUENTE ES `compartido/resaltados.ts` y hay un
   test que compara esta hoja con la del sitio y con la de AMP: si el editor
   mostrara un verde y el sitio otro, el periodista elegiria a ciegas. */
.editor mark { background: #fdf3c4; padding: 0 .1em; border-radius: 2px; }
.editor mark.res-verde { background: #d9f2e3; }
.editor mark.res-celeste { background: #d8ecfb; }
.editor mark.res-rosa { background: #fbdde3; }
.editor mark.res-lila { background: #e8ddf7; }

/* Las pastillas del desplegable de resaltado (`imagen3.png` de la referencia). */
.editor__desp-menu--fila { display: flex; gap: .15rem; min-width: 0; }
.editor__desp-menu--fila .editor__desp-item { padding: .35rem; width: auto; }
.editor__color {
  display: block; width: 1.15rem; height: 1.15rem; border-radius: 50%;
  border: 1px solid rgba(4, 33, 28, .18);
}
.editor__color--amarillo { background: #fdf3c4; }
.editor__color--verde { background: #d9f2e3; }
.editor__color--celeste { background: #d8ecfb; }
.editor__color--rosa { background: #fbdde3; }
.editor__color--lila { background: #e8ddf7; }

/* El area de escritura: se lee como texto de nota, no como un formulario. */
/* El `padding-left` es un CANAL, no una sangría estética: el `+` de la línea
   vacía vive ahí. Con 1.3rem el botón (que arranca en .35rem y mide 1.6rem)
   quedaba MONTADO sobre la primera letra — lo marcó Hernán como "molesta y no
   hace nada", y la mitad de eso era esto: no se leía como un botón sino como
   basura encima del texto. El canal deja también el lugar donde va a ir la
   manija de arrastre. */
/* EL AREA NO CRECE CON EL TEXTO: SCROLLEA ADENTRO.
 *
 * Lo marco Hernan: *"el richtext no puede crecer tanto como el texto porque me
 * genera mucho scroll"*. Y no era una molestia estetica — una nota larga hacia
 * la pagina de tres o cuatro pantallas, asi que la barra del editor quedaba
 * arriba de todo, fuera de la vista, justo mientras se escribe el final. Poner
 * negrita en el ultimo parrafo obligaba a subir, apretar y volver a bajar.
 *
 * Con el tope, el que scrollea es el texto y la barra no se mueve nunca: no
 * hace falta `sticky` porque la barra esta AFUERA de la caja que scrollea.
 * La ventana menos el alto es lo que ocupan la barra fija de la ficha, las
 * solapas y los campos de arriba; el `min-height` gana en pantallas bajas.
 *
 * `overscroll-behavior: contain` para que llegar al final del texto no siga
 * scrolleando la pagina de atras. */
.editor .ProseMirror {
  min-height: 22rem;
  max-height: calc(100vh - 13rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 1.2rem 1.3rem 2rem 2.5rem;
  outline: 0;
  font-size: 1.02rem;
  line-height: 1.65;
}
.editor .ProseMirror > * + * { margin-top: .9rem; }
.editor .ProseMirror p { margin: 0; }
/* LOS TRES NIVELES SE TIENEN QUE DISTINGUIR ESCRIBIENDO, no al publicar.
   Si en el editor los tres se ven igual, elegir entre "Subtítulo 1" y
   "Subtítulo 2" es un acto de fe — y la jerarquía la arma quien escribe. */
.editor .ProseMirror h2,
.editor .ProseMirror h3,
.editor .ProseMirror h4 {
  font-family: var(--display); font-weight: 700; letter-spacing: -.02em;
  margin: 1.6rem 0 0;
}
.editor .ProseMirror h2 { font-size: 1.25rem; }
.editor .ProseMirror h3 { font-size: 1.08rem; }
.editor .ProseMirror h4 { font-size: .97rem; color: #33534d; }
.editor .ProseMirror blockquote {
  margin: 1.2rem 0; padding: .2rem 0 .2rem 1rem;
  border-left: 3px solid var(--verde);
  color: var(--tinta-suave); font-style: italic;
}
.editor .ProseMirror ul, .editor .ProseMirror ol { padding-left: 1.4rem; margin: .9rem 0; }
.editor .ProseMirror li { margin: .25rem 0; }
.editor .ProseMirror hr {
  border: 0; border-top: 1px solid var(--linea); margin: 1.6rem 0;
}
.editor .ProseMirror a { color: var(--verde-hondo); }

/* El transporte, escondido cuando el editor tomo el mando. */
.editor__fuente--oculta { display: none; }

/* El aviso de la copia local se distingue del de servidor: no es lo mismo
   "quedó en el servidor" que "quedó en esta máquina y no llegó a subir". */
.recuperar--local { background: #eaf4fa; border-color: #a9cfe3; border-left-color: #1f5a7a; }
.recuperar--local .recuperar__ayuda { color: #1f5a7a; }

/* =========================================================================
   LA MEDIATECA (`docs/21`)
   La misma grilla se usa en la pantalla y —despues— adentro del selector.
   ========================================================================= */

/* --- subir: primero y visible. En una redaccion el caso normal es venir con el
   archivo en la mano, no buscar donde esta el boton. --- */
.subir {
  display: flex; align-items: stretch; gap: .8rem;
  margin-bottom: 1.2rem;
}
.subir__caja {
  flex: 1;
  display: flex; flex-direction: column; justify-content: center;
  gap: .2rem;
  padding: 1rem 1.2rem;
  border: 2px dashed var(--linea);
  border-radius: 3px;
  background: var(--papel);
  cursor: pointer;
  transition: border-color .12s, background .12s;
}
.subir__caja:hover, .subir__caja:focus-within { border-color: var(--verde); background: #fbfdfc; }
/* Acá vivía `.subir__caja--encima`, el resaltado de "estás soltando encima". No la
   ponía nadie: el arrastre pasó a aceptarse sobre TODA la pantalla —"quien
   arrastra doce fotos no debería tener que apuntarle a un rectángulo"— y el
   resaltado se hace con `.soltando` sobre el `<main>`. La regla quedó huérfana y
   la encontró eslint, por su variable sin usar del otro lado. */
.subir__caja input { position: absolute; opacity: 0; pointer-events: none; }
.subir__texto { font-size: .92rem; }
.subir__ayuda { font-size: .78rem; color: var(--apagado); }
.subir__boton { align-self: stretch; }

/* --- la grilla ------------------------------------------------------------ */
.mms {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
  gap: .9rem;
}
.mm {
  position: relative;
  display: block;
  text-decoration: none; color: inherit;
  border: 1px solid var(--linea);
  border-radius: 3px;
  overflow: hidden;
  background: var(--papel);
  transition: border-color .12s, transform .12s;
}
.mm:hover { border-color: var(--verde); }
.mm:focus-visible { outline: 2px solid var(--verde); outline-offset: 2px; }
/* LA HOJA NO RECORTA NADA. Se muestra lo que Cloudflare entregó, entero.
   Antes había un `aspect-ratio: 16/10` + `object-fit: cover` encima de una
   imagen que YA venía recortada en otra proporción, así que se comía una franja
   de cada foto sin que nadie lo hubiera decidido (lo vio Hernán).
   `height: auto` con las medidas puestas en el `<img>`: el navegador reserva el
   lugar exacto antes de descargar y la grilla no se mueve al cargar. */
.mm__img { display: block; width: 100%; height: auto; background: #e3eae8; }
.mm__sinimg {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .3rem;
  aspect-ratio: 16 / 10;
  background: #eef2f1;
  color: var(--apagado);
}
.mm__sinimg--grande { aspect-ratio: 16 / 9; border-radius: 3px; }

/* El archivo que no es imagen se dibuja con lo que el navegador ya sabe hacer
   con el, no con un icono que lo represente. Antes un video era un recuadro gris
   con un triangulito, asi que para saber cual era habia que abrirlo aparte. */
.media__player {
  display: block; width: 100%; height: auto;
  aspect-ratio: auto 16 / 9; background: #000; border-radius: 3px;
}
.media__audio {
  display: grid; gap: .8rem; justify-items: center; align-content: center;
  aspect-ratio: 16 / 6; background: #f1f4f2;
  border: 1px solid var(--linea); border-radius: 3px; padding: 1rem;
}
.media__audio audio { width: 100%; max-width: 26rem; }
.mm__marca { font-size: 1.6rem; line-height: 1; }
.mm__ext { font-family: var(--dato); font-size: .7rem; text-transform: uppercase; }
.mm__pie { display: block; padding: .45rem .6rem .55rem; }
.mm__nombre {
  display: block; font-size: .84rem; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mm__datos { display: block; font-family: var(--dato); font-size: .72rem; color: var(--apagado); }
.mm__foco {
  position: absolute; top: 50%; left: 50%;
  width: .55rem; height: .55rem; margin: -.28rem 0 0 -.28rem;
  border-radius: 50%;
  background: var(--verde-claro);
  box-shadow: 0 0 0 2px rgba(4, 33, 28, .55);
  pointer-events: none;
}
.mm__falta {
  position: absolute; top: .4rem; right: .4rem;
  font-size: .62rem; font-weight: 700; text-transform: uppercase;
  background: #fdf4f3; color: #8d1e1a; border: 1px solid #e3bebc;
  padding: .05rem .3rem; border-radius: 2px;
}

/* --- el detalle: la imagen manda, porque elegir el foco es la operacion --- */
.media__cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 22rem;
  gap: 1.5rem;
  align-items: start;
}
.media__vista { background: var(--papel); border: 1px solid var(--linea); border-radius: 3px;
  padding: 1rem; }

/* El foco se elige haciendo click encima: no hay recorte manual (`docs/16`), y
   este punto es lo unico que decide como se recorta la foto en cada modulo. */
/* CONTENIDA, y el ALTO es el que importa. A ancho completo una foto apaisada ya
   ocupa media pantalla, y una vertical de 2560px no entra ni de lejos: hay que
   hacer scroll para ver dónde se está poniendo el foco, que es justo lo que esta
   pantalla existe para poder mirar de una.
   `fit-content` en el contenedor NO es cosmético: el punto se posiciona en
   porcentaje contra él, y el clic se mide con su `getBoundingClientRect()`. Si el
   contenedor fuera más ancho que la imagen —que es lo que pasa apenas la imagen
   deja de ocupar el 100%—, el punto quedaría corrido y el clic guardaría un foco
   que no es donde se hizo clic. Así el contenedor calca a la imagen. */
.foco {
  position: relative; display: block; width: fit-content; max-width: 100%;
  margin: 0 auto; cursor: crosshair; line-height: 0;
}
.foco__img {
  display: block;
  max-width: 100%; max-height: min(70vh, 40rem); width: auto; height: auto;
  border-radius: 2px; background: #e3eae8;
}
.foco__punto {
  position: absolute; top: 50%; left: 50%;
  width: 1.1rem; height: 1.1rem; margin: -.55rem 0 0 -.55rem;
  border-radius: 50%;
  border: 2px solid #fff;
  background: rgba(15, 206, 169, .85);
  box-shadow: 0 0 0 2px rgba(4, 33, 28, .5), 0 2px 6px rgba(0, 0, 0, .35);
  pointer-events: none;
  transition: top .08s, left .08s;
}
@media (prefers-reduced-motion: reduce) { .foco__punto { transition: none; } }
.foco__ayuda { font-size: .82rem; color: var(--apagado); margin: .7rem 0 0; }

.media__datos {
  display: grid; grid-template-columns: auto 1fr; gap: .2rem .8rem;
  margin: 1rem 0 0; padding-top: .8rem;
  border-top: 1px solid var(--linea);
  font-size: .82rem;
}
.media__datos dt { color: var(--apagado); }
.media__datos dd { margin: 0; font-family: var(--dato); font-size: .78rem; }

.media__form { display: flex; flex-direction: column; gap: .2rem;
  background: var(--papel); border: 1px solid var(--linea); border-radius: 3px; padding: 1rem 1.1rem; }
.media__form .campo > input, .media__form .campo > textarea {
  width: 100%; font: inherit; padding: .5rem .65rem;
  border: 1px solid var(--linea); border-radius: 2px; background: var(--papel); color: inherit;
}
.media__form .campo > textarea { resize: vertical; }
.media__form .campo > input:focus-visible, .media__form .campo > textarea:focus-visible {
  outline: 0; border-color: var(--verde); box-shadow: 0 0 0 3px rgba(0, 167, 138, .18);
}
.media__form .campo small { display: block; margin-top: .25rem; font-size: .76rem; color: var(--apagado); }
.foco__campos { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; }

@media (max-width: 66rem) {
  .media__cols { grid-template-columns: minmax(0, 1fr); }
}

/* --- la barra de progreso de la subida ------------------------------------
 * Con archivos de 20 MB en una conexion de redaccion, una barra quieta es
 * indistinguible de algo colgado. Por eso el progreso es de SUBIDA (XHR) y no un
 * spinner de adorno. */
.progreso { margin: -.6rem 0 1.2rem; }
.progreso__barra {
  height: 6px; border-radius: 3px; overflow: hidden;
  background: var(--linea);
}
.progreso__barra span {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--verde), var(--verde-claro));
  transition: width .15s linear;
}
.progreso__texto { margin: .4rem 0 0; font-size: .84rem; color: var(--apagado); }

/* --- filtros sueltos y "cargar mas" ---------------------------------------- */
.filtros-mas { display: flex; gap: .4rem; margin: -.4rem 0 1rem; }
.chip--suelto .chip__n { display: none; }
.mas { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-top: 1.2rem; }
.mas__cuantas { font-family: var(--dato); font-size: .78rem; color: var(--apagado); }

/* --- botones del detalle: TODOS del mismo tamaño --------------------------
 * Que "Borrar" fuera mas chico que "Guardar" no era un detalle estetico: la
 * diferencia de tamaño se lee como diferencia de importancia, y ahi el ojo
 * calcula mal donde esta cada cosa. Mismo tamaño, y lo destructivo se distingue
 * por color y por estar separado. */
.acciones__borrar { margin-right: auto; }

/* =========================================================================
   MEDIATECA, SEGUNDA PASADA
   Todo lo de acá salio de usarla: seleccion multiple, el dialogo de añadir, la
   pantalla de datos despues de subir, y botones que no se parten en dos lineas.
   ========================================================================= */

/* --- que NINGUN boton se parta en dos lineas -----------------------------
 * Un boton en dos renglones se lee como descuido antes de que uno sepa por que,
 * y tiene razon: si no entra, el problema es la etiqueta o el ancho, no el
 * usuario. */

.encabezado--con-accion {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
}
.encabezado__ayuda { margin: .5rem 0 0; font-size: .87rem; color: var(--apagado); max-width: 44rem; }
/* LA MISMA AYUDA, PERO AL PIE. Hernán: *"a lo sumo una ayuda, pero abajo de
   todo… la primera vez ok, ayuda, pero luego molesta"*. Arriba se lee antes que
   lo que uno vino a hacer, todos los días; abajo la encuentra el que la busca.
   Más chica y con una línea arriba, para que se lea como nota al pie. */
.pie-ayuda {
  margin: 2rem 0 0; padding-top: .8rem; border-top: 1px solid var(--linea);
  font-size: .82rem; color: var(--apagado); max-width: 44rem;
}

/* --- el dialogo de añadir ------------------------------------------------- */
.dlg {
  width: min(34rem, 92vw);
  border: 1px solid var(--linea);
  border-radius: 4px;
  padding: 1.4rem 1.5rem 1.6rem;
  background: var(--papel);
  color: var(--tinta);
  box-shadow: 0 20px 60px rgba(4, 33, 28, .25);
}
.dlg::backdrop { background: rgba(4, 33, 28, .45); }
.dlg__titulo { font-family: var(--display); font-size: 1.25rem; font-weight: 700;
  letter-spacing: -.02em; margin: 0 0 1rem; }
/* La × es un boton del sistema (`.btn btn--texto`); esta clase solo lo UBICA y
   le da tamaño. Lo demas —foco, cursor, colores— ya lo trae `.btn`.
 *
 * MIDE 2.5rem DE LADO, y no es un gusto: Hernán marcó que *"el cerrar modal del
 * multimedia está muy chiquito"*. Era un signo de 1.4rem con .2rem de padding, o
 * sea un blanco de ~28px en la esquina — abajo del mínimo táctil de 44px y
 * dificil de acertar tambien con mouse. Es ademas la unica salida visible del
 * diálogo para quien no sabe que Escape lo cierra. */
.dlg__cerrar {
  position: absolute; top: .55rem; right: .6rem;
  display: flex; align-items: center; justify-content: center;
  width: 2.5rem; height: 2.5rem; padding: 0;
  font-size: 1.6rem; line-height: 1;
  border-radius: 4px;
}
/* Un fondo al pasar: sin el, un signo suelto en la esquina no se lee como algo
   que se pueda apretar hasta que uno lo prueba. */
.dlg__cerrar:hover { background: var(--linea); }

.dlg__otras { list-style: none; margin: 1.2rem 0 0; padding: 1rem 0 0;
  border-top: 1px solid var(--linea); display: flex; flex-direction: column; gap: .8rem; }
.dlg__otras li { display: grid; grid-template-columns: 1fr auto; gap: .1rem 1rem; font-size: .87rem; }
.dlg__otras strong { grid-column: 1; }
.dlg__otras span { grid-column: 1; font-size: .8rem; color: var(--apagado); }
.dlg__otras em {
  grid-row: 1 / span 2; grid-column: 2; align-self: center;
  font-style: normal; font-size: .68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .08em; color: var(--apagado);
  border: 1px solid var(--linea); border-radius: 2rem; padding: .15rem .55rem;
}

/* La caja de arrastre ahora vive adentro del dialogo. */
.dlg .subir { display: block; margin: 0; }
.dlg .subir__caja { display: block; text-align: center; padding: 1.6rem 1.2rem; }
.dlg .subir__texto { display: block; font-size: 1rem; margin-bottom: .3rem; }

/* Soltar sobre toda la pantalla. */
.soltando { position: relative; }
.soltando::after {
  content: "Soltá los archivos para subirlos";
  position: fixed; inset: 0; z-index: 50;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--display); font-size: 1.4rem; font-weight: 700; color: var(--verde-hondo);
  background: rgba(232, 247, 243, .92);
  border: 3px dashed var(--verde);
  pointer-events: none;
}

/* --- seleccion multiple --------------------------------------------------- */
.mm__elegir {
  position: absolute; top: .45rem; left: .45rem; z-index: 2;
  width: 1.15rem; height: 1.15rem;
  border: 2px solid #fff; border-radius: 3px;
  background: rgba(4, 33, 28, .35);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .35);
  opacity: 0; transition: opacity .12s;
}
.mm:hover .mm__elegir, .mm--elegida .mm__elegir { opacity: 1; }
.mm--elegida { border-color: var(--verde-hondo); }
.mm--elegida .mm__elegir { background: var(--verde-hondo); border-color: #fff; }
.mm--elegida .mm__elegir::after {
  content: "✓"; display: block; color: #fff; font-size: .8rem; line-height: 1.1rem; text-align: center;
}

/* La barra aparece sola cuando hay algo elegido. */
.seleccion {
  position: sticky; top: 0; z-index: 6;
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: .6rem .8rem; margin-bottom: .8rem;
  background: var(--tinta); color: #dfeae7;
  border-radius: 3px;
}
.seleccion__n { font-size: .87rem; margin-right: .4rem; }
.seleccion__n strong { font-family: var(--dato); color: var(--verde-claro); }
.seleccion__sep { flex: 1; }

/* --- la pantalla de datos despues de subir -------------------------------- */
.reciens { list-style: none; margin: 1.2rem 0 0; padding: 0;
  display: flex; flex-direction: column; gap: .8rem; }
.recien {
  display: grid; grid-template-columns: 16rem minmax(0, 1fr); gap: 1.2rem;
  background: var(--papel); border: 1px solid var(--linea); border-radius: 3px;
  padding: 1rem;
}
.recien__vista { display: flex; flex-direction: column; gap: .4rem; }
.foco--chico .foco__img { max-height: 11rem; object-fit: contain; background: #eef2f1; }
.recien__ayuda { font-size: .76rem; color: var(--apagado); margin: 0; text-align: center; }
.recien__archivo { font-family: var(--dato); font-size: .72rem; color: var(--apagado); margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.recien__campos { display: flex; flex-direction: column; gap: .1rem; }
.recien__campos .campo { margin-bottom: .5rem; }
.recien__campos .campo > input {
  width: 100%; font: inherit; padding: .45rem .6rem;
  border: 1px solid var(--linea); border-radius: 2px; background: var(--papel); color: inherit;
}
.recien__campos .campo > input:focus-visible {
  outline: 0; border-color: var(--verde); box-shadow: 0 0 0 3px rgba(0, 167, 138, .18);
}
.recien__dos { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; }
.recien__pie { display: flex; justify-content: flex-end; margin-top: 1rem; }

@media (max-width: 60rem) {
  .recien { grid-template-columns: minmax(0, 1fr); }
  .recien__dos { grid-template-columns: 1fr; }
}

/* `display: flex` le gana a `[hidden]`, asi que la barra se veia vacia con
   "0 seleccionados". Es el clasico, y hay que escribirlo. */
.seleccion[hidden], [hidden] { display: none !important; }

/* Un link que hace de boton tiene que verse como boton: si no, el ojo lo lee
   como "otra cosa" justo al lado de la accion principal. */
.secundaria--link, a.secundaria {
  display: inline-flex; align-items: center; justify-content: center;
  height: 2.3rem; padding: 0 1.1rem;
  border: 1px solid var(--linea); border-radius: 2px;
  background: var(--papel); color: var(--tinta);
  font-size: .87rem; font-weight: 600; text-decoration: none;
}
.secundaria--link:hover, a.secundaria:hover { border-color: var(--verde); color: var(--tinta); }

/* --- los dialogos de preguntar --------------------------------------------
 * `confirm()` y `prompt()` del navegador no son una opcion: se ven de otra
 * epoca, el boton dice "Aceptar" pase lo que pase, bloquean el hilo, y en varios
 * navegadores se pueden desactivar sin que la aplicacion se entere. */
.dlg--pregunta { width: min(26rem, 92vw); }
.dlg__texto { font-size: .9rem; color: var(--apagado); margin: 0 0 1.1rem; line-height: 1.5; }
.dlg--pregunta .campo { margin-bottom: 1.1rem; }
.dlg--pregunta .campo > input {
  width: 100%; font: inherit; padding: .55rem .7rem;
  border: 1px solid var(--linea); border-radius: 2px; background: var(--papel); color: inherit;
}
.dlg--pregunta .campo > input:focus-visible {
  outline: 0; border-color: var(--verde); box-shadow: 0 0 0 3px rgba(0, 167, 138, .18);
}
.dlg__acciones { display: flex; justify-content: flex-end; gap: .6rem; }

/* =========================================================================
   EL SISTEMA DE BOTONES
   Hernan: "¿no podes hacer un sistema de botones que funcione siempre y
   olvidarnos de estar validando esto?".
   Antes habia reglas de boton en SEIS lugares —el login puso `.principal` con
   width:100%, la ficha lo piso con altura fija, el dialogo con otra— y por eso
   "Borrar", "Guardar" y "Guardar y seguir" no median lo mismo. El bug no era un
   descuido: era la consecuencia de tener la misma decision escrita seis veces.
   Acá esta UNA vez. Un boton es `.btn` + su variante, y nada mas.
   ========================================================================= */
.btn {
  /* La altura es la misma SIEMPRE. Es lo unico que hay que respetar para que
     tres botones al lado se vean como tres botones y no como un descuido. */
  height: 2.3rem;
  display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
  padding: 0 1.05rem;
  font: inherit; font-size: .87rem; font-weight: 600;
  line-height: 1;
  white-space: nowrap;            /* ninguno se parte en dos lineas */
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: 2px;
  cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.btn:focus-visible { outline: 2px solid var(--verde); outline-offset: 2px; }
.btn[disabled], .btn--apagado { opacity: .5; pointer-events: none; }

.btn--principal { background: var(--verde-hondo); border-color: var(--verde-hondo); color: #fff; }
.btn--principal:hover { background: var(--verde-medio); border-color: var(--verde-medio); color: #fff; }

.btn--secundario { background: var(--papel); border-color: var(--linea); color: var(--tinta); }
.btn--secundario:hover { border-color: var(--verde); color: var(--tinta); }

.btn--peligro { background: var(--papel); border-color: #e3bebc; color: #8d1e1a; }
.btn--peligro:hover { background: #fdf4f3; border-color: #a3231f; }

/* Para lo que no es una accion de peso: "Guardar y seguir", los atajos de fecha,
   la × de un dialogo, salir, plegar el menu.

   ESTABA ESCRITO PARA FONDO OSCURO Y SE USA MAYORMENTE SOBRE CLARO, que es el
   bug que reporto Hernan: el hover ponia el texto en `#fff` sobre papel, o sea
   invisible. De los siete usos, CUATRO son sobre fondo claro —"Guardar y seguir"
   entre ellos, que es el que mas se aprieta— y tres sobre oscuro. La base tiene
   que ser la del fondo por defecto del gestor, que es el claro; lo oscuro se
   pide, no se hereda. */
.btn--texto {
  height: auto; padding: 0 0 1px; background: none; border: 0;
  border-bottom: 1px solid var(--linea); color: var(--apagado); font-size: .84rem;
}
.btn--texto:hover { border-bottom-color: var(--verde); color: var(--tinta); }

/* LAS SUPERFICIES OSCURAS, TODAS JUNTAS Y EXPLICITAS.
   Antes vivian de que la base estuviera pensada para ellas. Y el detalle que casi
   se escapa al invertir la base: `.aviso__cerrar:hover` esta MUCHO mas arriba en
   esta hoja y tiene la misma especificidad que `.btn--texto:hover`, asi que la
   regla nueva le ganaba por orden y dejaba la × del aviso oscura sobre oscuro —
   el mismo bug, mudado. Por eso van con el contenedor adelante: gana el contexto,
   no el orden. */
.lateral .btn--texto,
.aviso .btn--texto { border-bottom-color: #3a5450; color: #9fb5b0; }
.lateral .btn--texto:hover { border-bottom-color: var(--verde-claro); color: #fff; }
/* La × del aviso no lleva subrayado: es un cierre, no un enlace de accion. */
.aviso .btn--texto { border-bottom-color: transparent; }
.aviso .btn--texto:hover { border-bottom-color: transparent; color: #fff; }

/* Sobre fondo oscuro (la barra de seleccion, el lateral). */
.btn--oscuro { background: transparent; color: #dfeae7; border-color: #3a5450; }
.btn--oscuro:hover { border-color: var(--verde-claro); color: #fff; }
.btn--peligro.btn--oscuro { color: #ffb4b0; border-color: #6b3330; background: transparent; }
.btn--peligro.btn--oscuro:hover { background: #3a1a18; border-color: #a3231f; }

.btn--bloque { width: 100%; }
.btn--grande { height: 2.7rem; font-size: .95rem; }

/* El chip es un boton de filtro: misma familia, forma distinta porque dice otra
   cosa —"estoy filtrando por esto"— y no ejecuta una accion. */
.btn--chip {
  height: 1.9rem; padding: 0 .75rem; border-radius: 2rem;
  background: var(--papel); border-color: var(--linea); color: var(--apagado);
  font-size: .85rem;
}
.btn--chip:hover { border-color: var(--verde); color: var(--tinta); }
.btn--chip-puesto { background: var(--tinta); border-color: var(--tinta); color: #fff; }
/* UN CHIP PUESTO INVIERTE LOS COLORES, asi que el hover de `.btn--chip` —que
   oscurece el TEXTO hasta `--tinta`— lo dejaba del mismo color que el fondo:
   el filtro activo desaparecia justo cuando el mouse estaba encima. Reportado
   por Hernan. El hover de un chip puesto se queda en blanco y mueve el borde,
   que es lo unico que puede cambiar sin perder el contraste. */
.btn--chip-puesto:hover { background: var(--tinta); border-color: var(--verde); color: #fff; }
.chip__n { font-family: var(--dato); font-size: .75rem; opacity: .75; }

/* Lo viejo, para que no vuelva: si alguien escribe `class="principal"` no se ve
   como boton y se nota enseguida. Es a proposito. */

/* =========================================================================
   FECHA Y HORA — uno solo para todo el sistema
   Hernan: "cuando es solo fecha puede andar, pero cuando hay que poner hora es
   muy malo el default". El culpable es `datetime-local`: mete la hora adentro
   del mismo control, en un desplegable minusculo. Partido en dos, cada nativo
   hace lo que sabe hacer bien.
   ========================================================================= */
.fh { display: flex; gap: .4rem; align-items: center; }
/* El componente se pinta solo: los dos controles viven adentro de `.fh`, no
   como hijos directos del campo, asi que la regla general no los alcanza — que
   es justamente lo que se busco al poner el `>`. */
.fh input {
  font: inherit;
  padding: .5rem .65rem;
  border: 1px solid var(--linea); border-radius: 2px;
  background: var(--papel); color: inherit;
}
.fh input:focus-visible {
  outline: 0; border-color: var(--verde); box-shadow: 0 0 0 3px rgba(0, 167, 138, .18);
}
.fh__dia { flex: 1 1 9rem; min-width: 0; }
.fh__hora { flex: 0 0 6.2rem; }
.fh__atajos { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .35rem; }
/* Los atajos son lo que ningun calendario trae y es lo que una redaccion hace de
   verdad con una fecha. Chicos: son ayuda, no la accion principal. */
.fh__atajo {
  font-size: .76rem; height: 1.5rem; padding: 0 .5rem;
  border: 1px solid var(--linea); border-radius: 999px; color: var(--apagado);
}
.fh__atajo:hover { border-color: var(--verde); color: var(--tinta); background: var(--papel); }

/* =========================================================================
   ELEGIR VARIOS — el reemplazo del <select multiple>
   "es muy por default, ¿podemos tener un componente mas profesional?" (Hernan).
   Lo elegido arriba y a la vista; lo que se puede agregar, abajo y plegado.
   ========================================================================= */
.campo--elegir { display: flex; flex-direction: column; gap: .4rem; }
.campo__titulo { font-size: .78rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--apagado); }

.elegidos { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .35rem; }
.elegidos__uno label {
  display: inline-flex; align-items: center; gap: .35rem;
  height: 1.8rem; padding: 0 .3rem 0 .6rem;
  border: 1px solid var(--verde); border-radius: 999px;
  background: #e8f7f3; font-size: .85rem; cursor: pointer;
}
/* El casillero es lo que hace que esto ande sin JavaScript, pero no se ve: la
   ficha ES la marca de que esta elegido. */
.elegidos__uno input { position: absolute; opacity: 0; width: 0; height: 0; }
.elegidos__sacar { color: var(--apagado); font-size: 1rem; line-height: 1; padding: 0 .2rem; }
.elegidos__uno label:hover .elegidos__sacar { color: #8d1e1a; }
.elegidos__vacio { margin: 0; font-size: .85rem; color: var(--apagado); font-style: italic; }

.sumar { font-size: .85rem; }
.sumar summary { cursor: pointer; color: var(--verde-hondo); font-weight: 600; }
/* SE PINTA SOLO, y es la contracara del `>` de arriba: al acotar `.campo input`
   al hijo directo, todo control que un componente arme adentro de su propia
   estructura pasa a ser responsabilidad del componente. Este buscador quedó sin
   estilo la primera vez justamente por eso —lo marcó Hernán— y es el precio
   correcto: mejor un campo que hay que vestir que una regla que pinta lo que no
   le corresponde. */
.sumar__buscar {
  width: 100%; margin-top: .4rem;
  font: inherit; font-size: .85rem;
  padding: .4rem .55rem;
  border: 1px solid var(--linea); border-radius: 2px;
  background: #fbfdfc; color: inherit;
}
.sumar__buscar:focus-visible {
  outline: 0; border-color: var(--verde); box-shadow: 0 0 0 3px rgba(0, 167, 138, .18);
  background: #fff;
}
.sumar__lista {
  list-style: none; margin: .4rem 0 0; padding: 0;
  max-height: 11rem; overflow-y: auto;
  border: 1px solid var(--linea); border-radius: 2px;
}
.sumar__uno label { display: flex; align-items: center; gap: .5rem; padding: .3rem .5rem; cursor: pointer; }
.sumar__uno label:hover { background: var(--papel); }
.sumar__uno[hidden] { display: none; }

/* =========================================================================
   TAGS — con acuse de recibo
   "no te quedan marcados con un chip cuando separas por comas, entonces no
   sabes muy bien si funciona" (Hernan). El campo de texto sigue siendo el que
   viaja; esto es lo que confirma que el sistema entendio.
   ========================================================================= */
.campo--tags .tags__caja {
  display: flex; flex-wrap: wrap; align-items: center; gap: .3rem;
  padding: .3rem .4rem; min-height: 2.3rem;
  border: 1px solid var(--linea); border-radius: 2px; background: #fff;
}
.campo--tags .tags__caja:focus-within {
  border-color: var(--verde); box-shadow: 0 0 0 3px rgba(0, 167, 138, .18);
}
.tag {
  display: inline-flex; align-items: center; gap: .2rem;
  height: 1.6rem; padding: 0 .2rem 0 .55rem;
  border-radius: 999px; background: #eef4f2; border: 1px solid var(--linea);
  font-size: .82rem;
}
.tag__sacar { min-width: 1.1rem; height: 1.1rem; font-size: .95rem; padding: 0; color: var(--apagado); }
.tag__sacar:hover { color: #8d1e1a; background: none; }
.tags__nuevo { border: 0; outline: 0; flex: 1 1 7rem; min-width: 5rem; padding: .2rem; font: inherit; }

/* --- ELEGIR Y CREAR NO SON LO MISMO, Y SE TIENEN QUE VER DISTINTO ----------
 *
 * Primera pieza de `docs/27` contra los miles de tags sin sentido. Antes esto
 * era un `<datalist>`: elegir uno que existe y crear uno nuevo eran el mismo
 * gesto y no se distinguían. Así es como en una semana aparecen "Milei",
 * "milei" y "Javier Milei" — casi ninguna duplicación es deliberada.
 *
 * El CONTEO a la derecha es la mitad de la feature: "40 notas" al lado de un
 * nombre dice cuál es el bueno sin que nadie tenga que explicarlo, y un tag que
 * dice "1 nota" se lee como advertencia por sí solo. */
.campo--tags { position: relative; }
.tags__sug {
  position: absolute; z-index: 6; left: 0; right: 0; top: 100%;
  margin: .2rem 0 0; padding: .25rem; list-style: none;
  max-height: 15rem; overflow-y: auto;
  background: var(--papel);
  border: 1px solid var(--linea); border-radius: 3px;
  box-shadow: 0 10px 30px rgba(4, 33, 28, .16);
}
.tags__sug[hidden] { display: none; }
.tags__sug-item {
  display: flex; align-items: baseline; justify-content: space-between; gap: .8rem;
  width: 100%; padding: .4rem .55rem;
  border: 0; border-radius: 2px; background: none; color: inherit;
  font: inherit; text-align: left; cursor: pointer;
}
.tags__sug-item:hover { background: #eef4f2; }
.tags__sug-nombre { font-weight: 600; }
.tags__sug-detalle {
  flex: none; font-family: var(--dato); font-size: .75rem; color: var(--apagado);
}
/* CREAR VA SEPARADO Y DICE QUE ES NUEVO. La línea de arriba no es adorno: es lo
   que convierte "seguir tipeando" en una decisión consciente. */
.tags__sug-item--nuevo {
  border-top: 1px solid var(--linea); border-radius: 0 0 2px 2px; margin-top: .2rem;
}
.tags__sug-item--nuevo .tags__sug-nombre { font-weight: 500; color: var(--verde-hondo); }
.tags__sug-item--nuevo .tags__sug-detalle { font-style: italic; }

/* =========================================================================
   ETIQUETAS — tags públicos y agrupadores en un solo lugar (`docs/27`)
   Reusa `.listado` y `.fila`: es la misma operación que el listado de notas
   —escanear muchas filas cortas buscando una— y dos densidades distintas para
   lo mismo se leen como dos productos.
   ========================================================================= */
.etiqueta__nueva {
  display: flex; align-items: flex-end; gap: .8rem; flex-wrap: wrap;
  margin-bottom: 1.2rem; padding: .9rem 1.1rem;
  background: var(--papel); border: 1px solid var(--linea); border-radius: 3px;
}
/* El nombre no necesita el ancho de la pantalla: un campo de novecientos píxeles
   para escribir "elecciones" se ve mal y encima miente sobre cuánto entra. */
.etiqueta__nueva .campo { flex: 0 1 20rem; margin: 0; }
.etiqueta__nueva .chk { margin-bottom: .45rem; }

.fila--etiqueta { grid-template-columns: 7.5rem minmax(0, 1fr) 9rem auto; }
/* El slug es la URL y no se puede cambiar: se muestra para que se vea POR QUÉ
   renombrar no la mueve. En monoespaciada porque es una dirección, no un nombre. */
.etiqueta__slug {
  display: block; font-family: var(--dato); font-size: .76rem; color: var(--apagado);
  margin-top: .1rem;
}
.etiqueta__n { font-family: var(--dato); font-size: .8rem; }

/* --- páginas: la de la raíz y la que no tiene dirección (`docs/36`) ---------- */
/* La home va primera y marcada. Era una entrada propia del menú lateral hasta
   que «Portada» se fue de ahí: sin esta marca, el destino que más se abre queda
   perdido entre las otras diecinueve. */
/* El nombre y su marca, EN LA MISMA LINEA. Hace falta el contenedor: el título
   es un `<a>` en `display: block` (para que el objetivo sea toda la fila), así
   que sin esto la marca se cae al renglón de abajo y la fila queda en tres
   pisos. `min-width: 0` para que un nombre largo recorte y no empuje la marca. */
.pagina__linea { display: flex; align-items: baseline; gap: .5rem; min-width: 0; }
.pagina__linea a { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pagina__raiz {
  flex: none; padding: .1rem .45rem;
  font-size: .7rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--papel); background: var(--verde-medio); border-radius: 2px;
}
/* Sin dirección y sin la raíz: no se ve en ninguna parte del sitio. En rojo
   porque es un estado que hay que arreglar, no una variante. */
.etiqueta__slug--sin { color: #b23; font-style: italic; }

/* Las dos opciones de dirección. `fieldset` porque son excluyentes de verdad:
   una página tiene URL propia o no la tiene. */
.direccion {
  border: 1px solid var(--linea); border-radius: 3px; padding: .7rem .9rem;
  margin-bottom: 1rem;
}
.direccion legend { font-size: .8rem; color: var(--apagado); padding: 0 .3rem; }
.direccion .campo { margin: .3rem 0 .7rem 1.5rem; }
.direccion--fija .rotulo { margin: 0 0 .3rem; }
/* La de la raíz no elige: la pantalla explica por qué y no ofrece un control. */
.direccion__fija { margin: 0; font-size: .86rem; color: var(--apagado); }
/* La de una sola nota se marca: es la que hay que limpiar o fusionar. El mismo
   borde que usa el listado de usuarios para la fila que pide una mirada. */

/* Un separador dentro de una columna de formulario. */
.rotulo--sep { margin-top: 1.6rem; padding-top: 1rem; border-top: 1px solid var(--linea); }
.chk--grande { font-size: .95rem; font-weight: 600; }

/* =========================================================================
   EL EDITOR, SEGUNDA PASADA
   Hernán: "entré a la página de TipTap y los iconos y funcionalidades eran
   mejores que lo que tenemos puesto… pensá que esto es todo el sistema".
   Tiene razón en las dos mitades: el editor es donde la redacción pasa el día,
   y le faltaban las dos cosas que hacen que un editor se sienta moderno —la
   barra que aparece donde está la selección, y el menú que aparece donde se va
   a insertar.
   ========================================================================= */

/* La caja pasa a ser el marco de referencia de lo que flota adentro. */
.editor { position: relative; }

/* --- negrita y cursiva son LETRAS, no dibujos (ver `ui/iconos.ts`) --------- */
.letra { font-family: var(--display); font-size: 1rem; line-height: 1; }
.letra--negrita { font-weight: 800; }
.letra--cursiva { font-style: italic; font-weight: 500; padding: 0 .15rem; }

/* --- la barra flotante ---------------------------------------------------- */
.editor__flota {
  position: absolute; z-index: 5;
  display: flex; gap: .1rem;
  padding: .2rem;
  background: var(--tinta);
  border-radius: 3px;
  box-shadow: 0 6px 20px rgba(4, 33, 28, .3);
  animation: flota-entra .1s ease-out;
}
.editor__flota[hidden] { display: none; }
.editor__flota .editor__boton { color: #cfe0dc; }
.editor__flota .editor__boton:hover { background: #23433d; color: #fff; }
.editor__flota .editor__boton--activo { background: var(--verde); border-color: var(--verde); color: #fff; }
/* La punta que apunta a la selección: es lo que hace que se lea como "esto es
   para lo que marcaste" y no como una barra suelta. */
.editor__flota::after {
  content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  border: 5px solid transparent; border-top-color: var(--tinta);
}
@keyframes flota-entra { from { opacity: 0; transform: translateY(3px); } }
@media (prefers-reduced-motion: reduce) { .editor__flota { animation: none; } }

/* --- el `+` de la línea vacía y su menú ----------------------------------- */
.editor__mas {
  position: absolute; left: .35rem; z-index: 4;
  width: 1.6rem; height: 1.6rem;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 999px;
  background: none; color: var(--apagado); cursor: pointer;
}
.editor__mas[hidden] { display: none; }
.editor__mas:hover { background: #eef4f2; color: var(--verde-hondo); }
.editor__mas .ico { width: 1.1rem; height: 1.1rem; }

.editor__lista {
  position: absolute; z-index: 6;
  min-width: 15rem;
  padding: .3rem;
  background: #fff;
  border: 1px solid var(--linea); border-radius: 3px;
  box-shadow: 0 10px 30px rgba(4, 33, 28, .16);
}
.editor__lista[hidden] { display: none; }
.editor__opcion {
  display: flex; align-items: center; gap: .6rem; width: 100%;
  padding: .45rem .5rem;
  border: 0; border-radius: 2px;
  background: none; color: inherit; text-align: left; cursor: pointer;
  font: inherit;
}
.editor__opcion:hover { background: var(--papel); }
.editor__opcion .ico { width: 1.15rem; height: 1.15rem; color: var(--verde-hondo); flex: none; }
.editor__opcion span { display: flex; flex-direction: column; }
.editor__opcion strong { font-size: .88rem; font-weight: 600; }
.editor__opcion small { font-size: .76rem; color: var(--apagado); }

/* --- el texto de ayuda del documento vacío -------------------------------- */
/* Con `::before` y `float`, que es lo que no empuja el cursor una línea abajo. */
.editor .ProseMirror .editor__marcador::before {
  content: attr(data-marcador);
  float: left; height: 0; pointer-events: none;
  color: var(--apagado); opacity: .7;
}

/* La barra flotante, cuando no entra arriba, va abajo — y la punta con ella. */
.editor__flota--abajo::after {
  top: auto; bottom: 100%;
  border-top-color: transparent; border-bottom-color: var(--tinta);
}

/* --- la imagen en el editor: como se va a ver publicada -------------------
 * Hernán: "meto una imagen y pone una imagencita ahí perdida". El editor tiene
 * que mostrar la foto al tamaño que va a salir, con su epígrafe debajo y
 * escribible. Una miniatura obliga a imaginarse el resultado. */
.editor__img { margin: 1.6rem 0; }
.editor__img img,
.editor__img video {
  display: block; width: 100%; height: auto;
  border-radius: 2px; background: var(--papel);
}
.editor__img figcaption {
  font-size: .85rem; color: var(--apagado);
  padding: .45rem .2rem 0;
  border-bottom: 1px dashed transparent;
  min-height: 1.6em;
}
/* El epígrafe vacío se ANUNCIA: es el campo que nunca se completa si no se pide. */
.editor__img figcaption:empty::before,
.editor__img figcaption.is-empty::before {
  content: attr(data-marcador);
  color: var(--apagado); opacity: .6; pointer-events: none;
}
.editor__img figcaption:focus { outline: 0; border-bottom-color: var(--verde); }

/* Los tres tamaños. Son DATO del bloque, no estilo suelto: el sitio decide qué
   significa cada uno en su layout, y una nota escrita hoy no se rompe si el
   diseño cambia. Acá se muestra la proporción, que es lo que hay que juzgar. */
.editor__img--ancha { margin-left: -2rem; margin-right: -2rem; }
.editor__img--completa { margin-left: -2rem; margin-right: -2rem; }
.editor__img--completa img { border-radius: 0; }

/* La barra del bloque: la misma forma que la flotante de texto, con etiquetas
   en vez de íconos donde el nombre dice más que un dibujo. */
.editor__flota--bloque .editor__tam {
  font-size: .76rem; font-weight: 600; letter-spacing: .01em; padding: 0 .35rem;
}
.editor__flota--bloque .editor__sep { background: #3a5450; }

/* =========================================================================
   EL SELECTOR DE MULTIMEDIA
   Hernán: "el modal que abre de multimedia parecemos un CMS de gente sin
   experiencia". Tenía razón, y no era cuestión de estilo: lo que había era una
   lista de miniaturas sacadas del DOM, sin buscador ni filtros, cuando
   `docs/21` decía "selector reusable". Ahora es LA MEDIATECA adentro de un
   diálogo — mismos filtros, misma grilla, mismo scroll.
   ========================================================================= */
/* ELEGIR UNA FOTO ES MIRAR FOTOS, ASI QUE OCUPA LA PANTALLA.
 *
 * Hernán: *"el modal que se abre de multimedia, aprovechemos toda la pantalla"*.
 * Estaba topeado en `min(64rem, …)` y `min(46rem, …)`, o sea que en un monitor
 * grande dejaba de crecer aunque sobrara lugar: en una pantalla de 27" mostraba
 * las mismas ocho miniaturas que en una notebook, con el resto en negro.
 *
 * El tope alto se queda —una grilla de 2000px de ancho da filas de doce fotos
 * diminutas y se vuelve peor, no mejor— pero ahora es un techo real y no uno que
 * se alcanza en cualquier monitor de escritorio. */
.dlg--selector {
  width: 96vw;
  max-width: 100rem;
  height: 92vh;
  max-height: none;
  padding: 1.2rem 1.4rem;
  display: flex; flex-direction: column;
}
/**
 * EL `[data-cuerpo]` TAMBIEN ES UN ESLABON, y le faltaba serlo.
 *
 * El guion arma `<dialog> > <div data-cuerpo> > .selector`, y `.selector` ya
 * pedia `flex:1; min-height:0` para que scrollee la lista y no el dialogo. Pero
 * en el medio hay un `<div>` sin nada declarado: como item flex del dialogo
 * crece con su contenido, asi que la cadena se cortaba ahi y **scrolleaba el
 * dialogo entero**. En el selector de notas eso dejaba el pie —la cuenta y el
 * boton "Listo"— dos mil pixeles abajo del borde.
 *
 * En el selector de FOTOS el mismo hueco estaba y no se veia: las 24 miniaturas
 * de la primera pagina entran justas en pantalla. Con "Cargar mas" apretado una
 * vez, se rompia igual.
 */
.dlg--selector [data-cuerpo] {
  display: flex; flex-direction: column; flex: 1; min-height: 0;
}
.selector { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.selector__cab { margin-bottom: .3rem; }
.selector__cuantos { margin: .15rem 0 0; font-size: .84rem; color: var(--apagado); }
/* Lo único que scrollea es la grilla: los filtros y el buscador se quedan
   arriba, que es donde hacen falta cuando hay doscientos archivos. */
.selector__grilla { flex: 1; min-height: 0; overflow-y: auto; padding-top: .2rem; }

/* --- Subir desde el selector ---------------------------------------------
   La cabecera pasa a tener dos cosas —el titulo y el control de subir— asi que
   se reparten en una fila. En pantalla angosta se apilan: el control de subir
   es lo que se vino a buscar, no un adorno del costado. */
.selector__cab {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: .8rem;
  flex-wrap: wrap;
  /* El hueco de la × del diálogo, que está posicionada encima de todo: sin esto
     «Añadir material» le queda debajo y la cruz no se puede apretar. */
  padding-right: 2.6rem;
}
/* «Añadir material» adentro del selector: el MISMO contenido que el diálogo de la
   pantalla (`formasDeSubir`), en un panel que se despliega en el lugar — un
   diálogo adentro de otro diálogo es donde el foco y el Escape se pelean.
   Acá vivían `.selector__subir*`, una caja de subida propia con su texto propio.
   La sacó Hernán: *"parece como que inventaste un nuevo sistema para subir
   archivos"*. Era eso, y encima subía por otro camino. */
.anadir {
  margin: .8rem 0 0;
  padding: 1rem 1.1rem;
  border: 1px solid var(--linea);
  border-radius: 3px;
  background: var(--papel);
}

.selector__aviso {
  margin: .4rem 0 0;
  padding: .45rem .7rem;
  border-radius: 3px;
  background: var(--fondo);
  font-size: .84rem;
}
/* Mismo trato que `.error`: el borde de color a la izquierda es lo que lo hace
   distinguible de un aviso comun de un vistazo, sin leerlo. */
.selector__aviso--mal {
  background: #fdf4f3;
  border-left: 3px solid #a3231f;
  color: #8d1e1a;
}

/* Lo recien subido, marcado hasta que se cierre el selector. Sin esto, en una
   grilla de doscientas miniaturas iguales no hay forma de saber cual es la que
   acabas de subir — que es exactamente lo que se vino a buscar. */
.mm--recien { outline: 2px solid var(--verde-hondo); outline-offset: 2px; }

.selector__cargando { color: var(--apagado); font-size: .9rem; padding: 2rem 0; }
/* En el selector la tarjeta ELIGE: no hay casillero de selección múltiple. */
.dlg--selector .mm__elegir { display: none; }
.dlg--selector .mm { cursor: pointer; }
.dlg--selector .mms { grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); }

/* --- el cursor ENTRE bloques ----------------------------------------------
 * Hernán: "tengo dos imágenes y no tengo forma de poner texto entre medio".
 * ProseMirror ya tenía la posición —se llega con las flechas y con un click—,
 * pero TipTap es headless y **no trae este CSS**: el cursor estaba ahí y era
 * invisible. Para el que escribe, invisible es lo mismo que inexistente.
 *
 * Se dibuja como un cursor de texto ancho, que es lo que es: si escribís, ahí
 * nace un párrafo. */
.editor .ProseMirror-gapcursor { display: none; pointer-events: none; position: relative; }
.editor .ProseMirror-gapcursor::after {
  content: ""; display: block; position: absolute; top: -2px;
  width: 100%; border-top: 2px solid var(--verde);
  animation: gap-late 1.1s steps(2, start) infinite;
}
.editor .ProseMirror-gapcursor:first-child { margin-top: 0; }
.editor .ProseMirror-focused .ProseMirror-gapcursor { display: block; }
@keyframes gap-late { to { visibility: hidden; } }
@media (prefers-reduced-motion: reduce) {
  .editor .ProseMirror-gapcursor::after { animation: none; }
}

/* La zona de abajo de todo: clic ahí y seguís escribiendo. Sin esto, una nota
   que termina en imagen no tiene dónde poner el cursor. */
.editor .ProseMirror { padding-bottom: 2.5rem; }

/* --- La dirección pública de la nota (riel de Publicación) -------------------
   Se muestra, no se edita: `url_at` se congela en la primera publicación y ése
   es justamente el motivo por el que existe. La fecha de la URL se lee adentro
   del enlace, que es lo que faltaba para poder explicar una nota cuya URL no
   coincide con las dos fechas de arriba. */
.urlpub { list-style: none; margin: 0; padding: 0; display: grid; gap: .3rem; }
.urlpub li { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.urlpub__cab { font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; opacity: .65; }
/* `break-all` y no `ellipsis`: un slug largo cortado con puntos suspensivos deja
   de servir para lo único que se usa, que es leer la fecha y copiar el enlace. */
.urlpub__enlace { font-size: .8rem; line-height: 1.35; word-break: break-all; }
.urlpub--provisoria .urlpub__enlace { opacity: .7; font-style: italic; }
.urlpub--sin { font-size: .8rem; opacity: .7; margin: 0; }

/* --- La pantalla de guardado (`ui/guardada.ts`) ------------------------------
   Reemplaza al "volver al listado". Lo que se viene a buscar acá es LA URL: para
   pasarsela a quien prepara la publicidad. Por eso la direccion es lo unico que
   pesa visualmente y todo lo demas está apagado. */
.guardada { max-width: 46rem; }
.guardada__ok { font-size: .78rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--verde-hondo); font-weight: 700; margin: 0 0 .3rem; }
.guardada__titulo { font-family: var(--display); font-size: 1.5rem; font-weight: 700;
  letter-spacing: -.02em; margin: 0 0 .3rem; }
.guardada__estado { font-size: .86rem; color: var(--apagado); margin: 0 0 1.4rem; }

.guardada__sitios { list-style: none; margin: 0; padding: 0; display: grid; gap: .8rem; }
.guardada__sitio { display: grid; grid-template-columns: 1fr auto; gap: .1rem .8rem;
  align-items: center; padding: .8rem 1rem; border: 1px solid var(--linea);
  border-radius: .5rem; background: var(--papel); }
.guardada__cab { grid-column: 1; font-size: .74rem; text-transform: uppercase;
  letter-spacing: .04em; color: var(--apagado); }
.guardada__principal { grid-column: 2; grid-row: 1; font-size: .68rem;
  text-transform: uppercase; letter-spacing: .04em; color: var(--verde-hondo); font-weight: 700; }
/* `break-all`: una URL cortada con puntos suspensivos no se puede copiar a ojo,
   que es justo para lo que se muestra. */
.guardada__url { grid-column: 1; grid-row: 2; font-size: .92rem; word-break: break-all;
  color: var(--tinta); font-weight: 600; }
.guardada__copiar { grid-column: 2; grid-row: 2; }
.guardada__falta { grid-column: 1; grid-row: 2; font-size: .86rem; color: var(--apagado); }
.guardada__sitio--sin { border-style: dashed; }

.guardada__sale { margin: 1rem 0 0; padding: .8rem 1rem; border-radius: .5rem;
  background: #eef7f4; font-size: .88rem; line-height: 1.5; }
.guardada__sale--borrador { background: var(--papel); border: 1px solid var(--linea); }

.guardada__seguir { margin-top: 2rem; padding-top: 1.2rem; border-top: 1px solid var(--linea); }
.guardada__seguir .rotulo { margin-bottom: .7rem; }
.guardada__seguir .btn { margin: 0 .4rem .4rem 0; }

/* =========================================================================
   USUARIOS Y PERFIL
   La lista reusa `.listado` y `.fila` del listado de notas, y no por ahorro:
   son la misma operacion —escanear muchas filas cortas buscando una— y dos
   densidades distintas para lo mismo se leen como dos productos.
   ========================================================================= */

.usuario__correo {
  display: block;
  font-family: var(--dato);
  font-size: .78rem;
  color: var(--apagado);
  margin-top: .1rem;
}
.usuario__yo {
  font-family: var(--texto);
  font-size: .68rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--verde-hondo);
}

/* La fila que pide una mirada. Un borde, no un fondo de color: el fondo
   compite con el `.pill` del estado, que es lo primero que hay que leer. */
.fila--ojo { box-shadow: inset 3px 0 0 #e0b64a; }

.usuario__form { max-width: 34rem; }

/* --- el reparto: lo que se edita seguido, y lo suelto ---------------------
 *
 * Nacio en la cuenta (perfil y edicion de usuario). Hernan: "perfil y editar
 * usuario son muy pobres visualmente". Eran una tira de 34rem pegada a la
 * izquierda con las secciones separadas por una linea, en una pantalla que da
 * para el doble — las unicas del gestor que no usaban tarjetas como el panel de
 * inicio o la mediateca.
 *
 * El reparto no es estetico: a la izquierda LO QUE SE EDITA SEGUIDO —quien es la
 * persona, que es la etiqueta—, a la derecha LAS OPERACIONES SUELTAS —la
 * contrasena, el acceso, fusionar, los ajustes que casi nunca se tocan—. Se
 * apila cuando no entra.
 *
 * SE LLAMA `reparto` Y NO `cuenta` porque no es de la cuenta: la ficha de
 * etiqueta pedia exactamente la misma forma. Antes usaba `.tarjetas`, que es
 * `auto-fit minmax(15rem, 1fr)` — pensado para tarjetas de LECTURA (el panel de
 * inicio, dos y anchas). Con tres tarjetas de FORMULARIO da tres columnas de
 * 15rem, y ahi cada campo mide menos que su propia ayuda. Lo marco Hernan:
 * *"cuando editas un tag publico, a 3 columnas es imposible, queda todo
 * apretado"*.
 *
 * La leccion es que el numero de columnas no puede salir de cuantas secciones
 * haya. `auto-fit` reparte el ancho entre las que existan, asi que agregar una
 * seccion ANGOSTA todas las demas — un formulario que estaba bien se rompe el
 * dia que gana un campo mas, sin que nadie toque su CSS. Un reparto fijo con un
 * lado principal no tiene esa propiedad. */
.reparto {
  display: grid; gap: 1.2rem;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  align-items: start;
}
.reparto__lado { display: grid; gap: 1.2rem; align-content: start; }

/**
 * EL LADO QUE SE QUEDA A LA VISTA mientras el otro se recorre.
 *
 * Lo usa el editor de menús: el árbol puede tener treinta ítems y el formulario
 * que los edita es uno solo. Sin esto, editar el ítem 28 obliga a subir hasta el
 * formulario, escribir, y volver a bajar para ver dónde estaba.
 *
 * `max-height` + `overflow-y` porque un panel más alto que la ventana pegado
 * arriba deja su propio botón de guardar fuera de la pantalla, y ahí el sticky
 * pasa de ayudar a estorbar.
 *
 * Sólo en dos columnas: apilado, "pegado arriba" taparía el contenido de abajo,
 * que es justo lo que se está mirando.
 */
@media (min-width: 62.01rem) {
  .reparto__lado--fijo {
    position: sticky;
    top: 1.2rem;
    max-height: calc(100vh - 2.4rem);
    overflow-y: auto;
  }
}
@media (max-width: 62rem) { .reparto { grid-template-columns: minmax(0, 1fr); } }

/* La chapa: estado, rol y correo de un vistazo. La pantalla mostraba el nombre y
   nada mas, asi que para saber si esa cuenta podia entrar habia que volver al
   listado — que es donde si estaba, en su pildora. */
.cuenta__chapa {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin: .5rem 0 0; font-size: .85rem;
}
.cuenta__rol { color: var(--verde-hondo); font-weight: 600; }
.cuenta__correo { color: var(--apagado); font-family: var(--dato); font-size: .8rem; }

/* Adentro de una tarjeta ya no hace falta la linea ni el margen: el borde de la
   tarjeta es lo que separa, y sumarle otro deja dos rayas paralelas. */
.usuario__bloque { max-width: none; }
.usuario__bloque .usuario__form { max-width: none; }
.usuario__bloque h2 {
  font-family: var(--display);
  font-size: 1.05rem; font-weight: 700; letter-spacing: -.015em;
  margin: 0 0 .3rem;
}
.usuario__bloque .encabezado__ayuda { margin-bottom: 1rem; }

/* Un control apagado tiene que PARECER apagado: si se ve igual que uno vivo,
   el que lo intenta escribir cree que se rompio el teclado. */
.campo > input:disabled, .campo > select:disabled {
  background-color: #f1f4f3;
  color: var(--apagado);
  cursor: not-allowed;
}

.sesiones { list-style: none; margin: 0; padding: 0; }
.sesiones__una {
  display: flex; align-items: baseline; gap: .8rem;
  padding: .55rem 0;
  border-bottom: 1px solid var(--linea);
  font-size: .87rem;
}
.sesiones__una:last-child { border-bottom: 0; }
/* QUE dispositivo es, primero; la IP al lado y en chico.
   Hernan, mirando su lista —ocho renglones que decian `::1`—: "raro, no aporta
   mucho". La pregunta que la pantalla hace es "reconoces esta sesion?", y eso lo
   contesta el navegador, no un numero. La IP se queda porque sostiene el indicio
   de cuenta compartida; lo que cambio es que dejo de ser lo unico. */
.sesiones__que { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.sesiones__ip { font-family: var(--dato); font-size: .75rem; color: var(--apagado); }
/* La accion que le faltaba a la lista: sin esto, ver una sesion que no reconoces
   no tenia mas salida que cambiar la contrasena. */
.sesiones__cerrar { margin-top: .9rem; display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.sesiones__cerrar small { font-size: .78rem; color: var(--apagado); }
.sesiones__uso { color: var(--apagado); margin-left: auto; }
.sesiones__esta {
  font-size: .68rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--verde-hondo);
}

/* El nombre del lateral es el camino al perfil, y tiene que verse pulsable
   sin gritarlo: el color lo hereda, lo unico que cambia es al pasar por encima. */
.lateral__pie .quien a { color: inherit; text-decoration: none; }
.lateral__pie .quien a:hover { text-decoration: underline; }
.lateral__pie .quien a:focus-visible { outline: 2px solid var(--verde); outline-offset: 2px; }

/* =========================================================================
   EL FLOTANTE DE LA ETAPA DE PRUEBAS  ·  SE BORRA ENTERO AL TERMINARLA
   Hernán, 2026-08-09: *"poner un flotante en todo el gestor para que los
   testers vayan anotando cosas… esto es solo para esta etapa de desarrollo,
   luego se elimina"*. Todo lo de acá está junto y con este rótulo para que
   sacarlo sea borrar un bloque, no ir a buscar reglas repartidas.
   ========================================================================= */
.pru {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 60;
  /* El ancho lo pone la caja al abrirse; cerrado, el botón manda. */
  max-width: min(26rem, calc(100vw - 2rem));
}
/* El `<summary>` ES el botón: así abre sin JavaScript, que es justo lo que hace
   falta el día que se rompa el guion — y ese día es cuando hay que reportarlo. */
.pru__boton {
  display: inline-flex; align-items: center; gap: .45rem;
  margin-left: auto;
  padding: .55rem .9rem;
  border-radius: 999px;
  background: var(--verde-hondo); color: #fff;
  font-size: .85rem; font-weight: 600;
  box-shadow: 0 6px 20px rgba(4, 33, 28, .28);
  cursor: pointer; list-style: none; user-select: none;
  width: fit-content;
}
.pru__boton::-webkit-details-marker { display: none; }
.pru__boton:hover { filter: brightness(1.08); }
.pru[open] .pru__boton { border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; }
/* El punto de novedades sin leer: lo enciende el guion sacando `hidden`. */
.pru__punto {
  width: .5rem; height: .5rem; border-radius: 50%;
  background: #ffd34d; box-shadow: 0 0 0 2px rgba(4, 33, 28, .35);
}

.pru__caja {
  margin-top: .5rem;
  width: min(26rem, calc(100vw - 2rem));
  max-height: min(34rem, calc(100vh - 6rem));
  overflow-y: auto;
  background: var(--papel);
  border: 1px solid var(--linea); border-radius: 4px;
  box-shadow: 0 20px 60px rgba(4, 33, 28, .25);
  padding: 1rem 1.1rem 1.1rem;
}
.pru__ayuda { margin: .3rem 0 .8rem; font-size: .82rem; color: var(--apagado); }

/* Las dos solapas del flotante: una se escribe, la otra se lee. Radio + CSS,
   como las de la ficha — andan sin JavaScript, que acá es la regla. */
.pru__radio { position: absolute; opacity: 0; pointer-events: none; }
.pru__solapas {
  display: flex; gap: .2rem;
  border-bottom: 1px solid var(--linea); margin-bottom: .9rem;
}
.pru__solapa {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .4rem .7rem; cursor: pointer;
  font-size: .84rem; font-weight: 600; color: var(--apagado);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.pru__solapa:hover { color: var(--tinta); }
#pru_tab_contar:checked ~ .pru__solapas .pru__solapa[for="pru_tab_contar"],
#pru_tab_nov:checked ~ .pru__solapas .pru__solapa[for="pru_tab_nov"] {
  color: var(--verde-hondo); border-bottom-color: var(--verde-hondo);
}
/* El foco del teclado tiene que verse: el radio es invisible, así que lo muestra
   la solapa. Sin esto, tabular por el flotante deja de tener referencia. */
.pru__radio:focus-visible ~ .pru__solapas .pru__solapa { outline: 2px solid var(--verde); outline-offset: -2px; }
.pru__panel { display: none; }
#pru_tab_contar:checked ~ [data-pru-panel="contar"],
#pru_tab_nov:checked ~ [data-pru-panel="nov"] { display: block; }


/* Las tres opciones, una debajo de otra: puestas en fila el texto de ayuda no
   entra, y sin la ayuda "duda" e "idea" se eligen a ojo. */
.pru__tipos { display: grid; gap: .35rem; margin-bottom: .7rem; }
.pru__tipo { display: flex; gap: .5rem; align-items: flex-start; cursor: pointer; }
.pru__tipo small { display: block; font-size: .78rem; color: var(--apagado); }
.pru__tipo input { margin-top: .25rem; }

.pru__acciones { display: flex; justify-content: flex-end; }
.pru__nov { list-style: none; margin: 0; padding: 0; display: grid; gap: .8rem; }
.pru__novcab { display: flex; justify-content: space-between; gap: .6rem; margin: 0; font-size: .85rem; }
.pru__novcab time { font-size: .75rem; color: var(--apagado); white-space: nowrap; }
.pru__nov ul { margin: .2rem 0 0; padding-left: 1.1rem; font-size: .82rem; color: var(--apagado); }
.pru__vacio { font-size: .82rem; color: var(--apagado); margin: .4rem 0 0; }

/* La lista de reportes, para nosotros. */
.reps .rep__texto { margin: 0; white-space: pre-wrap; }
.reps .rep__ctx { margin: .25rem 0 0; font-size: .75rem; color: var(--apagado); }
.reps .rep__quien { font-size: .8rem; color: var(--apagado); white-space: nowrap; }
.rep__tipo {
  display: inline-block; padding: .1rem .45rem; border-radius: 3px;
  font-size: .72rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
}
.rep__tipo--problema { background: #fdf4f3; color: #8d1e1a; }
.rep__tipo--idea { background: #eef7f1; color: var(--verde-hondo); }
.rep__tipo--duda { background: #fdf8e3; color: #7a6a1f; }
/* Lo resuelto se apaga en vez de esconderse: sigue siendo el registro de que se
   atendió, y verlo apagado es lo que hace visible cuánto se resolvió. */
.rep--2 { opacity: .5; }

@media (max-width: 40rem) {
  .pru__texto { display: none; }
}

/* --- la revisión de la nota, plegada bajo el editor ------------------------
 *
 * TERCER LUGAR Y EL QUE QUEDA. Estuvo adentro de la solapa SEO —donde no la veía
 * nadie— y después en el riel derecho, de donde la sacó Hernán: *"perdemos el
 * foco en la fecha y cosas más importantes"*. El criterio ya estaba escrito en
 * `ui/ficha.ts`: el riel es lo que se toca en TODAS las notas, y una lista de
 * sugerencias no lo es.
 *
 * Acá es lo que es: información ambiente, hermana de la línea de palabras que
 * está justo arriba. Cerrada ocupa un renglón. */
.revx { margin: .3rem 0 0; }
.revx > summary {
  cursor: pointer; list-style: none;
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .82rem; font-weight: 600; color: var(--verde-hondo);
}
.revx > summary::-webkit-details-marker { display: none; }
/* El triangulito lo dibujamos nosotros: el nativo cambia de forma en cada
   navegador y acá conviven tres tamaños de texto chicos. */
.revx > summary::before {
  content: "▸"; font-size: .7em; opacity: .7; transition: transform .12s;
}
.revx[open] > summary::before { content: "▾"; }
.revx > summary:hover { color: var(--verde-medio); }
/* Sin nada para corregir se apaga en vez de desaparecer: que aparezca y se vaya
   movería el editor de lugar cada vez que se arregla la última cosa. */
.revx--bien > summary { color: var(--apagado); font-weight: 400; }
.revx .revision { margin-top: .5rem; }
.revx > small { display: block; margin-top: .5rem; font-size: .78rem; color: var(--apagado); }

/* La fila que dice que no existe y que no se puede crear. No es un botón: no
   hace nada, y por eso no se comporta como uno. */
.tags__sug-item--no { cursor: default; color: var(--apagado); }
.tags__sug-item--no:hover { background: none; }
.tags__sug-item--no .tags__sug-nombre { font-weight: 500; }

/* --- en qué diario estás parado (`cabecera-actual.ts`) ----------------------
 *
 * Va pegado a la marca y no adentro del listado como un filtro: no es "qué notas
 * veo" sino para qué diario estoy trabajando. Sale sólo con más de una cabecera.
 *
 * El botón "Ir" existe para que el selector funcione sin JavaScript. Con el
 * guion puesto sobra —el `onchange` manda el formulario— así que se esconde; la
 * clase la pone `gestor.js` al arrancar, o sea que sin guion el botón queda. */
.lateral__cab {
  display: flex; flex-wrap: wrap; align-items: center; gap: .4rem;
  margin: 0 0 .9rem; padding: 0 .1rem;
}
.lateral__cab .rotulo {
  width: 100%; margin: 0 0 .1rem;
  color: rgba(255, 255, 255, .55);
}
.lateral__cab select {
  flex: 1 1 auto; min-width: 0;
  font-size: .85rem; padding: .35rem 1.6rem .35rem .5rem;
  color: #fff;
  background-color: rgba(255, 255, 255, .08);
  border-color: rgba(255, 255, 255, .18);
  /* La flecha de la hoja es gris oscuro y acá el fondo es la tinta: se repite en
     claro en vez de heredar una que no se vería. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%23ffffff' stroke-opacity='.7' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
}
/* `background-color` por lo mismo que el resto: en un `<option>` el atajo no
   rompe nada —no lleva flecha—, pero deja la trampa armada para el día que
   alguien copie esta línea a un `select`. */
.lateral__cab select option { color: var(--tinta); background-color: #fff; }
.lateral__cab select:focus-visible {
  border-color: var(--verde-claro);
  box-shadow: 0 0 0 3px rgba(15, 206, 169, .25);
}
.lateral__cab-ir {
  font-size: .8rem; padding: .3rem .6rem;
  color: #fff; background: rgba(255, 255, 255, .1);
  border: 1px solid rgba(255, 255, 255, .18); border-radius: 2px;
}
.lateral__cab-ir:hover { background: rgba(255, 255, 255, .18); }
/* Con guion, el botón sobra. */
.con-guion .lateral__cab-ir { display: none; }

/* Plegado no entra un desplegable: se esconde entero. La marca sigue diciendo
   en cuál estás, que es lo que hace falta para no equivocarse. */
.lateral--min .lateral__cab { display: none; }

/* En qué cabeceras va una sección, en su fila del listado. Va debajo del slug y
   no en una columna propia: con una sola cabecera no existe, así que una columna
   fija dejaría un hueco en el caso normal. */
.seccion__donde { display: block; font-size: .78rem; color: var(--apagado); }
/* El cargo del autor, en su fila del listado. Es lo que distingue dos personas
   con el mismo nombre, así que va pegado al nombre y no en una columna aparte. */
.autor__rol { display: block; font-size: .8rem; color: var(--apagado); }

/* --- navegación: la raíz, como una fila más (`docs/36`) ----------------------
 * NO TIENE ESTILO PROPIO Y ESE ES EL PUNTO. Usa `.fila--menu` igual que un menú
 * —misma grilla, misma chapa, mismo alto— porque contesta la misma clase de
 * pregunta: qué dirección lleva a qué. Lo pidió Hernán: *"la idea es que
 * parezca un ítem más de menús"*.
 * Lo único propio son estas tres líneas: el nombre no es un enlace (no hay
 * adónde ir sin pedir otro permiso) y el selector ocupa la columna donde un
 * menú muestra cuántos ítems tiene. */
.fila__home { font-weight: 600; color: var(--tinta); }
.fila__fecha--raiz { text-align: left; }
.fila__fecha--raiz select { width: 100%; }

/* --- navegación: el lugar que el diseño pide y no tiene menú -----------------
 * Se marca como se marca un ítem roto en el árbol —borde rojo a la izquierda— y
 * por el mismo motivo: es algo que el sitio necesita y no tiene, y hoy fallaba
 * en silencio. Lo trajo una pregunta de Hernán: *"¿cómo se entera el cliente si
 * le falta crear alguno?"*. No se enteraba. */
.fila--falta { border-left: 3px solid #b23; background: #fff7f7; }
.fila--falta:hover { background: #fff1f1; }
.fila__aviso { font-size: .82rem; color: #b23; }
/* Y la de al lado: un menú que existe y no sale en ningún lado. No es un error
   —no rompe nada— pero es trabajo hecho que nadie ve, así que se dice apagado. */
.fila--sin-uso .fila__titulo a { color: var(--apagado); }
.fila__sin-uso { color: var(--apagado); font-style: italic; }

/* --- navegación: el árbol de un menú (`docs/30`) ----------------------------
 * La forma es la de Amura —una lista con sangría, el badge de tipo, el ítem
 * abierto marcado— y la diferencia está en los botones: acá cada movimiento es
 * un `<form>`, así que ordenar no depende del JavaScript. */
.nav-arbol { list-style: none; margin: 0; padding: 0; }
.nav-item {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .4rem .5rem;
  border: 1px solid var(--linea);
  border-left: 4px solid var(--verde);
  margin-bottom: -1px;
  background: var(--papel);
}
/* La sangría del hijo. Un solo nivel, que es hasta donde llega el menú. */
.nav-item--n1 { margin-left: 1.6rem; border-left-color: var(--linea); }
.nav-item--abierta { outline: 2px solid var(--verde); outline-offset: -2px; }
.nav-item__nombre { flex: 1; min-width: 0; font-weight: 600; }
.nav-item__tipo {
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--apagado);
  background: var(--fondo);
  border-radius: 3px;
  padding: .1rem .35rem;
  white-space: nowrap;
}
.nav-item__marca { font-size: .72rem; color: var(--apagado); }
/* LO ROTO SE VE ACA Y NO EN EL SITIO. El ítem sigue cargado —sacarlo callado deja
   a alguien buscando por qué su sección no está— pero el lector no llega nunca. */
.nav-item--roto { border-left-color: #b23; background: #fff7f7; }
.nav-item__marca--roto { color: #b23; }
.nav-item--oculto .nav-item__nombre { color: var(--apagado); font-weight: 500; }
.nav-item__acciones { display: flex; align-items: center; gap: .1rem; }
/* Un formulario que es UN botón: no puede meter su propia caja en la fila. */
.acc-form { display: inline; margin: 0; }
/* El bloque de un destino. `display: contents` para que el campo de adentro se
   acomode como cualquier otro del formulario; `[hidden]` tiene que ganarle a eso,
   porque `contents` en un elemento oculto igual dibuja a los hijos. */
.nav-destino { display: contents; }
.nav-destino[hidden] { display: none; }

/* --- mover un ítem: el agarre, el fantasma y la marca de destino -------------
 *
 * EL AGARRE ES CHICO Y ESTÁ AL PRINCIPIO. Antes arrastraba la fila entera, que
 * parecía más generoso y era peor: adentro hay un enlace, y arrastrar un enlace
 * es una acción del navegador. Un agarre explícito dice dónde se agarra.
 *
 * Sin guion no se ve (`html:not(.con-guion)`): sin JavaScript no arrastra nada, y un agarre
 * es una promesa falsa. Para ese caso están los botones de subir y bajar, que
 * son los que se esconden cuando el guion SÍ está. */
.nav-item__agarre {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.5rem; height: 1.9rem;
  color: #b9c6c2;
  cursor: grab;
  touch-action: none;   /* el dedo mueve el ítem, no la página */
}
.nav-item__agarre .ico { width: 1.05rem; height: 1.05rem; }
.nav-item:hover .nav-item__agarre { color: var(--apagado); }
.nav-item__agarre:focus-visible { outline: 2px solid var(--verde); outline-offset: 1px; }
html:not(.con-guion) .nav-item__agarre { display: none; }
/* Y al revés: con guion sobran los pasos de a uno, porque el agarre mueve con el
   mouse Y con el teclado. Ver `ui/navegacion.ts`. */
.con-guion .nav-item__pasos { display: none; }

/* La fila que se está llevando se apaga —queda como hueco de donde salió— y la
   línea gruesa dice dónde va a caer: arriba, abajo, o adentro (hacerse hijo). */
.nav-item--llevando { opacity: .35; }
.nav-item--sobre { box-shadow: inset 0 3px 0 var(--verde); }
.nav-item--sobre-abajo { box-shadow: inset 0 -3px 0 var(--verde); }
.nav-item--adentro { background: #e8f0ee; box-shadow: inset 3px 0 0 var(--verde); }
/* Levantado con el teclado: la fila queda marcada mientras se elige el hueco,
   porque sin puntero no hay nada más que diga cuál se está moviendo. */
.nav-item--levantado { outline: 2px dashed var(--verde); outline-offset: -2px; }

/**
 * EL FANTASMA, que lo dibujamos nosotros.
 *
 * El arrastre nativo mostraba una captura pálida del navegador, descolocada
 * respecto de donde agarraste. Éste es la fila de verdad, clonada, y sigue al
 * puntero desde el punto exacto donde la tomaste.
 *
 * `pointer-events: none` NO es cosmético: el destino se calcula con
 * `elementFromPoint`, y sin esto el fantasma está siempre debajo del puntero y
 * se tapa a sí mismo — la marca no aparecería nunca.
 */
.nav-item--fantasma {
  position: fixed; top: 0; left: 0; z-index: 60;
  pointer-events: none;
  opacity: .95;
  box-shadow: 0 6px 20px rgba(4, 33, 28, .22);
  border-radius: 3px;
  transform-origin: 0 0;
}
.nav-item--fantasma .nav-item__acciones { display: none; }
/* Mientras se arrastra, el cursor es de agarre en toda la página: el puntero se
   va del árbol y volver a la flecha del sistema hace pensar que se soltó. */
body.arrastrando, body.arrastrando * { cursor: grabbing !important; }
/* Y no se selecciona texto por el camino. */
body.arrastrando { user-select: none; }

/* --- EL EDITOR DE PORTADA -------------------------------------------------
   El lienzo ocupa TODO EL ANCHO y lo que se edita abre en un modal encima.

   La primera version puso las opciones en un panel a la derecha y Hernan lo
   midio: "el contenido al estar a la derecha se pierde muchisimo tiempo, se hace
   un contenido muy alto". Es cierto y es geometrico — el panel tiene 340px y el
   formulario de un modulo son dos columnas de campos, asi que todo cae en una
   tira vertical que hay que recorrer. El modal tiene el ancho de la pantalla.

   El resto del cromo vive DENTRO del marco (`ui/lienzo.ts`), porque tiene que
   convivir con la hoja del sitio y no con esta. */

.ed { display: flex; flex-direction: column; gap: .6rem; }

.ed-barra {
  display: flex; align-items: center; gap: .6rem;
  padding: .5rem .7rem; border: 1px solid var(--linea); border-radius: 8px;
  background: var(--fondo);
}
.ed-barra form { margin: 0; }
/* QUE PAGINA SE ESTA ARMANDO. Solo aparece en una página: en la home seria
   repetir lo que ya dice el lateral, que es la regla de la casa. */
.ed-cual {
  font-weight: 600; color: var(--texto); text-decoration: none;
  padding-right: .6rem; border-right: 1px solid var(--linea);
}
.ed-cual:hover { text-decoration: underline; }
.ed-estado { margin-right: auto; font-size: .85rem; color: var(--apagado); }
.ed-estado.mal { color: #a3231f; font-weight: 600; }
/* Descartar solo tiene sentido si hay algo que descartar. */
.ed-solo-borrador { display: none; }
.ed-hay-borrador .ed-solo-borrador { display: block; }

/* EL LIENZO HACE SU PROPIO SCROLL. Una portada son veinte contenedores: si el
   scroll fuera el de la pagina, la barra de Publicar se iria para arriba y habria
   que volver a buscarla. */
#ed-marco {
  width: 100%; height: calc(100vh - 190px); min-height: 460px;
  border: 1px solid var(--linea); border-radius: 8px; background: #fff;
}

/* --- el modal ------------------------------------------------------------- */
#ed-fondo {
  position: fixed; inset: 0; z-index: 60; background: rgba(15, 23, 42, .45);
}
#ed-modal[hidden], #ed-fondo[hidden] { display: none; }
/* Con el modal abierto la pagina de atras no se mueve: sin esto, la rueda del
   mouse fuera del modal hace scrollear el gestor y al cerrar uno ya no esta
   donde estaba. */
body.ed-con-modal { overflow: hidden; }

/* --- EL CAJON: el modal deja de flotar y le hace lugar al lienzo -------------

   LO PIDIO HERNAN: *"cuando estas editando un modulo abajo del modal ya se esta
   reflejando el cambio, es genial, pero el detalle es que el modulo te tapa lo
   que hace"*.

   POR QUE UN CAJON Y NO CORRER EL MODAL. Habia tres caminos: correr la portada
   para que el modulo caiga en la franja libre, correr el modal a la mitad que el
   modulo no ocupa, o que dejen de pisarse. Los dos primeros son MEDIDAS, y una
   medida se rompe con un modulo alto --una apertura, una grilla de ocho-- que no
   entra en ninguna franja. Ahi vuelve el problema sin que se entienda por que a
   veces si y a veces no.

   Con el cajon **no se tapan porque no se superponen**: el marco se achica
   exactamente lo que mide el panel. No hay geometria que lo rompa.

   LO QUE HACE VIABLE ESTO SON LAS SOLAPAS. Sin Contenido/Diseño/Foto el panel
   seria una columna de dos metros y no entraria en media pantalla; la decision de
   *"no deberiamos mostrar nada mas en esta pantalla, quizas lo mejor es solapas"*
   es la que paga esto.

   EL ALTO LO MIDE EL GUION (`--cajon`) y no lo fija esta hoja: el panel de un
   separador y el de un modulo de noticias con tres solapas no miden lo mismo, y
   reservar el maximo para los dos dejaria un hueco gris debajo del panel chico. */
#ed-modal {
  position: fixed; z-index: 61;
  inset: auto 0 0 0;
  width: 100%;
  /* EL CAJON NUNCA SE COME EL LIENZO ENTERO. Con `55vh` a secas, en una pantalla
     de 700px el panel se lleva 385, el cromo de arriba 190, y al lienzo le
     quedaban 125 --menos que su minimo, asi que crecia por abajo y volvia a
     quedar tapado, que es justo lo que esto viene a sacar. El segundo termino
     reserva 170px de lienzo pase lo que pase. */
  max-height: min(46vh, calc(100vh - 300px));
  display: flex; flex-direction: column;
  background: var(--papel);
  border-top: 1px solid var(--linea);
  border-radius: 12px 12px 0 0;
  box-shadow: 0 -10px 32px rgba(15, 23, 42, .18);
}
/* EL CONTENIDO NO SE ESTIRA A LO ANCHO DE LA PANTALLA. El cajon va de borde a
   borde --es lo que lo hace leer como un cajon y no como un modal ancho-- pero un
   formulario de 2000px de ancho no lo lee nadie. */
.ed-modal-cab, .ed-modal-cuerpo, .ed-modal-pie {
  width: 100%; max-width: 1100px; margin-inline: auto; box-sizing: border-box;
}

/* EL MARCO SE ACHICA LO QUE MIDE EL CAJON. `min-height` se baja mientras tanto:
   el de 460px es para que el lienzo no quede ridiculo con la pantalla entera,
   pero con el cajon abierto ganaria y volveria a taparlo, que es el bug que esto
   viene a sacar.

   Y LA PAGINA DEJA DE PEDIR AIRE MIENTRAS TANTO. Lo midio Hernan usandolo: *"es
   verdad que entre el cajon y la cabecera queda poco para mirar"*. Tenia razon y
   el aire estaba en un lugar que no se ve: `.panel` reserva 2rem arriba y **4rem
   abajo**, o sea 96px --y los 64 de abajo los tapa el cajon, que esta pegado al
   pie. Son 96px de margen alrededor de un editor que ocupa la pantalla.

   LA CUENTA, para que el que la toque pueda seguirla: el marco descuenta 190px de
   cromo (la barra de publicar, el aire de la pagina y los margenes). Bajando el
   aire de 96px a 8px quedan 102. No es un numero nuevo elegido a ojo: es el de
   siempre menos lo que se saco. */
body.ed-con-modal .panel { padding-top: .5rem; padding-bottom: 0; }
body.ed-con-modal #ed-marco {
  height: calc(100vh - 102px - var(--cajon, 45vh));
  min-height: 170px;
}

/* SIN VELADURA: el punto entero es VER el lienzo mientras se lo toca. La capa
   sigue existiendo --es la que cierra al hacer clic afuera-- pero transparente. */
#ed-fondo { background: none; }


.ed-modal-cab {
  display: flex; align-items: flex-start; gap: .6rem;
  padding: .9rem 1rem .5rem; border-bottom: 1px solid var(--linea);
}
.ed-modal-cab h2 { margin: 0; font-size: 1.05rem; flex: 1; }
.ed-modal-cuerpo { padding: .9rem 1rem; overflow-y: auto; }
.ed-modal-pie {
  display: flex; align-items: center; gap: .8rem;
  padding: .7rem 1rem; border-top: 1px solid var(--linea);
}
.ed-guardado { margin-left: auto; font-size: .8rem; color: var(--apagado); }

/* --- los campos del modal -------------------------------------------------- */
/* EN FILAS Y NO EN UNA TIRA: es la mitad de por que el modal es mejor que el
   panel. Tres selects que en 340px eran tres renglones, aca son uno. */
.ed-fila {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 0 .9rem;
}
.ed-campo { display: block; margin: .55rem 0; font-size: .8rem; }
.ed-campo > span { display: block; margin-bottom: .2rem; color: var(--apagado); }
.ed-campo small { display: block; margin-top: .2rem; color: var(--apagado); font-size: .72rem; }
.ed-campo input, .ed-campo select { width: 100%; }
.ed-campo input[type="color"] { height: 2.6rem; padding: .2rem; cursor: pointer; }

/* --- La lista de fotos de un modulo (el editor de «Multimedia») ------------
   Una fila por foto: miniatura, sus dos textos, la foto de telefono y el orden.
   El orden va a la DERECHA y no a la izquierda porque la columna que se lee
   primero tiene que ser la foto, que es como uno reconoce cual es cual. */
.ed-fotos { margin: .5rem 0 .8rem; }
.ed-fotos__lista { list-style: none; margin: 0; padding: 0; display: grid; gap: .45rem; }
.ed-foto {
  display: grid;
  grid-template-columns: 5.5rem 1fr auto auto;
  align-items: center;
  gap: .6rem;
  padding: .4rem;
  border: 1px solid var(--linea);
  border-radius: 3px;
  background: var(--papel);
}
.ed-foto__vista {
  display: block;
  width: 5.5rem;
  height: 3.4rem;
  object-fit: cover;
  border-radius: 2px;
  background: var(--fondo);
}
.ed-foto__vista--chica { width: 3rem; height: 2rem; }
.ed-foto__campos { display: grid; gap: .3rem; min-width: 0; }
.ed-foto__campos input { width: 100%; font-size: .84rem; padding: .28rem .4rem; }
.ed-foto__movil {
  display: flex;
  align-items: center;
  gap: .3rem;
  font-size: .75rem;
  color: var(--apagado);
}
.ed-foto__sin { white-space: nowrap; }
.ed-foto__mover { display: flex; gap: .1rem; }
.ed-foto__mover button { padding: .2rem .4rem; font-size: .95rem; line-height: 1; }

.ed-fotos__vacio {
  margin: 0 0 .5rem;
  padding: .6rem;
  border: 1px dashed var(--linea);
  border-radius: 3px;
  font-size: .84rem;
  color: var(--apagado);
  text-align: center;
}

/* En el modal angosto la fila se apila: cuatro columnas en 30rem dejan los dos
   campos de texto en dos centimetros y no se puede escribir nada. */
@media (max-width: 720px) {
  .ed-foto { grid-template-columns: 5.5rem 1fr; }
  .ed-foto__movil, .ed-foto__mover { grid-column: 2; justify-self: start; }
}


/* `1.15rem` arriba y no `.7rem`: con dos grupos de opciones dibujadas seguidos
   —donde va la foto, y que forma tiene— el segundo quedaba pegado al primero y
   los dos se leian como una sola lista larga. Lo marco Hernan: *"«Forma de la
   foto» esta un poco pegado al de arriba"*. */
.ed-grupo { border: 0; margin: 1.15rem 0 0; padding: 0; }
.ed-grupo:first-child { margin-top: .4rem; }
.ed-grupo legend { padding: 0; font-size: .8rem; color: var(--apagado); }
/* La primera pregunta pesa mas que las otras: de ella depende todo lo de abajo.
   Los dos radios van en fila; el tamano y la alineacion los pone `.chk`. */
.ed-tipo { margin: 0 0 .8rem; padding-bottom: .6rem; border-bottom: 1px solid var(--linea); }
.ed-tipo > div { display: flex; gap: 1.4rem; }
.ed-tipo .chk { font-size: .95rem; font-weight: 600; margin: 0; }

.ed-como { margin: 0 0 .8rem; font-size: .82rem; color: var(--apagado); }
.ed-vacio { font-size: .85rem; color: var(--apagado); }

/* --- las tarjetas: grillas y modulos --------------------------------------- */
.ed-grillas, .ed-catalogo {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: .5rem;
}
/* display:block y no el flex de .btn: la tarjeta tiene tres cosas apiladas
   —miniatura, nombre y descripcion— y el flex del boton las pone en fila. */
.btn.ed-tarjeta {
  display: block; height: auto; text-align: left;
  padding: .55rem .6rem; white-space: normal; line-height: 1.35;
}
.ed-tarjeta strong { display: block; font-size: .85rem; }
.ed-tarjeta small { display: block; color: var(--apagado); font-size: .74rem; font-weight: 400; }
.btn.ed-puesta { border-color: var(--verde); }

/* EL CATALOGO DE MODULOS. Lo midio Hernan: *"el modal de modulos es demasiado
   pobre, todos altos distintos"*. Eran dos cosas: las tarjetas median lo que
   midiera su descripcion, y no habia NADA para mirar — solo dos lineas de texto
   por caja, siete veces.

   ALTURAS IGUALES CON `1fr` Y NO CON UNA ALTURA FIJA: una altura en pixeles se
   rompe el dia que una descripcion tenga una palabra mas, y en un idioma que no
   sea el nuestro se rompe seguro. Con la fila elastica las siete miden lo que
   mida la mas alta, sea cual sea. */
.ed-catalogo { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); grid-auto-rows: 1fr; }
.ed-catalogo li { display: flex; }
.btn.ed-tarjeta { width: 100%; padding: .7rem; }
.ed-tarjeta strong { margin-bottom: .1rem; }
.ed-tarjeta small { line-height: 1.3; }

/* EL CROQUIS, dibujado de la declaracion del modulo (`catalogo.ts`, `croquis`) y
   no de una imagen — la misma decision que las miniaturas de las grillas. No
   describe al modulo: lo hace reconocible de un vistazo entre siete cajas. */
.ed-croquis {
  display: flex; gap: 3px; width: 100%; height: 30px; margin-bottom: .5rem;
  padding: 4px; border-radius: 4px; background: rgba(127, 127, 127, .1);
}
.ed-croquis i { flex: 1 1 auto; border-radius: 2px; background: var(--apagado); opacity: .4; }
.btn.ed-tarjeta:hover .ed-croquis i { opacity: .6; }

/* Una grilla de tarjetas: barras parejas, de pie. */
.ed-croquis--grilla i { align-self: stretch; }
/* La apertura: una grande y una chica al lado. */
.ed-croquis--apertura i:first-child { flex: 2 1 auto; }
/* Una lista: barras acostadas, una debajo de la otra. */
.ed-croquis--lista, .ed-croquis--numerada, .ed-croquis--texto {
  flex-direction: column; gap: 4px; justify-content: center;
}
.ed-croquis--lista i, .ed-croquis--numerada i { height: 3px; flex: 0 0 auto; }
/* La numerada arranca corta y va creciendo, como un ranking. */
.ed-croquis--numerada i:first-child { width: 45%; }
.ed-croquis--numerada i:nth-child(2) { width: 70%; }
/* El titulo: una barra gruesa y una fina abajo, que es su bajada. */
.ed-croquis--texto i:first-child { height: 6px; width: 60%; flex: 0 0 auto; opacity: .55; }
.ed-croquis--texto i:last-child { height: 3px; width: 35%; flex: 0 0 auto; }
/* La tira que se corre: la ultima se va cortada por el borde. */
.ed-croquis--tira { overflow: hidden; }
.ed-croquis--tira i:last-child { flex: 0 0 12px; }
/* El separador: una linea sola, al medio. */
.ed-croquis--linea { align-items: center; }
.ed-croquis--linea i { height: 2px; flex: 1 1 auto; }
/* El hueco: el contorno de una caja y nada adentro. */
.ed-croquis--hueco i {
  background: none; border: 1px dashed var(--apagado); opacity: .5; border-radius: 3px;
}


/* LA MINIATURA DE UNA GRILLA SE DIBUJA DE SUS COLUMNAS, no es una imagen.
   Amura tiene un PNG por wrap, asi que una grilla nueva es codigo Y un archivo —
   y si cambian las proporciones, el PNG queda mintiendo. Aca sale del mismo dato
   que usa el render. */
/* LAS MISMAS CUATRO COLUMNAS QUE EL SITIO. Era un flex con anchos en porcentaje,
   que alcanzaba mientras toda grilla fuera un renglon; con una zona que baja dos
   filas, el croquis tiene que ser una grilla o miente sobre la forma. */
.ed-mini {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 1fr;
  gap: 3px; width: 100%; height: 34px; margin-bottom: .45rem;
  padding: 3px; border-radius: 4px; background: rgba(127, 127, 127, .12);
}
.ed-mini i {
  grid-column: span var(--c);
  grid-row: span var(--f);
  border-radius: 2px;
  background: var(--apagado); opacity: .45;
}

/* --- las notas de un modulo manual ----------------------------------------- */
.ed-manual { margin-top: .6rem; }
/* LA LISTA DE CANDIDATAS SCROLLEA SOLA. Sin esto son veinte notas que estiran el
   modal entero, y las que ya estan elegidas —lo que uno vino a mirar— quedan
   arriba de todo, fuera de la vista. */
[data-lista-notas] { max-height: 210px; overflow-y: auto; border-top: 1px solid var(--linea); }
.ed-notas { list-style: none; margin: .3rem 0; padding: 0; }
.ed-nota {
  display: grid; grid-template-columns: 1fr auto; align-items: center;
  gap: 0 .4rem; padding: .3rem .4rem; border-radius: 5px; font-size: .82rem;
}
.ed-nota:nth-child(odd) { background: rgba(127, 127, 127, .07); }
.ed-nota-t { grid-column: 1; }
.ed-nota-s { grid-column: 1; font-size: .72rem; color: var(--apagado); }
.ed-nota button { grid-column: 2; grid-row: 1 / 3; }
/* Las dos son botones de texto del sistema; aca solo se los achica al tamano
   de una fila de lista. */
.btn.ed-x, .btn.ed-mas-chico, .btn.ed-cerrar {
  height: auto; min-width: 0; font-size: 1.05rem; line-height: 1;
  padding: .1rem .35rem; color: var(--apagado);
}
.btn.ed-x:hover { color: #a3231f; }
.btn.ed-mas-chico:hover { color: var(--verde); }

/* --- las solapas del modal de un modulo ------------------------------------
   "Creo que no deberiamos mostrar nada mas en esta pantalla; quizas lo mejor es
   solapas: esta primera es contenido, la siguiente puede ser diseno". La
   division es la buena — de donde salen las notas, y como se ven— porque son dos
   preguntas de dos momentos distintos: la primera se toca todos los dias, la
   segunda se decide una vez. */
.ed-solapas {
  display: flex; gap: .2rem; margin: 0 0 .9rem;
  border-bottom: 1px solid var(--linea);
}
.btn.ed-solapa {
  height: auto; padding: .45rem .8rem; margin-bottom: -1px;
  border-radius: 3px 3px 0 0; font-weight: 600; color: var(--apagado);
  border-bottom: 2px solid transparent;
}
.btn.ed-solapa.ed-puesta { color: var(--tinta); border-bottom-color: var(--verde); }

/* --- la disposicion de la foto, dibujada ------------------------------------
   "Mira si podes hacer algo mas pro y no simples radios, que tambien estan
   estirados". Los radios estaban estirados porque el kit le da `width: 100%` a
   todo control dentro de un campo; aca directamente no se ven — la tarjeta
   entera es el control, y el dibujo dice lo que el texto tendria que explicar. */
.ed-disps {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: .4rem; margin-top: .35rem;
}
.ed-disp {
  display: block; cursor: pointer; padding: .4rem;
  border: 1px solid var(--linea); border-radius: 6px; background: var(--papel);
  text-align: center; font-size: .72rem; color: var(--apagado);
}
.ed-disp:hover { border-color: var(--verde); }
/* El radio sigue existiendo para el teclado y para el formulario; lo que no
   hace es ocupar lugar ni estirarse. */
.ed-disp input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.ed-disp:has(input:checked) {
  border-color: var(--verde); box-shadow: inset 0 0 0 1px var(--verde);
  color: var(--tinta); font-weight: 600;
}
.ed-disp:has(input:focus-visible) { box-shadow: 0 0 0 3px rgba(0, 167, 138, .18); }
.ed-disp-t { display: block; margin-top: .3rem; }

/* El dibujo: un bloque para la foto y unas rayas para el texto, acomodados como
   van a quedar. Sale del nombre de la disposicion. */
.dm {
  display: flex; gap: 3px; height: 44px; padding: 3px;
  border-radius: 3px; background: rgba(127, 127, 127, .1);
}
.dm--col { flex-direction: column; }
.dm--col-inv { flex-direction: column-reverse; }
.dm--fila-inv { flex-direction: row-reverse; }
/* La foto es un BLOQUE LLENO y el texto son rayas finas: es lo que hace que el
   dibujo se entienda de un vistazo. Con los dos del mismo gris no se distinguian
   —el bloque parecia una raya mas gorda— y el dibujo dejaba de decir nada. */
.dm-foto { flex: 1 1 42%; border-radius: 2px; background: var(--apagado); opacity: .85; }
.dm-txt {
  flex: 1 1 60%; display: flex; flex-direction: column; justify-content: center; gap: 3px;
}
.dm-txt b { display: block; height: 3px; border-radius: 2px; background: var(--apagado); opacity: .3; }
.dm-txt b:last-child { width: 60%; }
.ed-disp:has(input:checked) .dm-foto { background: var(--verde); opacity: 1; }

/* TEXTO SOBRE LA FOTO: el unico dibujo que NO es un flex de dos cajas, porque la
   disposicion tampoco lo es — el texto va ENCIMA. Sin esto caia en el dibujo de
   "sin foto" y salia con foto: lo vio Hernan y tenia razon, dos opciones
   distintas dibujadas igual son un selector que no ayuda a elegir.

   Las rayas van abajo y sobre un velo, que es exactamente lo que hace el
   degradado de la tarjeta de verdad. */
.dm--sobre { display: block; position: relative; }
.dm--sobre .dm-foto { position: absolute; inset: 3px; border-radius: 2px; }
.dm--sobre .dm-txt {
  position: absolute; inset: auto 5px 5px; display: flex; gap: 3px;
  padding: 3px 3px 2px; border-radius: 0 0 2px 2px;
  background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, .45));
}
.dm--sobre .dm-txt b { background: #fff; opacity: .85; }

/* SIN FOTO: las rayas ocupan todo. Tenia la clase y no tenia regla, asi que se
   apoyaba en que el `<i>` no se emite — o sea que el dibujo salia bien por lo que
   NO estaba, y cualquiera que agregara el `<i>` de vuelta no iba a entender por
   que. Con la regla, la clase dice lo que hace. */
.dm--solo .dm-txt { flex: 1 1 100%; }

/* --- la forma de la foto ----------------------------------------------------

   UN RECTANGULO DE ESA PROPORCION, y nada mas. Lo pidio Hernan mirando la
   primera version, que era un desplegable: *"pense que ibas a poner dibujitos
   como con la foto, porque visualmente se entiende mejor"*. Una proporcion ES una
   forma, asi que el dibujo no la ilustra: la dice entera.

   LA RELACION VIENE EN `--rel` (`16/9`), del mismo dato que el render le manda a
   Cloudflare, asi que una proporcion nueva se dibuja sola. Es el patron de
   `--parte` en la miniatura de una grilla.

   La CAJA mide siempre igual y el rectangulo se acomoda adentro: sin eso la fila
   de opciones sube y baja segun la forma, que es exactamente lo que hace dificil
   compararlas. */
.pr {
  display: grid; place-items: center;
  height: 44px; padding: 3px; border-radius: 3px;
  background: rgba(127, 127, 127, .1);
}
.pr i {
  /* La ALTURA manda y el ancho sale de la relacion: asi la panoramica se estira
     de verdad y la vertical se angosta, que es lo que las distingue de un
     vistazo. Con el ancho fijo todas salian casi iguales. */
  display: block; height: 100%; width: auto; max-width: 100%;
  aspect-ratio: var(--rel);
  border-radius: 2px; background: var(--apagado); opacity: .85;
}
.ed-disp:has(input:checked) .pr i { background: var(--verde); opacity: 1; }

/* «Como viene»: sin forma propia, porque justamente la decide el modulo. Un
   contorno punteado dice eso mejor que cualquier rectangulo lleno — que ademas
   seria uno de los otros y volveriamos al dibujo repetido. */
.pr--auto i {
  aspect-ratio: 3 / 2;
  background: transparent; border: 1px dashed var(--apagado); opacity: .6;
}
.ed-disp:has(input:checked) .pr--auto i { background: transparent; border-color: var(--verde); }

/* El numero al lado del nombre. Sale de la CLAVE, no de un texto aparte. */
.ed-forma .ed-disp-t small {
  display: block; font-weight: 400; font-variant-numeric: tabular-nums;
  color: var(--apagado);
}
.ed-formas { margin-top: .2rem; }

/* --- que se muestra: fichas que se prenden ---------------------------------- */
.ed-fichas { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .35rem; }
.ed-ficha { position: relative; cursor: pointer; }
.ed-ficha input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.ed-ficha span {
  display: inline-block; padding: .32rem .7rem; border-radius: 999px;
  border: 1px solid var(--linea); background: var(--papel);
  font-size: .8rem; color: var(--apagado);
}
.ed-ficha:hover span { border-color: var(--verde); }
.ed-ficha input:checked + span {
  border-color: var(--verde); background: #e8f5f2; color: var(--verde-hondo); font-weight: 600;
}
.ed-ficha input:focus-visible + span { box-shadow: 0 0 0 3px rgba(0, 167, 138, .18); }


/* --- los filtros de varios valores, con su negacion -------------------------
   "Los filtradores como seccion, agrupador podes seleccionar 1 o mas, no solo
   uno". Usan `elegirVarios` del kit, que ya trae las fichas y el buscador. */
.ed-fila--filtros { align-items: start; }
.ed-filtro .campo--elegir { margin-bottom: .3rem; }
/* La lista de "Agregar" no puede crecer sin fin adentro de un modal: con veinte
   secciones el modal se estiraba hasta tapar el lienzo. */
.ed-filtro .sumar__lista { max-height: 170px; overflow-y: auto; }
/* Sin nada elegido, "todas menos ninguna" es "todas": la casilla sigue ahi para
   que se vea que existe, pero apagada. */
.ed-negar { font-size: .78rem; color: var(--apagado); margin: .2rem 0 0; }
.ed-negar--muda { opacity: .45; }

/* --- la muestra del fondo del contenedor -----------------------------------
   "El modal de fondo, lo mismo: no se entiende que es ese modal". Tenia razon —
   era un cuadradito de color y nada mas. Lo que se decide ahi no es un color: es
   como va a quedar el texto encima, y eso hay que verlo. */
.ed-muestra {
  padding: 1rem 1.1rem; border-radius: 6px; margin-bottom: .9rem;
  background: var(--fondo-muestra);
}
.ed-muestra-s {
  display: block; font-size: .7rem; font-weight: 700; letter-spacing: .08em;
  margin-bottom: .3rem; color: var(--verde-claro);
}
.ed-muestra-t { display: block; font-family: var(--display); font-size: 1.35rem; line-height: 1.2; }
.ed-muestra-b { display: block; margin-top: .35rem; font-size: .85rem; }
/* Las mismas dos clases que usa el sitio (`visor/base.css`), con los mismos
   colores: la muestra no aproxima, aplica la regla de verdad. */
.ed-muestra.sobre-oscuro { color: #fff; }
.ed-muestra.sobre-oscuro .ed-muestra-b { color: rgba(255, 255, 255, .72); }
.ed-muestra.sobre-claro { color: #12161c; }
.ed-muestra.sobre-claro .ed-muestra-b { color: rgba(0, 0, 0, .6); }
/* El selector de color no ocupa toda la fila: es un color, no un texto largo. */
.ed-color .campo > input[type="color"] { width: 8rem; height: 2.6rem; padding: .2rem; cursor: pointer; }

/* --- hasta donde llega el fondo, dibujado ----------------------------------
   "A todo el ancho" y "al ancho del sitio" son dos frases parecidas y dos cosas
   muy distintas: el dibujo lo resuelve sin leer. */
.ed-anchos {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: .4rem; margin-top: .35rem;
}
.am {
  display: block; height: 34px; padding: 4px 0; border-radius: 3px;
  background: repeating-linear-gradient(45deg, rgba(127,127,127,.08) 0 4px, transparent 4px 8px);
}
.am i { display: block; height: 100%; background: var(--apagado); opacity: .55; }
.am--pantalla i { margin: 0; }
.am--sitio i { margin: 0 18%; }
.am--caja i { margin: 0 18%; border-radius: 5px; }
.ed-disp:has(input:checked) .am i { background: var(--verde); opacity: 1; }

/* ===========================================================================
 * LA CONFIGURACION DEL MEDIO (`ui/configuracion.ts`)
 *
 * Doce campos de red uno abajo del otro son doce cajas de texto identicas: el
 * ojo no encuentra Instagram sin leer las doce etiquetas. El icono adelante
 * —el MISMO SVG que dibuja el sitio— resuelve eso sin agregar una palabra.
 *
 * Va alineado a la caja de texto y no a la etiqueta: la etiqueta es chica y
 * queda arriba, asi que centrar contra el bloque entero dejaria el logo
 * flotando entre dos renglones. */
.redes-campos { display: grid; gap: 0; }
.red-campo { display: grid; grid-template-columns: 1.5rem 1fr; gap: .6rem; align-items: end; }
.red-campo .campo { flex: 1; min-width: 0; }
.red-campo__icono {
  display: flex;
  justify-content: center;
  /* La altura del control mas el margen inferior del campo: asi el icono cae a
     la altura del texto y no de la etiqueta. */
  padding-bottom: 1.85rem;
  color: var(--apagado);
}
.red-campo__icono svg { width: 1.05rem; height: 1.05rem; }
/* Cargada = a color. Es la unica lectura que hace falta de un vistazo: cuales
   de las doce estan puestas. */
.red-campo:has(input:not(:placeholder-shown)) .red-campo__icono { color: var(--texto); }

/* --- publicidad (`docs/34`) --------------------------------------------------

   EL LISTADO NO ES UNA LISTA: ES EL MAPA DEL INVENTARIO. Se agrupa por LUGAR, y
   un lugar sin avisos se dibuja igual —«libre»— porque esa es la fila que busca
   el que vende. Adentro de cada grupo se reusa `.listado`/`.fila` como el resto
   del gestor.

   ⚠️ ACA HABIA UN BLOQUE `.pos__*` PARA LA PANTALLA DE POSICIONES Y SE FUE con la
   entidad (2026-08-23). Sobrevive `.pos__n`, que es el numerito redondo del
   lugar: sigue significando lo mismo. */

/* DOS COLUMNAS Y UNA TERCERA OPCIONAL: estado + cuerpo, y el porcentaje del
   sorteo a la derecha cuando hay mas de uno compartiendo el lugar. */
.fila--aviso { grid-template-columns: 7.5rem minmax(0, 1fr) auto; }

.pub__alta {
  display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
  margin: 0 0 1.2rem;
}
.pub__alta input[type="text"] { flex: 1 1 12rem; }
.pub__alta select[name="lugar"] { flex: 1 1 18rem; }
/* 5rem alcanzaban para un número de dos cifras pero no para su etiqueta: en la
   columna del detalle el `placeholder` del campo dice qué cuenta —«Posición»,
   «Párrafo», «Después de la tarjeta»— y salía cortado en «Posici…». El número que
   se escribe es corto; lo que hay que poder leer es de qué es. */
.pub__alta input[type="number"] { width: 9rem; }
/* UN ANUNCIANTE TIENE DOS COSAS, no cuatro: el nombre y lo que se puede hacer con
   él. `.fila` es la grilla del listado de NOTAS —estado, cuerpo, meta, acciones—
   y sin decirlo el nombre caía en la columna de 6,5rem del estado, partido en dos
   renglones, y las acciones en la del medio: media pantalla vacía a la derecha
   (*"tenés bastante más ancho"*). Acá son dos columnas: el nombre se lleva el
   ancho y las acciones se van al borde, que es donde se las busca. */
.fila--anunciante { grid-template-columns: minmax(0, 1fr) auto; }

/* La × que saca un aviso de un lugar. Va al final de la fila, que es donde se
   busca lo que saca algo de una lista. */
.colocacion { position: relative; align-items: start; }
.colocacion__sacar { align-self: center; margin-top: 1.1rem; }
/* Vaciada pero todavia sin guardar: se ve que quedo sin lugar y se puede deshacer
   eligiendo otro. Borrar la fila la haria desaparecer sin rastro. */
.colocacion--sacada { opacity: .55; }

.pub__contacto { display: flex; gap: .35rem; align-items: center; }
/* El contacto es un teléfono o un correo, y los dos entran holgados en 18rem.
   En 11rem un correo se leía a la mitad. */
.pub__contacto input { width: 18rem; max-width: 100%; font-size: .85rem; }

/* =========================================================================
   EL MAPA DE PUBLICIDAD: el inventario dibujado como una pagina.

   Lo pidio Hernan: *"todo un listado asi es demasiada informacion… algo que ayuda
   mucho a la gente es mostrar un grafico de cada tipo de anuncio"*. El porque
   largo esta en `ui/publicidad.ts`; lo que importa aca es una sola regla:

   ⚠️ ES UN ESQUEMA, NO UNA MAQUETA DEL SITIO DEL CLIENTE. Nada de esto intenta
   parecerse al layout real —ni anchos, ni tipografia, ni columnas de verdad—
   porque el dia que lo intentara habria que mantenerlo sincronizado con el
   render, y un mapa desincronizado miente sobre donde sale la plata. Dice
   "arriba / en el cuerpo / al costado / abajo" y nada mas.
   ========================================================================= */

.mapa { margin-bottom: 1.6rem; }
.mapa .chips { margin-bottom: 1rem; }

/* Los dos anchos, uno al lado del otro. NO es un filtro «ver solo mobile»: es el
   mismo mapa a otro ancho, y ponerlos juntos es lo que hace ver de un vistazo que
   la columna lateral cae al final del contenido en el telefono. */
.mapa__anchos {
  display: flex;
  align-items: flex-start;
  gap: 1.4rem;
  flex-wrap: wrap;
}

/* ⚠️ MAS CHICOS DE LO QUE ENTRABAN, a pedido: *"la primera columna la podemos
   hacer mas chica porque solo es el mapa"*. Y tenia razon por lo que el croquis ES:
   un ESQUEMA. No gana nada por ser grande —no hay que leer nada adentro salvo el
   nombre del hueco— y cada pixel que se lleva se lo saca a la columna donde de
   verdad se trabaja. Con 28rem el hueco mas largo ("In-article (arriba)") sigue
   entrando en un renglon. */
.croquis { margin: 0; flex: 1 1 18rem; max-width: 28rem; }
.croquis--angosto { flex: 0 0 10rem; max-width: 10rem; }
.croquis figcaption {
  font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .08em;
  color: var(--apagado); margin-bottom: .4rem;
}

/* La hoja: el recuadro que hace de pagina. */
.croquis__hoja {
  display: flex; flex-direction: column; gap: .4rem;
  padding: .5rem;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: 4px;
}

/* La marca del sitio y el pie: dos barras que dan el arriba y el abajo. Sin
   ellas, el leaderboard se lee como el borde de la caja en vez de como algo que
   esta DEBAJO de la cabecera. */
.croquis__marca, .croquis__pie {
  height: .85rem; border-radius: 2px; background: var(--verde-hondo); opacity: .18;
}
.croquis__pie { height: 1.4rem; }

.croquis__cols { display: grid; grid-template-columns: minmax(0, 1fr) 5.5rem; gap: .4rem; }
.croquis__cuerpo, .croquis__lateral { display: flex; flex-direction: column; gap: .4rem; }
.croquis__lateral { align-content: start; }

/* Las rayas que hacen de contenido. Son decorativas y por eso llevan
   `aria-hidden`: lo que un lector de pantalla tiene que recorrer son los huecos,
   que son enlaces con nombre. */
.croquis__texto {
  height: 2.2rem; border-radius: 2px;
  background: repeating-linear-gradient(
    to bottom,
    var(--linea) 0, var(--linea) 2px,
    transparent 2px, transparent 7px);
  opacity: .85;
}
.croquis--angosto .croquis__texto { height: 1.6rem; }

/* --- el hueco -------------------------------------------------------------
   TRES ESTADOS Y NO DOS, porque "tiene avisos" y "esta saliendo algo" no son lo
   mismo: un lugar con dos campañas vencidas se ve lleno en la base y esta vacio
   en la pagina. Ese es justo el hueco que hay que salir a vender.

   Los colores son los de la casa y significan lo mismo que en el listado de
   notas: verde lo que esta publicado, gris lo que no. */
.hueco {
  display: flex; align-items: center; justify-content: center; gap: .4rem;
  min-height: 2.1rem; padding: .25rem .5rem;
  border: 1px dashed var(--linea);
  border-radius: 3px;
  background: var(--fondo);
  color: var(--apagado);
  font-size: .72rem; font-weight: 600;
  text-align: center; text-decoration: none;
  transition: border-color .12s, background .12s, color .12s;
}
.hueco:hover { border-color: var(--verde); color: var(--verde-hondo); }
.hueco:focus-visible { outline: 2px solid var(--verde); outline-offset: 2px; }
.hueco--alto { min-height: 6rem; }

.hueco--lleno {
  border-style: solid; border-color: var(--verde);
  background: #e8f7f3; color: var(--verde-hondo);
}
/* Cargado pero sin salir: pausado, vencido o todavia programado. Ni verde —no
   esta saliendo— ni gris —no esta libre para vender—. */
.hueco--dormido {
  border-style: solid; border-color: #d9a441;
  background: #fdf6e7; color: #8a6413;
}
/* El unico que puede no existir es el modulo de portada: el hueco hay que
   PONERLO en el editor antes de poder llenarlo. Rayado para que no se lea como
   un lugar disponible, que seria la promesa falsa del "cargue la posicion y no
   sale". */
.hueco--falta {
  border-color: #c9a0a0; color: #8d1e1a;
  background: repeating-linear-gradient(
    45deg, #fdf4f3 0, #fdf4f3 5px, #f7e6e4 5px, #f7e6e4 10px);
}
/* El que se esta mirando abajo. */
.hueco--abierto { box-shadow: 0 0 0 2px var(--verde-hondo); }

.hueco__nombre { line-height: 1.15; }
.hueco__n {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.25rem; height: 1.25rem; padding: 0 .3rem;
  border-radius: 1rem;
  background: var(--verde-hondo); color: #fff;
  font-size: .68rem;
}
.hueco--libre .hueco__n, .hueco--dormido .hueco__n { background: var(--apagado); }

/* --- los que van encima de la pagina ---------------------------------------
   AFUERA DEL RECUADRO A PROPOSITO: el anchor y el interstitial no estan en el
   flujo —van sobre lo que el lector vino a leer— y dibujarlos adentro diria que
   ocupan un lugar entre dos parrafos, que es justo lo que no hacen. Es la misma
   distincion que ya hace `RESERVABLES`. */
.mapa__encima { margin-top: 1.1rem; }
.mapa__encima-huecos { display: flex; gap: .5rem; flex-wrap: wrap; margin: .3rem 0 .4rem; }
.mapa__encima-huecos .hueco { flex: 0 1 12rem; }

/* En pantalla angosta los dos croquis se apilan y el del telefono deja de tener
   sentido al lado: se muestra igual, abajo, porque la diferencia que enseña
   —donde cae la columna lateral— no depende del ancho de QUIEN MIRA. */
@media (max-width: 60rem) {
  .mapa__anchos { flex-direction: column; }
  .croquis, .croquis--angosto { max-width: 26rem; flex: 1 1 auto; width: 100%; }
}

/* --- las dos columnas: el mapa y lo que se señaló ---------------------------
   ⚠️ AL LADO Y NO ABAJO. Es un error corregido a los diez minutos de estrenar el
   mapa. Hernan: *"me paso, y eso que tengo pantalla grande, que al hacer click
   aparece abajo el contenido pero no me daba cuenta porque no se ve"*.

   Y su duda —*"si metemos dos columnas no va a entrar en pantallas normales,
   ¿no?"*— tenia una respuesta medida: el mapa usa 720px (el croquis ancho 544 +
   el del telefono 176) y la pantalla le estaba dando 1595. Habia 830px VACIOS a la
   derecha mientras el detalle caia abajo del pliegue. La pregunta no era si
   entraban dos columnas: era por que habia una sola.

   EL MAPA SE QUEDA QUIETO mientras se scrollea el detalle. Es el indice de esta
   pantalla, y un indice que se va de vista obliga a scrollear para arriba cada vez
   que se quiere mirar otro hueco.

   ABAJO DEL CORTE SE APILAN, y ahi el detalle vuelve a quedar abajo — por eso los
   huecos del mapa apuntan a `#detalle` y el navegador salta solo. Sin JavaScript,
   que es la regla de todo el mapa. */
.pub__detalle { min-width: 0; }

/* EL CORTE SUBIO A 80rem AL BAJAR EL ANCHO DEL MAPA, y no es contradictorio: con
   la columna en 47rem, a 78rem de pantalla al detalle le quedaban 205px — dos
   columnas de nombre y ninguna util. Con 40rem le quedan 349px, que ya es una
   columna de trabajo. Debajo del corte se apilan, que es honesto. */
@media (min-width: 80rem) {
  .pub__tablero {
    display: grid;
    grid-template-columns: minmax(0, 40rem) minmax(0, 1fr);
    gap: 1.6rem;
    align-items: start;
  }
  .pub__mapa { position: sticky; top: 1rem; }
}

/* «Elegi un espacio del mapa»: la columna de la derecha antes de señalar nada.
   Vacia pareceria rota; con esto dice que falta hacer, que es una sola cosa y
   esta al lado. */
.pub__elegir {
  border: 1px dashed var(--linea);
  border-radius: 4px;
  padding: 1.4rem 1.5rem;
  background: var(--papel);
}
.pub__elegir-titulo {
  margin: 0 0 .5rem;
  font-family: var(--display);
  font-size: 1.05rem; font-weight: 700;
  color: var(--verde-hondo);
}
.pub__elegir .ayuda { margin: 0 0 .5rem; }
.pub__elegir .ayuda:last-child { margin-bottom: 0; }

/* El buscador del listado. Los cuatro selects filtran al cambiarlos; el boton se
   queda para el que escribe y aprieta Enter, y para cuando no hay guion. */
.buscar--pub { flex-wrap: wrap; margin-bottom: .8rem; }
.buscar--pub input[type="search"] { flex: 1 1 14rem; }
.buscar--pub select { flex: 0 1 11rem; }

.pub__cuantos { margin: 0 0 .8rem; font-size: .84rem; color: var(--apagado); }
.pub__cuantos a { color: var(--verde-hondo); }

/* UN LUGAR DEL SITIO. Separado del de al lado por aire y no por una linea: son
   bloques distintos del inventario, no filas de una tabla. */
.pub__lugar { margin-bottom: 1.6rem; }
.pub__volver { margin: 0 0 .5rem; font-size: .84rem; }
.pub__volver a { color: var(--verde-hondo); text-decoration: none; }
.pub__volver a:hover { text-decoration: underline; }
.pub__lugar:last-child { margin-bottom: 0; }
.pub__cab {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  padding-bottom: .4rem; border-bottom: 2px solid var(--linea);
}
/* EL TERMINO DE LA INDUSTRIA MANDA VISUALMENTE —«Leaderboard», «Interstitial»— y
   la traduccion va debajo, chica. Lo pidio Hernan: una agencia manda "un
   leaderboard de 728x90", y el que vende tiene que encontrar esa palabra. */
.pub__nombre {
  margin: 0; font-size: 1rem; font-weight: 700;
  display: flex; align-items: center; gap: .4rem;
}
.pub__donde { margin: .1rem 0 0; font-size: .8rem; color: var(--apagado); }
/* «Libre» NO es un estado de error: es una oportunidad de venta. Verde y no
   amarillo, que es lo que la primera version hacia mal al llamarlo "sin
   posicion". */
.pub__libre {
  font-size: .78rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--verde-hondo);
}
/* Y el que todavia no existe se ve DISTINTO de uno libre: uno se puede vender,
   el otro hay que ponerlo primero. Amarillo, que en el gestor ya significa «falta
   algo» — el mismo de `.pill--1` en el listado de notas. */
.pub__falta {
  font-size: .78rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: #8a6d1f;
}
/* LOS QUE ESTAN PUESTOS EN ESTE LUGAR Y NO SALEN EN ESTA PAGINA.
   Se nombran y no se esconden —este panel es a donde viene el que no ve salir su
   aviso— pero apagados: contarlos como si salieran es la mentira que el mapa
   acaba de dejar de decir (2026-08-27). */
.pub__otras {
  margin-top: 1rem; padding-top: .8rem; border-top: 1px dashed var(--borde);
}
.pub__otras-cab {
  margin: 0 0 .4rem; font-size: .82rem; color: var(--apagado);
}
/* Apagado, no escondido: se lee, se puede abrir y arreglar la casilla. */
.listado--apagado { opacity: .62; }
.listado--apagado:hover, .listado--apagado:focus-within { opacity: 1; }
.pub__vacio {
  margin: .5rem 0 0; font-size: .84rem; color: var(--apagado); max-width: 44rem;
}
/* El numero del lugar —el parrafo, el lugar de la columna— pegado al nombre y no
   perdido en la descripcion: es la mitad de su identidad. */
/* LLEVA LA PALABRA ADENTRO —«Parrafo 2», no «2»— asi que necesita aire a los
   costados: un numero pelado se lee como un indice del aviso y no como el punto
   de la pagina donde sale. */
.pos__n {
  display: inline-grid; place-items: center; min-width: 1.4rem; height: 1.4rem;
  padding-inline: .45rem;
  border-radius: 999px; background: var(--verde-suave, rgba(0, 167, 138, .12));
  font-size: .74rem; font-weight: 700; color: var(--verde-hondo);
}
/* La parte del sorteo, alineada a la derecha y con cifras de ancho fijo para que
   la columna de porcentajes se lea de un vistazo. */
.pub__peso {
  align-self: center;
  font-size: .82rem; font-weight: 700; color: var(--verde-hondo);
  font-variant-numeric: tabular-nums;
}

/* El pie de la ficha del aviso: la misma fila de acciones que usa el resto del
   gestor, sólo que abajo y no en la barra pegajosa. Separada del último campo
   para que no se lea como un control más del formulario. */
.ficha__acciones--pie { margin-top: 1.7rem; }
/* La linea de datos de un aviso va EN UNA LINEA. `.fila__meta` es una columna
   —en el listado de notas apila seccion, autores y fecha— y acá son cinco datos
   cortos separados por puntos: apilados ocupan cinco renglones por aviso. */
.pub__meta { font-size: .82rem; color: var(--apagado); }
.pub__meta time { color: inherit; }
/* El nombre arriba y sus datos abajo. Sin esto los dos quedan en el mismo
   renglon y el nombre —que es lo que se busca al escanear— se pierde entre los
   puntos. */
.fila__cuerpo { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
/* LA PASTILLA DEL NUMERO NO SE ESTIRA. En la columna del aviso el contenedor es
   un flex vertical, o sea que un hijo ocupa el ancho entero: la pastilla salia
   como una barra verde de punta a punta. Se ajusta al texto, que es lo unico que
   la hace leerse como una etiqueta y no como un fondo. */
.fila--aviso .pos__n { align-self: start; }

/* DONDE SE DEJA EL LUGAR HECHO. Va al pie del panel del hueco y no arriba: se
   busca despues de cargar un aviso y ver saltar la pagina, no antes. */
.pub__reserva {
  margin-top: 2rem; padding-top: 1.2rem;
  border-top: 1px solid var(--linea);
}
.pub__reserva .rotulo { margin: 0 0 .5rem; }
.pub__reserva button { margin-top: .8rem; }
/* EL MODO Y LOS DOS NUMEROS EN UNA FILA: se leen juntos —«automatico, 200 y 0»—
   y apilados ocuparian tres renglones para decir una sola cosa. */
.pub__reserva-campos {
  display: flex; align-items: flex-end; gap: .8rem; flex-wrap: wrap;
}
.pub__reserva-campos select { width: auto; min-width: 9rem; }
.pub__reserva-campos input { max-width: 5.5rem; }

/* LO RESERVADO, TODO JUNTO (solapa «Ajustes»). Se mira aca y se edita en el hueco:
   dos formularios para el mismo numero son dos verdades esperando a separarse. */
.pub__resv { width: 100%; border-collapse: collapse; margin-top: 1rem; }
.pub__resv th, .pub__resv td {
  padding: .5rem .6rem .5rem 0; border-bottom: 1px solid var(--linea);
  text-align: left; font-size: .84rem;
}
.pub__resv thead th { font-size: .72rem; text-transform: uppercase; color: var(--apagado); }
.pub__resv tbody th { font-weight: 600; }
.pub__resv tr:last-child th, .pub__resv tr:last-child td { border-bottom: 0; }
/* Un lugar que en esa pagina no existe: ni reservado ni apagado, no esta. */
.pub__resv-no { color: var(--apagado); }
.pub__resv-auto {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--apagado);
}
/* DOS ALTOS POR LUGAR, uno por pantalla: el aviso de escritorio y el del telefono
   son dos piezas distintas, y reservar el alto de una en la otra deja una banda
   en blanco donde no va nada (*"puse 200 en Leaderboard pero en celular no
   podemos dejar ese espacio"*). Van uno al lado del otro y no en dos filas: se
   completan juntos y la comparacion entre los dos numeros es el dato. */
.pub__dosaltos { display: flex; gap: .8rem; flex-wrap: wrap; margin-top: .4rem; }
.pub__dosaltos label {
  display: flex; flex-direction: column; gap: .15rem;
  font-size: .74rem; color: var(--apagado);
}
/* En automático los números los mantiene el sistema, y se ven igual: un modo que
   no dice qué está haciendo obliga a mirar el sitio para saber si hizo algo. */
.pub__dosaltos input:disabled { background: var(--fondo); color: var(--apagado); }
/* ⚠️ Y EL `<select>` NO SE ESTIRA. Estaba en `width: 100%` porque el formulario
   viejo eran cuatro columnas angostas, una por lugar, y ahi el modo ocupaba el
   ancho de su columna. En el panel del hueco esa misma regla lo hacia cruzar la
   pantalla entera y empujaba los dos numeros al renglon de abajo. */

/* ===========================================================================
 * LOS ROLES: la grilla de permisos.
 *
 * EL PROBLEMA A RESOLVER ES DE LECTURA, no de estilo. Son treinta casillas que
 * hay que poder recorrer decidiendo, y la version de Amura muestra como se pierde
 * eso: 114 permisos apilados en tres columnas de tarjetas, con el nombre repetido
 * y la aclaracion en gris chiquito al lado.
 *
 * Tres cosas lo sostienen: las secciones son cajas de ancho fijo que fluyen
 * (nadie lee una lista de treinta), cada permiso tiene su nombre en peso normal y
 * su ayuda debajo —no al costado, que es donde se apretan— y la seccion vacia se
 * apaga entera para que el ojo salte las que no interesan.
 * ======================================================================== */
.rol__titulo {
  margin: 2rem 0 .8rem;
  font-size: 1rem;
}
.rol__grilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: .9rem;
  align-items: start;
}
.rol__sec {
  margin: 0;
  padding: .7rem .85rem .5rem;
  border: 1px solid var(--linea);
  border-radius: 3px;
  background: var(--papel);
}
/* LA SECCION SIN NADA MARCADO SE APAGA, no se esconde. Esconderla haria que
   marcarla fuera imposible; apagarla deja que el ojo salte las que no interesan
   —que es lo que uno hace al armar un rol— sin sacarlas de la pantalla. */
.rol__sec--vacia { background: #fbfdfc; }
.rol__sec--vacia .rol__permisos { opacity: .55; }
/* ⚠️ EL TITULO DE LA SECCION VA ADENTRO DE LA CAJA, y hay que pedirlo.
   Un <legend> se dibuja POR DEFECTO encima del borde del <fieldset> —partiendolo
   al medio— que es como se ve un formulario clasico y no como se ve una tarjeta.
   Lo vio Hernan mirandolo: *"el titulo de la seccion con el checkbox queda fuera
   de la tarjeta"*. Con `float` el legend vuelve al flujo normal y se comporta
   como cualquier encabezado; el `clear` de abajo es lo que evita que la lista de
   permisos se le suba al lado.

   Y SIGUE SIENDO UN <legend> Y NO UN <div>: es lo que le da nombre al grupo de
   casillas para un lector de pantalla. Se cambia como se ve, no que es. */
.rol__sec > legend {
  float: left;
  width: 100%;
  margin: 0;
  /* El aire va en el legend y no en la lista: con el float de arriba, un margen
     superior de la lista no separa nada. */
  padding: 0 0 .45rem;
}
.rol__sec::after { content: ''; display: table; clear: both; }
.rol__padre {
  display: flex; align-items: center; gap: .5rem;
  width: 100%;
  cursor: pointer;
  font-weight: 700;
}
.rol__padre > span:first-of-type { flex: 1; }
/* EL CONTADOR DICE «3/5» Y NO «3», que es la diferencia entre un dato y una
   respuesta: lo que se quiere saber de un vistazo no es cuantos hay, es si falta
   alguno. */
.rol__cuenta {
  font: .72rem/1 var(--dato);
  color: var(--apagado);
  font-weight: 400;
}
.rol__permisos {
  clear: both;
  list-style: none;
  margin: .5rem 0 0;
  padding: 0;
  display: flex; flex-direction: column; gap: .1rem;
}
.rol__perm {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 .5rem;
  padding: .3rem .2rem;
  border-radius: 2px;
  cursor: pointer;
}
.rol__perm:hover { background: #f3f7f6; }
.rol__perm input { margin-top: .15rem; }
.rol__perm-nombre { font-size: .9rem; }
/* LA AYUDA VA DEBAJO DEL NOMBRE Y EN SU COLUMNA, alineada con el: al costado
   —como en Amura— compite con el nombre en la misma linea y termina cortada. */
.rol__perm-ayuda {
  grid-column: 2;
  font-size: .76rem;
  color: var(--apagado);
  line-height: 1.35;
}
.rol__pie {
  display: flex; gap: .6rem; align-items: center;
  margin-top: 1.6rem;
}
/* BORRAR VA SEPARADO Y ABAJO DE TODO: es la unica accion de esta pantalla que no
   se deshace, y no tiene por que estar al lado de «Guardar». */
.rol__borrar {
  margin-top: 2.5rem; padding-top: 1.2rem;
  border-top: 1px solid var(--linea);
}
/* Un boton de fila: el tamaño normal adentro de una lista pesa mas que la fila. */
.btn--chico { padding: .3rem .6rem; font-size: .8rem; }


/* ===========================================================================
 * EN QUE CABECERAS TRABAJA UNA PERSONA (ficha de usuario).
 *
 * Es una eleccion de dos pasos —«Todas» o «Solo estas» y cuales— asi que se lee
 * de arriba abajo y no en una linea: las dos opciones apiladas, la explicacion
 * de cada una debajo de su rotulo, y la lista COLGANDO de la segunda, que es lo
 * que dice sin palabras que sólo cuenta si se eligio esa.
 * ======================================================================== */
.usr__cabs {
  margin: 0 0 1rem;
  padding: .8rem .9rem;
  border: 1px solid var(--linea);
  border-radius: 3px;
  background: #fbfdfc;
}
.usr__cabs > legend {
  float: left;
  width: 100%;
  margin: 0;
  padding: 0 0 .5rem;
  font-size: .77rem;
  font-weight: 600;
  letter-spacing: .02em;
}
.usr__cabs::after { content: ''; display: table; clear: both; }
.usr__cab-op {
  /* El <legend> flota (misma razon que en roles: si no, se dibuja encima del
     borde), y un float no empuja a los bloques que siguen: sin esto la primera
     opcion se metia al lado del titulo, a la derecha de la caja. */
  clear: both;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 .5rem;
  align-items: start;
  padding: .25rem 0;
  cursor: pointer;
}
.usr__cab-op input { margin-top: .15rem; }
/* El rotulo y su explicacion, uno debajo del otro y los dos en la columna del
   texto: en linea quedaban pegados —«TodasTambien las que se creen»— porque son
   dos elementos sin separacion propia. */
.usr__cab-op > span { display: flex; flex-direction: column; }
.usr__cab-op small { color: var(--apagado); font-size: .78rem; line-height: 1.35; }
/* SANGRADA Y SIN VIÑETAS: cuelga de «Solo estas», no es una lista suelta. */
.usr__cab-lista {
  list-style: none;
  margin: .2rem 0 0;
  padding: 0 0 0 1.55rem;
}
.usr__cab {
  display: flex; align-items: center; gap: .5rem;
  padding: .22rem 0;
  cursor: pointer;
  font-size: .9rem;
}

/* El espacio: la bandeja y NADA adentro, que es literalmente lo que hace. Iba con
   el mismo croquis que la publicidad —los dos huecos— y dos modulos que se ven
   igual en el catalogo son dos modulos que hay que leer para distinguir, que es
   justo lo que el croquis vino a evitar. */
.ed-croquis--aire { background: rgba(127, 127, 127, .06); }
