/* ==========================================================================
   Portal del residente — capa de producto.

   `app.css` pone el armazon (la columna, la navegacion en sus tres rangos) y
   los componentes; `producto.css` lo que comparte con el panel. Aqui va la
   jerarquia propia del portal: el saldo, la invitacion de visita, las
   gestiones y la actividad reciente.

   El residente entra tres minutos desde el telefono a hacer UNA cosa: ver que
   debe, invitar a alguien o reservar el salon. Por eso la pantalla tiene un
   solo protagonista —el saldo— y todo lo demas es una fila de atajos, no una
   rejilla de modulos como en el panel.

   Solo tokens. Ningun color, tamano ni espacio literal.
   ========================================================================== */

/* --- Bienvenida ----------------------------------------------------------- */
.portal-bienvenida {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
}

.portal-bienvenida .titulo {
  margin: var(--s-2) 0;
  font-size: clamp(var(--t-xl), 2.5vw, var(--t-2xl));
}

.portal-bienvenida p { margin: 0; }

.portal-vivienda {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  color: var(--c-texto-secundario);
  font-size: var(--t-sm);
}

/* --- Bloques de la portada ------------------------------------------------
   La rejilla de la portada (`.portal-inicio`) vive en «Sistema de espaciado y
   rejilla», al final del archivo. */
.portal-seccion {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
}

.portal-seccion h2 {
  margin: 0;
  font-size: var(--t-base);
  font-weight: var(--p-semibold);
}

.portal-seccion > a,
.portal-seccion > .texto-terciario { font-size: var(--t-xs); }

/* --- Saldo ---------------------------------------------------------------
   Lo unico de la pantalla con este peso. Si algo mas creciera al lado, los
   dos dejarian de destacar.                                               */
.saldo-residente {
  display: flex;
  flex-direction: column;
  padding: var(--s-6);
}

.portal-saldo-label { margin-top: var(--s-6); font-size: var(--t-sm); }

.saldo-residente .cifra { margin: var(--s-1) 0; font-size: var(--t-3xl); }

.saldo-residente .cifra > span {
  font-size: var(--t-xl);
  font-weight: var(--p-normal);
  color: var(--c-texto-secundario);
}

.portal-saldo-nota { margin: var(--s-2) 0 0; font-size: var(--t-sm); }

/* Con mora, la nota va en el critico (texto sobre la tarjeta: AA en los dos
   temas) y los dias de atraso en semibold: es lo que hay que leer primero.
   Sin fondo rojo detras: un bloque rojo con texto encima no llega a 4.5. */
.portal-saldo-nota--mora { color: var(--c-critico); }
.portal-saldo-nota--mora strong { font-weight: var(--p-semibold); }

/* Pie de datos del saldo (ultimo pago, cargos, boletas en revision). Es lo
   que le da cuerpo a la tarjeta con la cuenta al dia: antes quedaba un "Q 0.00"
   y un hueco del alto de la tarjeta de visitas. Va pegado abajo, sobre el
   boton, y el aire que sobre queda entre la cifra y los datos. */
.saldo-residente__datos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr));
  gap: var(--s-4);
  margin: auto 0 0;
  padding: var(--s-4) 0 0;
  border-top: 1px solid var(--c-borde);
}

.saldo-residente__cifra { margin-bottom: var(--s-6); }
/* Al dia, el hueco a la derecha del Q 0.00 lo ocupa la escena «al dia»: el
   saldo en cero se celebra sin agregar otra accion. */
/* Al dia la escena va en su propia columna, a la altura del bloque de la
   cifra (rotulo, monto y nota) y centrada con el: un tercio de la tarjeta,
   entre 7.5 y 12rem, en proporcion 3:2 del viewBox. Antes era un sello de
   6rem flotando en una tarjeta de 600px. */
.saldo-residente__cifra--al-dia {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(7.5rem, 32%, 12rem);
  column-gap: var(--s-4);
  align-items: center;
}
.saldo-residente__cifra--al-dia > :not(.saldo-residente__dibujo) { grid-column: 1; }
.saldo-residente__dibujo {
  grid-column: 2;
  grid-row: 1 / span 3;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
}

/* Metricas secundarias: rotulo chico y apagado, valor un escalon arriba y
   en semibold, detalle abajo otra vez chico. Tres niveles, no dos parecidos. */
.saldo-residente__datos dt {
  color: var(--c-texto-secundario);
  font-size: var(--t-xs);
  font-weight: var(--p-medio);
}

.saldo-residente__datos dd {
  margin: var(--s-1) 0 0;
  color: var(--c-texto);
  font-size: var(--t-base);
  font-weight: var(--p-semibold);
  line-height: var(--l-ajustado);
  font-variant-numeric: tabular-nums;
}

.saldo-residente__datos dd > span {
  display: block;
  margin-top: var(--s-1);
  color: var(--c-texto-secundario);
  font-size: var(--t-xs);
  font-weight: var(--p-normal);
}

.saldo-residente .boton { margin-top: var(--s-5); align-self: flex-start; }

/* "Ver y pagar": el solido de acento (5.3 con blanco), radio de 8px (no hay
   token de radio de 8: se toma el paso de espaciado equivalente) y semibold,
   para que pese mas que cualquier otro boton de la portada. */
.saldo-residente__pagar {
  border-radius: var(--s-2);
  font-weight: var(--p-semibold);
}

/* --- Invitacion de visita -------------------------------------------------
   Es la accion que mas se usa y la unica tarjeta con fondo de marca: se
   encuentra sin leerla.                                                   */
.portal-visita {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  /* Arriba el mensaje, abajo las acciones (`margin-top: auto`): asi el boton
     queda a la altura del de la tarjeta del saldo, que hace lo mismo. */
  justify-content: flex-start;
  gap: var(--s-4);
  padding: var(--s-6);
  background: var(--c-acento-suave);
}

.portal-visita h2 {
  margin: var(--s-2) 0;
  font-size: var(--t-xl);
  letter-spacing: var(--e-titulo);
}

.portal-visita p { margin: 0; max-width: 24rem; font-size: var(--t-sm); }
.portal-visita .sobretitulo { font-size: var(--t-xs); color: var(--c-acento); }

/* El icono va directo sobre el fondo de la tarjeta, sin cuadro. */
.portal-visita__icono { display: flex; color: var(--c-acento); }
.portal-visita__icono svg { width: var(--s-6); height: var(--s-6); }

.portal-visita__acciones {
  margin-top: auto;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-5);
  font-size: var(--t-sm);
}

.portal-contador {
  padding: var(--s-1) var(--s-2);
  border-radius: var(--r-full);
  background: var(--c-fondo-elevado);
  font-variant-numeric: tabular-nums;
}

/* --- Gestiones rapidas ----------------------------------------------------
   Tres atajos en fila. Son tarjetas y no una lista de enlaces: en el telefono
   la tarjeta da un objetivo del tamano del dedo, y en escritorio se leen de
   un vistazo en vez de como tres renglones subrayados.                    */
.portal-gestiones { margin: var(--s-8) 0; }
.portal-gestiones > .portal-seccion { margin-bottom: var(--s-4); }

.gestiones-residente {
  display: grid;
  /* auto-fit en vez de tres fijas: entre 1200 y 1400px tres columnas dejan
     los atajos demasiado angostos, y un salto seco a una sola columna se ve
     como un corte. Asi pasan de tres a dos y a una segun el ancho real.  */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: var(--s-4);
}

/* Tarjeta ligera: borde de tabla (el mas tenue), sin sombra, y el icono
   suelto. Al pasar, el borde sube al normal, aparece la sombra sutil y la
   flecha toma el acento: se nota sin pintar la tarjeta de azul. */
.gestion-residente {
  display: grid;
  grid-template-columns: var(--s-6) minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  border-color: var(--c-borde-tabla);
  box-shadow: none;
  color: var(--c-texto);
  font-size: var(--t-base);
  font-weight: var(--p-semibold);
  text-decoration: none;
  transition: border-color var(--transicion), box-shadow var(--transicion);
}

.gestion-residente:hover {
  border-color: var(--c-borde);
  box-shadow: var(--sombra-sutil);
}

.gestion-residente small {
  display: block;
  margin-top: var(--s-1);
  color: var(--c-texto-secundario);
  font-size: var(--t-xs);
  font-weight: var(--p-normal);
}

.gestion-residente > span:last-child { color: var(--c-texto-terciario); }
.gestion-residente:hover > span:last-child { color: var(--c-acento); }

/* Icono limpio, sin cuadro detras (tambien en los estados vacios). */
.portal-gestion-icono { display: flex; color: var(--c-acento); }
.portal-gestion-icono svg { width: var(--s-6); height: var(--s-6); }

/* --- Actividad (avisos y proxima reserva) --------------------------------- */
.portal-actividad__bloque { padding: 0; overflow: hidden; }

.portal-actividad__bloque > .portal-seccion {
  padding: var(--s-5);
  border-bottom: 1px solid var(--c-borde);
}

.portal-actividad__bloque > .portal-seccion svg {
  width: var(--s-5);
  color: var(--c-texto-terciario);
}

/* Estado vacio del portal: dice que va a aparecer aqui, no solo que no hay
   nada. "Sin avisos" a secas se lee como que la pantalla no cargo.       */
.portal-vacio,
.estado-tranquilo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-6);
  text-align: center;
}

.portal-vacio h3,
.estado-tranquilo h2 {
  margin: 0;
  font-size: var(--t-sm);
  font-weight: var(--p-semibold);
}

.portal-vacio p,
.estado-tranquilo p {
  max-width: 18rem;
  margin: 0;
  color: var(--c-texto-secundario);
  font-size: var(--t-xs);
}

.portal-vacio .boton,
.estado-tranquilo .boton { margin-top: var(--s-1); font-size: var(--t-xs); }

/* --- Avisos --------------------------------------------------------------- */
.portal-noticias { border: 0; margin: 0; }

.portal-noticias .lista__item {
  justify-content: flex-start;
  gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
}

/* La fecha como taco de calendario: se ubica en el tiempo sin leer el texto. */
.portal-fecha {
  display: grid;
  min-width: var(--s-10);
  padding: var(--s-2);
  border-radius: var(--r-md);
  background: var(--c-fondo-sutil);
  color: var(--c-texto-secundario);
  font-size: var(--t-xs);
  text-align: center;
}

.portal-fecha strong {
  color: var(--c-texto);
  font-size: var(--t-lg);
  font-variant-numeric: tabular-nums;
}

.portal-noticia-titulo {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: var(--t-sm);
  font-weight: var(--p-medio);
}
.portal-noticia-titulo .etiqueta { display: table; margin-top: var(--s-2); }

.portal-noticias .lista__item > a { min-width: 0; }
/* `.portal__principal .lista__item .fila` empuja las filas a la derecha (para
   monto + boton); el enlace del aviso es una fila tambien y quedaba pegado
   al borde derecho de la tarjeta. */
.portal__principal .portal-noticias .lista__item > a.fila { justify-content: flex-start; }
.portal-noticias .portal-fecha { flex-shrink: 0; }

/* Los textos pegados sin espacios deben caber completos en su tarjeta,
   tanto en el muro de avisos como en la bandeja del residente. */
.portal__lectura article.tarjeta {
  min-width: 0;
  overflow-wrap: anywhere;
}

.portal__lectura article.tarjeta > .fila-entre { flex-wrap: wrap; }
.portal__lectura article.tarjeta > .fila-entre > .subtitulo {
  flex: 1 1 12rem;
  min-width: 0;
}
.portal__lectura article.tarjeta > .fila-entre > .etiqueta { flex-shrink: 0; }

/* --- Proxima reserva ------------------------------------------------------ */
.portal-reserva {
  display: grid;
  gap: var(--s-4);
  padding: var(--s-6);
  color: inherit;
  text-decoration: none;
}

.portal-reserva .etiqueta { justify-self: start; }
.portal-reserva h3, .portal-reserva p { margin: 0; }
.portal-reserva h3 { font-size: var(--t-lg); }
.portal-reserva p,
.portal-reserva > span:last-child { font-size: var(--t-sm); }

/* --- Armazon de tableta y escritorio: la piel del panel --------------------

   Pedido del dueno (2026-10-08), viendo el portal en 1920px: "pasa el mismo
   error" que tenia el panel. La lateral era una tarjeta blanca flotante del
   mismo color que las tarjetas, la barra de arriba otra tarjeta con un rotulo
   en mayusculas, y el contenido una columna centrada con dos franjas vacias.

   Ahora es el armazon del panel (`panel.css`): lateral gris oscura
   (`--c-lateral*`, la misma en los dos temas) pegada al borde, barra plana
   sobre el lienzo y el contenido a todo el ancho, con las tarjetas blancas
   como unicas superficies.

   Todo va acotado a `.app--portal` (la pone `residentes/base.html`): las
   pantallas de acceso heredan de esa base pero pintan su propio armazon.

   En el telefono (< 48rem) no cambia nada: columna, encabezado arriba y los
   cinco destinos al pie, donde llega el pulgar.                            */
.portal-cabecera { display: none; }

@media (min-width: 48rem) {
  /* Fondo del portal: Nubes Debiles (`--c-fondo-sutil`), mas suave que el
     lienzo #d6d6d6 del panel; las tarjetas blancas se separan por ese color
     ligero y un borde tenue, no por contraste duro. */
  body:has(> .app--portal) { padding: 0; background: var(--c-fondo-sutil); }

  .app.app--portal {
    width: 100%;
    max-width: none;
    min-height: 100vh;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    /* `overflow: hidden` anula el `position: sticky` de lateral y barra. */
    overflow: visible;
    background: var(--c-fondo-sutil);
  }

  /* La lateral es superficie oscura: se re-declaran los tokens que consumen
     sus reglas (como `.panel__lateral`), y el item, el icono, el borde y el
     foco toman la paleta sin una regla de color propia cada uno. */
  .app--portal .navegacion--lateral {
    border: 0;
    background: var(--c-lateral);
    color: var(--c-lateral-texto);
    --c-texto: var(--c-lateral-texto);
    --c-texto-secundario: var(--c-lateral-secundario);
    --c-texto-terciario: var(--c-lateral-terciario);
    --c-acento: var(--c-lateral-acento);
    --c-acento-suave: var(--c-lateral-hover);
    --c-borde: var(--c-lateral-borde);
  }

  /* Marca: el logo directo sobre el gris, sin cuadro blanco, y al lado el
     condominio con para que es esta superficie —igual que "Administracion"
     en el panel—. Antes "Portal del residente" iba en mayusculas en la barra. */
  .app--portal .navegacion__marca {
    flex-direction: row;
    align-items: center;
    gap: var(--s-3);
    padding: var(--s-2);
    border-radius: var(--r-md);
    text-align: left;
    transition: background var(--transicion);
  }

  .app--portal .navegacion__marca:hover { background: var(--c-lateral-hover); }

  .app--portal .navegacion__logo {
    flex: none;
    width: 2rem;
    height: 2rem;
    max-width: none;
    max-height: none;
    object-fit: contain;
  }

  .navegacion__marca-texto { display: grid; min-width: 0; gap: 1px; }

  .app--portal .navegacion__condominio {
    overflow: hidden;
    color: var(--c-texto);
    font-size: var(--t-base);
    font-weight: var(--p-semibold);
    line-height: var(--l-ajustado);
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .navegacion__rotulo { color: var(--c-texto-terciario); font-size: var(--t-xs); }

  /* Items: mismo peso que los del panel. El activo lleva fondo, peso y el
     icono en verde, no solo un cambio de tono. */
  .app--portal .navegacion--lateral .navegacion__item {
    color: var(--c-texto-secundario);
    font-weight: var(--p-medio);
  }

  .app--portal .navegacion--lateral .navegacion__icono { color: var(--c-texto-terciario); }

  .app--portal .navegacion--lateral .navegacion__item:hover {
    background: var(--c-lateral-hover);
    color: var(--c-texto);
  }

  .app--portal .navegacion--lateral .navegacion__item[aria-current="page"] {
    background: var(--c-lateral-activo);
    color: var(--c-texto);
    font-weight: var(--p-semibold);
  }

  .app--portal .navegacion--lateral .navegacion__item[aria-current="page"] .navegacion__icono {
    color: var(--c-acento);
  }

  /* Barra superior plana: sin tarjeta, sin rotulo, pegada arriba al rodar
     con el lienzo translucido detras. Solo herramientas, a la derecha. */
  .portal-cabecera {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--s-2);
    min-height: 3.5rem;
    padding: var(--s-2) var(--s-6);
    border-bottom: 1px solid var(--c-borde);
    /* Superficie propia, no el lienzo: en tema claro la barra del mismo gris
       que el fondo se leia como parte del contenido. */
    background: color-mix(in srgb, var(--c-fondo-elevado) 92%, transparent);
    backdrop-filter: blur(10px);
  }

  .portal-cabecera .selector-tema { border-color: transparent; }
  .portal-cabecera .selector-tema:hover { background: var(--c-acento-suave); }

  /* El verde suave del avatar casi no se distingue del lienzo: sobre la
     barra plana va en superficie blanca con borde, como una tarjeta chica. */
  .portal-cabecera .avatar-usuario {
    border: 1px solid var(--c-borde);
    background: var(--c-fondo-elevado);
  }

  /* Contenido a todo el ancho, alineado a la izquierda bajo la barra. Lo que
     no debe estirarse —formularios, detalle, texto seguido— conserva su
     ancho de lectura con `.portal__lectura`, pero arranca en el mismo borde
     que todo lo demas en vez de flotar al centro. */
  .app--portal .contenido {
    width: 100%;
    max-width: none;
    margin-inline: 0;
    padding: var(--s-6) var(--s-6) var(--s-12);
    background: transparent;
  }

  .app--portal .contenido > .pila-lg,
  .app--portal .contenido > .portal__avisos { max-width: none; margin-inline: 0; }

  .app--portal .contenido > .portal__lectura { max-width: var(--ancho-contenido); }

  .app--portal .portal__principal > .pie {
    max-width: none;
    margin-inline: 0;
    padding-inline: var(--s-6);
    border: 0;
    background: transparent;
  }
}

/* Tableta (48-64rem): una sola barra arriba. La navegacion ya es una franja
   horizontal (marca arriba, destinos abajo) y la barra de herramientas era una
   segunda franja debajo, con medio ancho vacio. Ahora las herramientas suben
   al hueco a la derecha de la marca: la franja de la navegacion es la unica,
   pegada arriba al rodar, y tema, campanita y cuenta quedan siempre a mano. */
@media (min-width: 48rem) and (max-width: 63.99rem) {
  .app--portal .navegacion--lateral {
    position: sticky;
    top: 0;
    z-index: 20;
    padding-inline: var(--s-6);
    border-bottom: 1px solid var(--c-lateral-borde);
  }

  /* La marca no se mete bajo las herramientas: se recorta antes. */
  .app--portal .navegacion__marca { max-width: calc(100% - 20rem); }

  .app--portal .navegacion--lateral .navegacion__grupo--destinos { justify-content: space-between; }

  .portal-cabecera {
    position: fixed;
    top: 0;
    right: 0;
    z-index: 21;
    /* El alto de la primera linea de la barra: padding + objetivo de toque. */
    min-height: calc(var(--alto-toque) + 2 * var(--s-3));
    padding: var(--s-3) var(--s-6);
    border: 0;
    background: transparent;
    backdrop-filter: none;
  }
}

@media (min-width: 64rem) {
  .app--portal .portal { gap: 0; padding: 0; }

  /* Pegada al borde izquierdo y de alto completo: flotando como tarjeta se
     leia como un bloque mas del contenido y no como el menu. */
  .app--portal .navegacion--lateral {
    width: 16rem;
    top: 0;
    height: 100vh;
    height: 100dvh;
    gap: var(--s-6);
    padding: var(--s-4) var(--s-3);
    border-right: 1px solid var(--c-lateral-borde);
    border-radius: 0;
    box-shadow: none;
  }

  .app--portal .navegacion__marca { align-items: center; margin: 0; }

  .app--portal .navegacion--lateral .navegacion__item {
    min-height: 2.5rem;
    padding: 0 var(--s-3);
    font-size: var(--t-sm);
  }

  .app--portal .portal__principal { gap: 0; min-height: 100vh; }

  .portal-cabecera { padding-inline: var(--s-10); }

  .app--portal .contenido { padding: var(--s-8) var(--s-10) var(--s-12); }

  .app--portal .portal__principal > .pie { padding-inline: var(--s-10); }
}

/* --- Rejillas de las pantallas interiores ---------------------------------
   Con el contenido a todo el ancho, una pila de una sola columna en 1920px
   deja la fecha de un movimiento a 1500px de su monto. Desde 80rem, Pagos y
   Visitas se parten en dos: el resumen o la accion a la izquierda y la lista
   a la derecha. Abajo de eso es la pila de siempre, en el mismo orden.   */
.portal-columnas,
.portal-visitas { display: grid; gap: var(--s-rejilla); }

/* Sobre la rejilla de 12 de la portada: 5 + 7 (el resumen no se aprieta a
   un tercio, donde las boletas se partian en cinco renglones) y 6 + 6 las
   mitades. Las lineas de corte son las mismas en todo el portal. */
@media (min-width: 80rem) {
  .portal-columnas {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    align-items: start;
  }
  .portal-columnas > :nth-child(odd) { grid-column: span 5; }
  .portal-columnas > :nth-child(even) { grid-column: span 7; }
  .portal-columnas.portal-columnas--mitades > * { grid-column: span 6; }

  .portal-visitas {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-template-rows: auto 1fr;
    align-items: start;
  }

  .portal-visitas > :first-child { grid-column: 1 / span 5; grid-row: 1; }
  .portal-visitas__recientes { grid-column: 1 / span 5; grid-row: 2; }
  .portal-visitas__lista { grid-column: 6 / span 7; grid-row: 1 / span 2; }
}

/* Listas y formularios en las pantallas interiores. */
.portal__principal .contenido > h1 { margin-bottom: var(--s-5); }
.portal__principal .contenido > .tarjeta + .tarjeta { margin-top: var(--s-rejilla); }
/* Solo los formularios con campos: los de un boton (cerrar sesion, cancelar,
   revocar) no se envuelven en una caja blanca vacia. */
.portal__lectura > form:has(.campo, fieldset) { padding: var(--s-6); background: var(--c-fondo-elevado); border: 1px solid var(--c-borde); border-radius: var(--r-lg); }
.portal__lectura .campo__etiqueta { font-weight: var(--p-medio); }
.portal__principal .lista__item { gap: var(--s-4); }
.portal__principal .lista__item > span:first-child { min-width: 0; overflow-wrap: anywhere; }
.portal__principal .lista__item .fila { flex-wrap: wrap; justify-content: flex-end; }
.portal__principal .lista__item form { flex-wrap: wrap; }
.portal__principal .lista__principal { line-height: var(--l-normal); }
.portal__principal .vacio { border: 1px dashed var(--c-borde-fuerte); border-radius: var(--r-lg); background: var(--c-fondo-elevado); }
.portal__principal .paginacion { display: flex; align-items: center; justify-content: center; gap: var(--s-4); margin-top: var(--s-5); flex-wrap: wrap; }
.portal__principal .paginacion a { min-height: var(--alto-toque); display: inline-flex; align-items: center; }
.portal__principal .documento-lista { margin-top: var(--s-5); }
.portal__principal .lista > li:has(> .lista__item) { list-style: none; }
.portal__principal .lista > li > .lista__item { width: 100%; }
@media (max-width: 47.99rem) {
  .portal__lectura > form { padding: var(--s-5) var(--s-4); }
  .portal__principal .lista__item { flex-wrap: wrap; }
  .portal__principal .lista__item > .fila { width: 100%; justify-content: space-between; }
  .portal-bienvenida { flex-direction: column; align-items: flex-start; gap: var(--s-3); }
  .portal-bienvenida .texto-secundario { font-size: var(--t-sm); }
  .portal-seccion > .texto-terciario { display: none; }
  .saldo-residente .cifra { font-size: var(--t-2xl); }
  .portal-visita { gap: var(--s-5); }
  .portal-visita__icono { display: none; }
  .portal-gestiones { margin-block: var(--s-6); }
  /* En el telefono tambien: el contenido sobre Nubes Debiles y las tarjetas
     blancas encima, en vez de blanco sobre blanco. */
  .app.app--portal { background: var(--c-fondo-sutil); }
}

/* Tarjetas de la portada con el borde mas tenue: sobre Nubes Debiles el
   #cccccc pesaba mas que el contenido. */
.saldo-residente,
.portal-visita,
.portal-actividad__bloque { border-color: var(--c-borde-tabla); }

/* ==========================================================================
   Componentes de la ola 3 (plan docs/11, fase C). Solo tokens.
   ========================================================================== */

/* --- Acciones del encabezado: campanita y menu de la cuenta --------------
   Las dos van en el encabezado del telefono y en la cabecera de escritorio
   (el mismo parcial, `residentes/partials/cabecera_acciones.html`). */
.encabezado__marca { min-width: 0; }
.encabezado__marca > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cabecera-acciones {
  display: flex;
  align-items: center;
  gap: var(--s-1);
  flex: none;
}

/* La campanita es un <details> como el menu de la cuenta (y como la del
   panel): abre un desplegable con lo mas nuevo de Avisos. */
.campanita { position: relative; }
.campanita > summary { list-style: none; cursor: pointer; }
.campanita > summary::-webkit-details-marker { display: none; }

.campanita__boton {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: var(--alto-toque);
  height: var(--alto-toque);
  border-radius: var(--r-md);
  color: var(--c-texto-secundario);
}

.campanita__boton:hover,
.campanita[open] > .campanita__boton,
.campanita__boton[aria-current="page"] { background: var(--c-acento-suave); color: var(--c-texto); }

.campanita__panel {
  position: absolute;
  top: calc(100% + var(--s-1));
  right: 0;
  z-index: 30;
  display: grid;
  gap: var(--s-2);
  width: min(22rem, calc(100vw - var(--s-8)));
  padding: var(--s-3);
  border: 1px solid var(--c-borde);
  border-radius: var(--r-lg);
  background: var(--c-fondo-elevado);
  box-shadow: var(--sombra-elevada);
}

.campanita__titulo { margin: 0; padding: var(--s-1) var(--s-2) 0; font-weight: var(--p-semibold); }
.campanita__titulo .texto-terciario { font-size: var(--t-xs); font-weight: var(--p-normal); }

.campanita__lista {
  display: grid;
  max-height: min(60vh, 34rem);
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}

.campanita__lista > li + li { border-top: 1px solid var(--c-borde); }

.campanita__aviso {
  display: grid;
  gap: 2px;
  padding: var(--s-2);
  border-radius: var(--r-md);
  color: var(--c-texto);
  font-size: var(--t-sm);
  text-decoration: none;
  overflow-wrap: anywhere;
}

.campanita__aviso:hover { background: var(--c-fondo-sutil); }
.campanita__aviso--nueva { background: var(--c-acento-suave); }
.campanita__aviso--nueva > strong::before {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  margin-right: var(--s-2);
  border-radius: var(--r-full);
  background: var(--c-acento);
  vertical-align: 0.1em;
}
.campanita__mensaje { color: var(--c-texto-secundario); }
.campanita__aviso time { color: var(--c-texto-terciario); font-size: var(--t-xs); }
.campanita__vacia { margin: 0; padding: 0 var(--s-2); color: var(--c-texto-secundario); font-size: var(--t-sm); }

.campanita__todas {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  min-height: var(--alto-toque);
  padding-inline: var(--s-2);
  font-size: var(--t-sm);
  font-weight: var(--p-medio);
}

/* Telefono: la campana va a mitad del encabezado y un desplegable anclado a
   ella se salia por la izquierda. Ahi ocupa el ancho de la pantalla menos el
   margen, bajo el encabezado, y rueda por dentro si no cabe. */
@media (max-width: 47.99rem) {
  .campanita__panel {
    position: fixed;
    top: calc(var(--s-16) + env(safe-area-inset-top));
    right: var(--s-3);
    left: var(--s-3);
    width: auto;
    max-height: calc(100dvh - 9rem);
    overflow-y: auto;
  }
}

.campanita__icono { width: 1.375rem; height: 1.375rem; }

/* El numero usa el par de tokens del boton primario: contraste AA en los
   dos temas, que el rojo de "critico" con texto blanco no cumple en oscuro. */
.campanita__contador {
  position: absolute;
  top: var(--s-1);
  right: var(--s-1);
  min-width: 1.25rem;
  padding: 0 var(--s-1);
  border-radius: var(--r-full);
  background: var(--c-acento-solido);
  color: var(--c-acento-solido-texto);
  font-size: var(--t-xs);
  font-weight: var(--p-semibold);
  line-height: 1.25rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.menu-cuenta { position: relative; }

.menu-cuenta > summary {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-height: var(--alto-toque);
  padding: 0 var(--s-2);
  border-radius: var(--r-md);
  color: var(--c-texto);
  font-size: var(--t-sm);
  font-weight: var(--p-medio);
  list-style: none;
}

.menu-cuenta > summary::-webkit-details-marker { display: none; }
.menu-cuenta > summary:hover,
.menu-cuenta[open] > summary { background: var(--c-acento-suave); }
.menu-cuenta__flecha { width: 1rem; height: 1rem; transition: transform var(--transicion); }
.menu-cuenta[open] .menu-cuenta__flecha { transform: rotate(180deg); }

/* El nombre completo solo cuando hay ancho; en el telefono la inicial y la
   casa: sin el avatar, «A-201 ▾» no se reconocia como el menu de la cuenta. */
.menu-cuenta__nombre { display: none; }

/* El interruptor de tema del encabezado del telefono es un objetivo tactil:
   44 px, no los 36 del control de escritorio. */
.encabezado .selector-tema { width: var(--alto-toque); height: var(--alto-toque); }

.menu-cuenta__panel {
  position: absolute;
  top: calc(100% + var(--s-1));
  right: 0;
  z-index: 30;
  width: min(18rem, calc(100vw - var(--s-8)));
  padding: var(--s-2);
  border: 1px solid var(--c-borde);
  border-radius: var(--r-lg);
  background: var(--c-fondo-elevado);
  box-shadow: var(--sombra-elevada);
}

.menu-cuenta__grupo + .menu-cuenta__grupo {
  margin-top: var(--s-2);
  padding-top: var(--s-2);
  border-top: 1px solid var(--c-borde);
}

.menu-cuenta__rotulo {
  padding: var(--s-1) var(--s-3);
  color: var(--c-texto-terciario);
  font-size: var(--t-xs);
  font-weight: var(--p-semibold);
}

.menu-cuenta__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  width: 100%;
  min-height: var(--alto-toque);
  padding: var(--s-2) var(--s-3);
  border: 0;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--c-texto);
  font-size: var(--t-sm);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.menu-cuenta__item:hover { background: var(--c-acento-suave); }
.menu-cuenta__item[aria-current="true"] { font-weight: var(--p-semibold); }

@media (min-width: 48rem) {
  .menu-cuenta .avatar-usuario { display: inline-grid; }
  .menu-cuenta__nombre { display: inline; color: var(--c-texto-secundario); font-weight: var(--p-normal); }
}

/* --- Pestanas de una seccion ---------------------------------------------
   Dos vistas de la misma seccion (Pagos: por pagar / pagos hechos; Visitas:
   invitaciones / quien entro; Reglamento: reglas / documentos). Se ven como
   pestanas y no como botones porque no son acciones: son lugares. */
.pestanas {
  display: flex;
  gap: var(--s-1);
  overflow-x: auto;
  border-bottom: 1px solid var(--c-borde);
}

.pestanas__item {
  display: inline-flex;
  align-items: center;
  flex: none;
  min-height: var(--alto-toque);
  padding: var(--s-2) var(--s-3);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  color: var(--c-texto-secundario);
  font-size: var(--t-sm);
  font-weight: var(--p-medio);
  text-decoration: none;
}

.pestanas__item:hover { color: var(--c-texto); }
.pestanas__item[aria-current="page"] { border-bottom-color: var(--c-acento); color: var(--c-texto); }

/* --- "Invitar de nuevo": personas recientes ------------------------------- */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: var(--alto-toque);
  padding: var(--s-2) var(--s-4);
  border: 1px solid var(--c-borde-fuerte);
  border-radius: var(--r-full);
  background: var(--c-fondo-elevado);
  color: var(--c-texto);
  font-size: var(--t-sm);
  text-decoration: none;
}

.chip:hover { border-color: var(--c-acento); background: var(--c-acento-suave); }

/* --- Visitas frecuentes (inicio) ------------------------------------------
   Fila de avatares con iniciales y el nombre abajo. Cada uno es un objetivo
   del ancho del dedo; si no caben, la fila rueda de lado en vez de partirse
   en dos renglones desalineados como las pills. Discretos a proposito: la
   accion dominante de la tarjeta sigue siendo "Invitar visita". */
.visitas-frecuentes {
  display: grid;
  gap: var(--s-3);
  width: 100%;
  padding-top: var(--s-4);
  border-top: 1px solid var(--c-borde);
}

.visitas-frecuentes__titulo {
  margin: 0;
  color: var(--c-texto-secundario);
  font-size: var(--t-xs);
  font-weight: var(--p-medio);
}

.visitas-frecuentes__lista {
  display: flex;
  gap: var(--s-2);
  margin: 0;
  padding: 0 0 var(--s-1);
  overflow-x: auto;
  list-style: none;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
}

.visita-frecuente {
  display: grid;
  justify-items: center;
  gap: var(--s-2);
  width: 4.5rem;
  padding: var(--s-1);
  border-radius: var(--r-md);
  color: var(--c-texto);
  text-decoration: none;
  scroll-snap-align: start;
}

.visita-frecuente__avatar {
  display: grid;
  place-items: center;
  width: var(--alto-toque);
  height: var(--alto-toque);
  border: 1px solid var(--c-borde);
  border-radius: var(--r-full);
  background: var(--c-fondo-elevado);
  color: var(--c-acento);
  font-size: var(--t-sm);
  font-weight: var(--p-semibold);
  transition: border-color var(--transicion);
}

.visita-frecuente__nombre {
  display: -webkit-box;
  overflow: hidden;
  font-size: var(--t-xs);
  line-height: var(--l-ajustado);
  text-align: center;
  overflow-wrap: anywhere;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}

.visita-frecuente:hover .visita-frecuente__avatar { border-color: var(--c-acento); }
.visita-frecuente:hover .visita-frecuente__nombre { color: var(--c-acento); }

/* --- Linea de avance de un reporte ----------------------------------------
   Tres pasos unidos por una linea (conexion uniforme): se lee como una
   secuencia, no como tres etiquetas sueltas. */
.pasos {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

.pasos__paso {
  position: relative;
  display: grid;
  justify-items: center;
  align-content: start;
  gap: var(--s-1);
  text-align: center;
  font-size: var(--t-sm);
  color: var(--c-texto-terciario);
}

.pasos__paso::before {
  content: "";
  position: absolute;
  top: 0.6875rem;
  left: -50%;
  width: 100%;
  height: 2px;
  background: var(--c-borde-fuerte);
}

.pasos__paso:first-child::before { display: none; }
.pasos__paso--hecho::before { background: var(--c-acento); }

.pasos__marca {
  position: relative;
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border: 2px solid var(--c-borde-fuerte);
  border-radius: var(--r-full);
  background: var(--c-fondo-elevado);
}

.pasos__paso--hecho { color: var(--c-texto); }
.pasos__paso--hecho .pasos__marca { border-color: var(--c-acento-solido); background: var(--c-acento-solido); }
.pasos__paso--hecho .pasos__marca::after {
  content: "";
  width: 0.375rem;
  height: 0.625rem;
  margin-top: -0.125rem;
  border: solid var(--c-acento-solido-texto);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.pasos__paso[aria-current="step"] { font-weight: var(--p-semibold); }
.pasos__fecha { font-size: var(--t-xs); color: var(--c-texto-secundario); font-weight: var(--p-normal); }

/* --- Movimientos de la cuenta en una linea -------------------------------- */
/* La fecha en columna de ancho fijo y cifras tabulares: con `auto` cada fila
   media lo suyo y los conceptos arrancaban en una x distinta en cada renglon. */
.movimiento { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr) auto; gap: var(--s-3); }
.movimiento__fecha { color: var(--c-texto-terciario); font-size: var(--t-sm); white-space: nowrap; font-variant-numeric: tabular-nums; }
.movimiento__concepto { min-width: 0; overflow-wrap: anywhere; }
.movimiento__monto { white-space: nowrap; font-variant-numeric: tabular-nums; }
.movimiento__monto--abono { color: var(--c-positivo); }
.saldo-final { display: flex; justify-content: space-between; gap: var(--s-3); padding: var(--s-4) var(--s-5); border-top: 1px solid var(--c-borde); background: var(--c-fondo-sutil); font-weight: var(--p-semibold); }

/* En el telefono la fecha sube a su propio renglon: en tres columnas, a
   360px el concepto quedaba en 90px y se partia a media palabra. */
@media (max-width: 47.99rem) {
  .movimiento { grid-template-columns: minmax(0, 1fr) auto; row-gap: var(--s-1); }
  .movimiento__fecha { grid-column: 1 / -1; font-size: var(--t-xs); }
}

/* ==========================================================================
   Revision de todas las pantallas (2026-10-09). Solo tokens.
   ========================================================================== */

/* Boletas en revision dentro de su tarjeta: filas sin caja propia (la caja ya
   es la tarjeta), con la insignia y el monto alineados a la derecha. */
.portal-boletas { border: 0; border-radius: 0; background: transparent; }
.portal-boletas .lista__item { padding-inline: 0; }

/* Pagos hechos: fecha | que se pago y como | estado | monto, en columnas
   fijas para que fechas, insignias y montos se lean en vertical. En el
   telefono la fecha sube arriba y el estado baja junto al monto. */
.portal-pago {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr) 8rem 8rem;
  align-items: center;
  gap: var(--s-4);
}
.portal-pago__fecha { color: var(--c-texto-secundario); font-size: var(--t-sm); font-variant-numeric: tabular-nums; }
.portal-pago__concepto { display: grid; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.portal-pago__concepto .texto-terciario { font-size: var(--t-sm); }
.portal-pago__estado { justify-self: start; }
.portal-pago__monto { justify-self: end; font-weight: var(--p-semibold); white-space: nowrap; }

@media (max-width: 47.99rem) {
  .portal-pago { grid-template-columns: minmax(0, 1fr) auto; row-gap: var(--s-2); }
  .portal-pago__fecha { grid-column: 1 / -1; font-size: var(--t-xs); }
  .portal-pago__concepto { grid-column: 1 / -1; }
}

/* Formulario con su historial al lado (Ya pague): dos mitades desde 80rem. */
/* Formularios que van en pantallas de dos columnas: misma caja que los de
   `.portal__lectura` (superficie blanca con borde sobre el lienzo). */
.portal-columnas form.pila {
  padding: var(--s-6);
  border: 1px solid var(--c-borde);
  border-radius: var(--r-lg);
  background: var(--c-fondo-elevado);
  box-shadow: var(--sombra-sutil);
}

/* Montos de las listas en columna: ancho minimo y a la derecha, despues de la
   insignia, para que una insignia mas larga no corra la cifra de su renglon. */
.portal__principal .lista__item .fila > .monto {
  min-width: 6.5rem;
  text-align: right;
  font-weight: var(--p-semibold);
  white-space: nowrap;
}
@media (max-width: 47.99rem) {
  .portal-columnas form.pila { padding: var(--s-5) var(--s-4); }
  .portal-acciones-formulario > .boton--primario { flex: 1 1 100%; }
}

/* Resultado de un pago (exito, en espera, error): una tarjeta centrada en el
   area de contenido, con el icono del estado arriba. */
.app--portal .contenido > .portal-resultado,
.portal-resultado { max-width: 32rem; margin-inline: auto; padding-top: var(--s-6); text-align: center; }
.portal-resultado > .tarjeta { padding: var(--s-8) var(--s-6); }
.portal-resultado__icono {
  display: inline-grid;
  place-items: center;
  width: 3.5rem;
  height: 3.5rem;
  margin-bottom: var(--s-2);
  border-radius: var(--r-full);
}
.portal-resultado__icono svg { width: 1.75rem; height: 1.75rem; }
.portal-resultado__icono--positivo { background: var(--c-positivo-suave); color: var(--c-positivo); }
.portal-resultado__icono--atencion { background: var(--c-atencion-suave); color: var(--c-atencion); }
.portal-resultado__icono--critico { background: var(--c-critico-suave); color: var(--c-critico); }
.portal-resultado__referencia {
  display: grid;
  gap: var(--s-1);
  margin-bottom: 0;
  padding: var(--s-4);
  border-radius: var(--r-md);
  background: var(--c-fondo-sutil);
}
.portal-resultado__referencia dt { color: var(--c-texto-secundario); font-size: var(--t-xs); }
.portal-resultado__referencia dd { margin: 0; }
.portal-resultado__referencia dd.fuente-tabular { font-size: var(--t-xl); font-weight: var(--p-semibold); letter-spacing: 0.08em; }
.portal-resultado__referencia dd.texto-terciario { font-size: var(--t-xs); }

/* Listas cuyo renglon va envuelto en un <li> (enlace o formulario adentro):
   `.lista__item + .lista__item` no los alcanza porque no son hermanos, y las
   filas quedaban sin separador. */
.portal__principal .lista > li + li { border-top: 1px solid var(--c-borde); }

/* Detalle de una invitacion vigente: el QR a la izquierda, lo demas a la
   derecha desde 64rem. */
.portal-qr { display: grid; gap: var(--s-8); }
@media (min-width: 64rem) {
  .portal-qr { grid-template-columns: minmax(18rem, 24rem) minmax(0, 36rem); align-items: start; }
  .portal-qr > .qr { margin: 0; }
}

/* Pares rotulo-valor de un detalle (invitacion, reserva, reporte, vehiculo):
   el rotulo chico arriba y el dato abajo, en una rejilla que se reparte. */
.portal-datos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 8rem), 1fr));
  gap: var(--s-4);
  margin-bottom: 0;
}
.portal-datos dt { color: var(--c-texto-secundario); font-size: var(--t-xs); }
.portal-datos dd { margin: var(--s-1) 0 0; font-weight: var(--p-medio); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }

/* Portada de un area sin foto: el icono de Reservas, no un rombo de texto. */
.amenidad__icono { width: 2.5rem; height: 2.5rem; }

/* Formulario de reserva en la columna ancha: los cuatro campos en dos por
   dos; reglamento y boton a lo ancho. */
@media (min-width: 80rem) {
  .portal-columnas .reserva-form .fieldset-plano {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-4) var(--s-5);
  }
  .portal-columnas .reserva-form .fieldset-plano > * { margin-top: 0; }
  .portal-columnas .reserva-form .fieldset-plano > :not(.campo) { grid-column: 1 / -1; }
  .portal-columnas .reserva-form .fieldset-plano > .boton { justify-self: start; width: auto; }
}

/* Pie de un detalle: volver a la izquierda, la accion final a la derecha. */
.portal-pie-acciones { justify-content: space-between; }
.portal-accion-final { margin-left: auto; }

/* Titulo de la pantalla con su accion principal a la derecha (Reportes,
   Vehiculos). En el telefono la accion baja a lo ancho, donde llega el dedo. */
.portal-encabezado {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3) var(--s-5);
}
.portal-encabezado .titulo { margin: 0; }
@media (max-width: 47.99rem) {
  .portal-encabezado > .boton { flex: 1 1 100%; }
}

/* El {% csrf_token %} es el primer hijo del formulario: la pila le daba
   margen al primer campo visible y la caja quedaba con un hueco arriba. */
.portal__principal form.pila > input[type="hidden"]:first-child + *,
.portal__principal form.pila > input[type="hidden"]:first-child + input[type="hidden"] + * { margin-top: 0; }

/* Documento: tipo como insignia, fecha y peso al lado; titulo y botones
   centrados en la fila. */
.documento-fila__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  margin: var(--s-2) 0 0;
  color: var(--c-texto-secundario);
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
}

/* Perfil: la persona con su inicial, como en el menu de la cuenta. */
.portal-persona { display: flex; align-items: center; gap: var(--s-4); }
.portal-persona > div { display: grid; gap: var(--s-1); min-width: 0; }
.portal-persona__avatar { display: inline-grid; flex: none; width: 3rem; height: 3rem; font-size: var(--t-lg); }

/* Casillas en lista (preferencias de avisos): cada opcion es un renglon
   tocable completo, no una casilla de 13px suelta. */
.portal-opciones { min-width: 0; margin-inline: 0; margin-bottom: 0; padding: 0; border: 0; }
.portal-opciones > legend { margin-bottom: var(--s-2); padding: 0; }
.portal-opcion { justify-content: flex-start; gap: var(--s-3); cursor: pointer; }
.portal-opcion input { width: 1.125rem; height: 1.125rem; margin: 0; accent-color: var(--c-acento-solido); }
.portal-opcion:hover { background: var(--c-fondo-sutil); }

/* `.lista { margin: 0 }` va despues de las pilas en app.css y les gana: una
   lista hija directa de una pila quedaba pegada a lo de arriba. */
.portal__principal .pila > .lista:not(:first-child) { margin-top: var(--s-4); }
.portal__principal .pila-sm > .lista:not(:first-child) { margin-top: var(--s-2); }
.portal__principal .pila-lg > .lista:not(:first-child) { margin-top: var(--s-8); }

/* Placa: se lee como placa, con espaciado y cifras parejas. */
.portal-placa { letter-spacing: 0.06em; font-variant-numeric: tabular-nums; }

/* Desde tableta, insignia + monto (+ boton) de un renglon no se parten: el
   texto de la izquierda es el que se acomoda en mas lineas. */
@media (min-width: 48rem) {
  .portal__principal .lista__item > .fila:last-child:not(:first-child) { flex: none; flex-wrap: nowrap; }
}

/* Telefono: ajustes de la portada. */
.portal__principal .portal-noticias .lista__item > a.fila { flex-wrap: nowrap; }
.portal-seccion > .boton--texto { flex: none; white-space: nowrap; }
.encabezado__marca { text-decoration: none; }
@media (max-width: 47.99rem) {
  .saldo-residente__datos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Ancho de lectura tambien cuando `.portal__lectura` no es hija directa. */
.portal__principal .pila-lg > .portal__lectura { max-width: var(--ancho-contenido); }

.portal-persona .fuente-tabular { white-space: nowrap; }

/* «Pagar»: las dos formas de pago como tarjetas hermanas, cada una con su
   accion al pie (Fitts: la misma altura de boton en las dos columnas). En el
   telefono, una debajo de la otra. Sin pasarela, la unica ocupa el ancho de
   lectura. Las casillas de los cargos, sin el marco del fieldset. */
.opciones-pago { display: grid; gap: var(--s-rejilla); align-items: stretch; }
.opciones-pago--una { max-width: var(--ancho-contenido); }
@media (min-width: 64rem) {
  .opciones-pago:not(.opciones-pago--una) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.opcion-pago { display: flex; flex-direction: column; gap: var(--s-3); padding: var(--s-6); }
.opcion-pago__titulo { margin: 0; font-size: var(--t-lg); }
.opcion-pago__cuerpo { display: flex; flex: 1 1 auto; flex-direction: column; gap: var(--s-4); }
.opcion-pago__cuerpo > .opciones-secundarias { margin: 0; }
.opcion-pago__accion { margin-top: auto; }
.opcion-pago__cargos { min-width: 0; margin: 0; padding: 0; border: 0; }
.portal__principal .opcion-pago__cargos .lista__item > label.fila { flex: 1 1 auto; min-width: 0; justify-content: flex-start; gap: var(--s-3); cursor: pointer; }
.opcion-pago__cargos input[type="checkbox"] { width: 1.125rem; height: 1.125rem; flex: none; accent-color: var(--c-acento-solido); }
@media (max-width: 47.99rem) {
  .opcion-pago { padding: var(--s-5); }
}

/* ==========================================================================
   Portada del residente en el telefono (propuesta de la disenadora,
   2026-10-20). Solo < 48rem: en tablet y escritorio manda la lateral.
   - Barra inferior en Rojo Amapola, la marca donde llega el pulgar. El
     destino actual se marca con una raya blanca arriba y semibold, no con
     opacidad: atenuar el blanco lo baja de 4.5 sobre el rojo.
   - Tarjeta de saldo: cifra grande en el color del texto (la moneda ya no va
     apagada), la etiqueta de estado solida en naranja de marca y "Ver y
     pagar" a todo el ancho, en su propio pie. El boton sigue en el azul de
     la interfaz y el atraso en el critico: la regla de marca no cambia.
   ========================================================================== */
@media (max-width: 47.99rem) {
  .navegacion--barra {
    border-top: 0;
    background: var(--c-barra-marca);
    backdrop-filter: none;
  }

  .navegacion--barra .navegacion__item { color: var(--c-barra-marca-texto); }

  .navegacion--barra .navegacion__item[aria-current="page"] {
    color: var(--c-barra-marca-texto);
    font-weight: var(--p-semibold);
    box-shadow: inset 0 3px 0 var(--c-barra-marca-texto);
  }

  .saldo-residente .cifra { font-size: var(--t-3xl); }

  .saldo-residente .cifra > span {
    font-size: inherit;
    font-weight: inherit;
    color: inherit;
  }

  .saldo-residente__datos {
    padding-bottom: var(--s-5);
    border-bottom: 1px solid var(--c-borde);
  }

  .saldo-residente .boton {
    align-self: stretch;
    justify-content: center;
  }
}

/* La etiqueta de estado del saldo, solida en naranja de marca en todos los
   anchos: el portal se lee igual en el telefono y en la computadora. */
.saldo-residente .etiqueta--critica,
.saldo-residente .etiqueta--atencion {
  background: var(--c-etiqueta-marca);
  color: var(--c-etiqueta-marca-texto);
  font-weight: var(--p-semibold);
}

.saldo-residente .etiqueta--critica::before,
.saldo-residente .etiqueta--atencion::before { display: none; }

/* Cabecera de marca en la lateral de escritorio (2026-10-20): el campo de
   bandas del isotipo, igual que en la lateral del panel. La lateral roja
   entera se probo y cansaba; esto da la paleta sin pintar toda la columna.
   Desde 64rem, donde la lateral es columna. */
@media (min-width: 64rem) {
  .app--portal .navegacion--lateral::before {
    content: "";
    flex: none;
    height: 4.5rem;
    margin: calc(var(--s-4) * -1) calc(var(--s-3) * -1) 0;
    background: url("../img/apto-logo.afd3d5f30551.svg") center 35% / cover no-repeat;
  }
}

/* Sin rotulos en mayusculas en el portal (regla del sistema): el
   sobretitulo del panel las usa; aqui se lee en caja normal. */
.sobretitulo { text-transform: none; letter-spacing: normal; }

/* Hilo de un reporte: lo que escribio la persona se distingue de la respuesta. */
.lista__item--propio { background: var(--c-acento-suave); border-radius: var(--r-md); }

/* Numero de cuenta para depositar: en su propio renglon y sin partirse. */
.cuenta-deposito__numero { font-variant-numeric: tabular-nums; font-weight: var(--p-semibold); white-space: nowrap; }

/* Asambleas: barras de resultado a todo el ancho de la tarjeta, con el acento. */
.asamblea-barra { width: 100%; height: 0.5rem; border: 0; border-radius: var(--r-full); background: var(--c-fondo-sutil); accent-color: var(--c-acento-solido); }
.asamblea-barra::-webkit-progress-bar { background: var(--c-fondo-sutil); border-radius: var(--r-full); }
.asamblea-barra::-webkit-progress-value { background: var(--c-acento-solido); border-radius: var(--r-full); }
.asamblea-barra::-moz-progress-bar { background: var(--c-acento-solido); border-radius: var(--r-full); }
/* Opciones de voto y de asistencia: una por renglón, con área de toque de 44 px. */
.asamblea-opcion { display: flex; align-items: center; gap: var(--s-3); min-height: 2.75rem; padding: var(--s-2) var(--s-3); border: 1px solid var(--c-borde); border-radius: var(--r-md); cursor: pointer; }
.asamblea-opcion + .asamblea-opcion { margin-top: var(--s-2); }
.asamblea-opcion:has(input:checked) { border-color: var(--c-acento-solido); background: var(--c-fondo-sutil); }
.asamblea-opcion input { margin: 0; width: 1.125rem; height: 1.125rem; accent-color: var(--c-acento-solido); }

/* ==========================================================================
   Arquitectura de informacion del portal (auditoria UX, 2026-10-21).
   Solo tokens. Leyes citadas en `docs/03-decisiones.md` «Portal: Comunidad».
   ========================================================================== */

/* --- Item activo de la barra del telefono (H8) ----------------------------
   Pildora blanca detras del icono, con el icono en el rojo de la barra: forma
   + color, no solo grosor (Von Restorff, WCAG 1.4.1). Rojo sobre blanco da
   4.9:1 (> 3:1 de un objeto grafico) y el texto sigue blanco sobre rojo. Todos
   los iconos llevan la misma caja para que marcar uno no mueva los demas. */
@media (max-width: 47.99rem) {
  .navegacion--barra .navegacion__icono {
    box-sizing: content-box;
    padding: var(--s-1) var(--s-4);
    border-radius: var(--r-full);
    transition: background var(--transicion), color var(--transicion);
  }

  .navegacion--barra .navegacion__item[aria-current="page"] { box-shadow: none; }

  .navegacion--barra .navegacion__item[aria-current="page"] .navegacion__icono {
    background: var(--c-barra-marca-texto);
    color: var(--c-barra-marca);
  }
}

/* Contador de la lateral (avisos del condominio nuevos en Comunidad). */
.navegacion__contador {
  display: inline-grid;
  place-items: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 var(--s-1);
  border-radius: var(--r-full);
  background: var(--c-acento-solido);
  color: var(--c-acento-solido-texto);
  font-size: var(--t-xs);
  font-weight: var(--p-semibold);
  font-variant-numeric: tabular-nums;
}

.navegacion__contador { margin-left: auto; }

.punto-aviso {
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--r-full);
  background: var(--c-atencion-punto);
}

/* Sub-pestanas (Reglas | Documentos dentro de Reglamento): control segmentado,
   un escalon menos que las de Comunidad (jerarquia visual) y distinto de los
   botones de categoria que vienen debajo (similitud: lo que se ve igual
   deberia hacer lo mismo). */
.pestanas--sub {
  display: inline-flex;
  align-self: flex-start;
  gap: 2px;
  padding: 3px;
  border: 0;
  border-radius: var(--r-md);
  background: var(--c-fondo-sutil);
  box-shadow: inset 0 0 0 1px var(--c-borde-tabla);
}
.pestanas--sub .pestanas__item {
  min-height: 2.25rem;
  padding: var(--s-1) var(--s-4);
  border: 0;
  border-radius: calc(var(--r-md) - 2px);
  margin: 0;
  font-size: var(--t-sm);
}
.pestanas--sub .pestanas__item[aria-current="page"] {
  background: var(--c-fondo-elevado);
  box-shadow: var(--sombra-sutil);
  font-weight: var(--p-semibold);
}

/* --- Menu de la cuenta: la pantalla actual es de la cuenta ----------------- */
.menu-cuenta > summary.menu-cuenta--activo { background: var(--c-acento-suave); box-shadow: inset 0 0 0 1px var(--c-acento); }
.menu-cuenta__item[aria-current="page"] { font-weight: var(--p-semibold); box-shadow: inset 3px 0 0 var(--c-acento); }

/* --- Inicio: atajos con verbo (H6, H7) --------------------------------------
   Tres tarjetas iguales en fila. Con la cuenta al dia, «Invitar visita» va en
   el solido de acento: es la unica primaria de la pantalla. */
.atajos-inicio { display: grid; align-content: start; gap: var(--s-4); }
.atajos-inicio .visitas-frecuentes { padding-top: var(--s-3); }

.atajos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 6rem), 1fr));
  gap: var(--s-3);
}

.atajo {
  display: grid;
  place-items: center;
  align-content: center;
  gap: var(--s-2);
  min-height: 5.5rem;
  padding: var(--s-3) var(--s-2);
  border: 1px solid var(--c-borde-tabla);
  border-radius: var(--r-lg);
  background: var(--c-fondo-elevado);
  color: var(--c-texto);
  font-size: var(--t-sm);
  font-weight: var(--p-semibold);
  line-height: var(--l-ajustado);
  text-align: center;
  text-decoration: none;
  transition: border-color var(--transicion), box-shadow var(--transicion);
}

.atajo:hover { border-color: var(--c-borde); box-shadow: var(--sombra-sutil); }
.atajo__icono { width: var(--s-6); height: var(--s-6); color: var(--c-acento); }

.atajo--primario {
  border-color: var(--c-acento-solido);
  background: var(--c-acento-solido);
  color: var(--c-acento-solido-texto);
}
.atajo--primario:hover { background: var(--c-acento-solido-hover); }
.atajo--primario .atajo__icono { color: inherit; }

@media (max-width: 47.99rem) {
  /* Fitts: los atajos tienen que verse sin rodar en un telefono de 844px, con
     la barra de abajo encima. Se le quita aire a la tarjeta del saldo, no
     informacion. */
  .saldo-residente { padding: var(--s-5); }
  .portal-saldo-label { margin-top: var(--s-3); }
  .saldo-residente__cifra { margin-bottom: var(--s-4); }
  .saldo-residente__datos { gap: var(--s-3); padding-bottom: var(--s-4); }
  .saldo-residente .boton { margin-top: var(--s-4); }
  .atajo { min-height: 5rem; }

  /* H14: el nombre del condominio no se corta en «Condominio …»: hasta dos
     renglones, y el resto se recorta al final del segundo. */
  .encabezado__marca > span {
    display: -webkit-box;
    white-space: normal;
    line-height: var(--l-ajustado);
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
  }
}


/* Menu de la cuenta: quien es arriba, iconos que se reconocen sin leer, y
   salir en su propio grupo. */
.menu-cuenta__persona {
  display: grid;
  gap: 2px;
  margin: 0 0 var(--s-2);
  padding: var(--s-2) var(--s-3) var(--s-3);
  border-bottom: 1px solid var(--c-borde);
  font-size: var(--t-sm);
}
.menu-cuenta__persona span { color: var(--c-texto-secundario); font-size: var(--t-xs); }
.menu-cuenta__item--icono { justify-content: flex-start; }
.menu-cuenta__icono { width: 1.125rem; height: 1.125rem; flex: none; color: var(--c-texto-terciario); }
.menu-cuenta__item[aria-current="page"] .menu-cuenta__icono { color: var(--c-acento); }

/* Accesos rapidos: el titulo solo donde sobra alto. En el telefono lo que
   importa es que los tres atajos entren en la primera pantalla (Fitts). */
.atajos-inicio__titulo { margin: 0; font-size: var(--t-base); font-weight: var(--p-semibold); }
@media (max-width: 47.99rem) {
  .atajos-inicio__titulo {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* Escritorio: los atajos en su propia tarjeta, a la altura de la del saldo
   (region comun); con el fondo suave de acento que tenia la de visitas. */
@media (min-width: 64rem) {
  .atajos-inicio {
    padding: var(--s-6);
    border: 1px solid var(--c-borde-tabla);
    border-radius: var(--r-lg);
    background: var(--c-acento-suave);
  }
  .atajos-inicio .atajo { min-height: 6.5rem; }
}

/* ==========================================================================
   Sistema de espaciado y rejilla del portal (pulido, 2026-10-21).

   Pedido del dueno viendo el portal a 1440 y 1920 px: «todo esta muy pegado»
   y las filas de Inicio no alineaban. Tres espacios con nombre, sacados de la
   escala `--s-*` de tokens.css (no son valores nuevos, son decisiones):

     --s-rejilla  hueco entre tarjetas, el MISMO en horizontal y en vertical
                  (region comun: lo que esta a la misma distancia se lee como
                  un grupo; con 0 px entre filas, dos filas eran una mancha).
     --s-seccion  ritmo vertical entre bloques de una pantalla (encabezado,
                  pestanas, grupos): un escalon mas que la rejilla, para que
                  separar secciones pese mas que separar tarjetas (proximidad).
     --s-pagina   margen lateral del contenido, el mismo para la barra de
                  arriba, el contenido y el pie (todo arranca en la misma
                  linea izquierda).

   La rejilla es de 12 columnas desde 80rem (donde caben dos columnas de
   tarjetas): Inicio corta en 7 + 5, Pagos y Reservas en 5 + 7, las mitades en
   6 + 6 y los formularios en 7 + 5. Todas las pantallas cortan en lineas de la
   misma rejilla (similitud; Jakob: el panel usa el mismo criterio).
   Solo tokens.
   ========================================================================== */
.app--portal {
  --s-rejilla: var(--s-4);
  --s-seccion: var(--s-6);
  --s-pagina: var(--s-5);
}

@media (min-width: 48rem) {
  .app--portal { --s-rejilla: var(--s-6); --s-seccion: var(--s-8); --s-pagina: var(--s-6); }
}

@media (min-width: 64rem) {
  .app--portal { --s-pagina: var(--s-10); }
}

/* Margenes de pagina: contenido, barra de arriba y pie en la misma linea. */
.app--portal .contenido { padding: var(--s-seccion) var(--s-pagina) var(--s-16); }
.app--portal .encabezado { padding-inline: var(--s-pagina); }
@media (min-width: 48rem) {
  .app--portal .contenido { padding-bottom: var(--s-12); }
  .app--portal .portal-cabecera,
  .app--portal .portal__principal > .pie { padding-inline: var(--s-pagina); }
}

/* Ritmo vertical: entre bloques, `--s-seccion`; entre tarjetas apiladas de
   un mismo grupo, `--s-rejilla` (lo mismo que las separa de lado). */
.app--portal .pila-lg > * + * { margin-top: var(--s-seccion); }
.app--portal :is(.pila, .pila-lg) > .tarjeta + .tarjeta { margin-top: var(--s-rejilla); }
.app--portal .contenido > .mb-6,
.app--portal .contenido > .resumen-encabezado { margin-bottom: var(--s-seccion); }
.portal-bienvenida .titulo { margin: 0; }

/* --- Inicio: una sola rejilla para las dos filas --------------------------
   Saldo + atajos arriba y avisos + reserva abajo cortan en la misma linea
   (7 + 5) y llevan el mismo hueco entre filas que entre columnas. Entre 48 y
   80rem (tableta, y escritorio de 1024 con la lateral) los atajos no caben a
   5/12 —se partian en 2 + 1—, asi que saldo y atajos van a lo ancho y solo
   avisos + reserva se reparten. */
.portal-inicio {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--s-rejilla);
}

.portal-inicio > * { grid-column: 1 / -1; min-width: 0; }

@media (min-width: 48rem) {
  .portal-inicio > .portal-inicio__avisos { grid-column: span 7; }
  .portal-inicio > .portal-inicio__reserva { grid-column: span 5; }
}

@media (min-width: 80rem) {
  .portal-inicio > .saldo-residente { grid-column: span 7; }
  .portal-inicio > .atajos-inicio { grid-column: span 5; }
}

/* Lo que falta no deja hueco: sin reserva, avisos a lo ancho; sin atajos (los
   tres modulos apagados), el saldo a lo ancho. */
.portal-inicio > .portal-inicio__avisos:last-child,
.portal-inicio > .saldo-residente:has(+ .portal-inicio__avisos) { grid-column: 1 / -1; }

/* La reserva se estira al alto de Avisos: en vez de un hueco blanco abajo, el
   enlace ocupa la tarjeta entera (Fitts: objetivo mas grande) y la escena de
   reservas cierra la tarjeta abajo a la derecha (estetica-usabilidad). */
.portal-inicio__reserva { display: flex; flex-direction: column; }
.portal-inicio__reserva .portal-reserva { display: flex; flex: 1; flex-direction: column; align-items: flex-start; }
.portal-reserva__dibujo { display: none; }

@media (min-width: 48rem) {
  .portal-reserva .portal-reserva__dibujo { display: block; align-self: flex-end; width: 8rem; height: auto; margin: auto 0 0; }
}

/* --- Jerarquia tipografica del portal --------------------------------------
   Cuatro escalones y nada mas (jerarquia visual):
     titulo de pantalla   h1, --t-2xl, fuente de marca
     titulo de contenido  el nombre de un aviso, una regla, un area: --t-lg
     titulo de tarjeta    lo que dice que es la caja («Mis pagos», «Total
                          pendiente», «Cuentas para depositar»): --t-base
     rotulo de seccion    fuera de las tarjetas («Mis invitaciones»): --t-sm
                          secundario. Ninguno en mayusculas.
   Antes el mismo papel salia a 14, 16, 18 y 22 px segun la pantalla. */
.app--portal .tarjeta > h2:first-child,
.app--portal .tarjeta > .seccion-titulo:first-child,
.app--portal .portal-seccion h2,
.app--portal .atajos-inicio__titulo {
  margin: 0;
  color: var(--c-texto);
  font-size: var(--t-base);
  font-weight: var(--p-semibold);
  line-height: var(--l-ajustado);
  letter-spacing: normal;
}

.app--portal .contenido .subtitulo,
.app--portal .regla h3 { font-size: var(--t-lg); }

.app--portal .seccion-titulo { margin-bottom: var(--s-3); text-transform: none; }

/* Titulo de tarjeta y lo que sigue: el mismo aire en todas (antes «Invitar de
   nuevo» y «Cuentas para depositar» quedaban pegados a su contenido). */
.app--portal .tarjeta.pila-sm > :first-child + * { margin-top: var(--s-3); }

/* --- Lateral --------------------------------------------------------------
   El ancho de la lateral del panel (Jakob). */
@media (min-width: 64rem) {
  .app--portal .navegacion--lateral { width: 17rem; }
}

/* --- Pestanas sin barra de desplazamiento ----------------------------------
   `overflow-x: auto` vuelve `auto` tambien el eje vertical, y el borde activo
   (margin-bottom: -1px) desbordaba un pixel: aparecian las flechitas de una
   barra vertical a la derecha de las pestanas. En el telefono siguen rodando
   de lado, sin barra visible. */
.pestanas { overflow-y: hidden; scrollbar-width: none; }
.pestanas::-webkit-scrollbar { display: none; }
.app--portal .pestanas--sub { margin-top: var(--s-4); }

/* --- Tarjetas en rejilla (Avisos, Reglamento) ------------------------------
   Una columna en el telefono y la tableta; dos desde 80rem. Cada tarjeta
   conserva una medida de lectura comoda (~70 caracteres) y la pantalla no
   queda con la mitad derecha vacia ni con una linea de 1,500 px. */
.portal-tarjetas { display: grid; gap: var(--s-rejilla); align-items: start; }
.app--portal .portal-tarjetas > * { min-width: 0; margin: 0; }

@media (min-width: 80rem) {
  .portal-tarjetas { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.app--portal .reglas-residente { max-width: none; }
.reglas-indice .chip { min-height: 2.25rem; padding-block: var(--s-1); }
@media (max-width: 47.99rem) {
  .reglas-indice .chip { min-height: var(--alto-toque); }
}

/* --- Formularios con columna de ayuda (`.portal-formulario`) ---------------
   Desde 80rem el formulario ocupa 7 de 12 columnas (campos de ~650 px, no de
   1,500) y a su derecha va lo que la persona quiere saber antes de enviar:
   que pasa despues, como funciona, la emergencia. En el telefono la ayuda va
   despues del formulario (revelacion progresiva), salvo la emergencia, que
   sigue antes. Abajo de 80rem es la columna de lectura de siempre. */
.app--portal .portal-ayuda { background: var(--c-fondo-sutil); box-shadow: none; }
.portal-ayuda > h2 + * { margin-top: var(--s-3); }
.portal-ayuda__pasos {
  display: grid;
  gap: var(--s-3);
  margin: 0;
  padding-left: var(--s-5);
  color: var(--c-texto-secundario);
  font-size: var(--t-sm);
  line-height: var(--l-normal);
}
.portal-ayuda__pasos li::marker { color: var(--c-acento); font-weight: var(--p-semibold); }

@media (min-width: 80rem) {
  .app--portal .contenido > .portal-formulario {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    /* La ultima fila es flexible: el formulario abarca las filas 2 y 3, y su
       alto sobrante cae en la 3 en vez de separar la emergencia de la ayuda. */
    grid-template-rows: auto auto 1fr;
    gap: var(--s-rejilla);
    align-items: start;
    max-width: 90rem;
  }

  .app--portal .portal-formulario > * { grid-column: 1 / -1; }
  .app--portal .portal-formulario > * + * { margin-top: 0; }
  .app--portal .portal-formulario > form { grid-column: 1 / span 7; grid-row: 2 / span 2; }
  .app--portal .portal-formulario > :is(.aviso, .portal-ayuda) { grid-column: 8 / -1; }

  /* Las pantallas de lectura sin columna de ayuda (perfil, preferencias,
     privacidad, contrasena, detalles) se centran en el area de trabajo en vez
     de quedar a la izquierda con la otra mitad vacia. */
  .app--portal .contenido > .portal__lectura:not(.portal-formulario) { margin-inline: auto; }
}

/* --- Campo de archivo como zona de soltar (`campo_archivo.html`) -----------
   El input real queda adentro, visible y enfocable; la zona es lo que se
   arrastra y se toca (Fitts). Borde punteado que toma el acento al pasar. */
.zona-archivo {
  display: grid;
  justify-items: center;
  gap: var(--s-2);
  padding: var(--s-6) var(--s-4);
  border: 1.5px dashed var(--c-borde-fuerte);
  border-radius: var(--r-lg);
  background: var(--c-fondo-sutil);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--transicion), background var(--transicion);
}

.zona-archivo:hover,
.zona-archivo--encima { border-color: var(--c-acento); background: var(--c-acento-suave); }
.zona-archivo:focus-within { border-color: var(--c-acento); }
.zona-archivo__icono { width: var(--s-8); height: var(--s-8); color: var(--c-acento); }
.zona-archivo__texto { margin: 0; color: var(--c-texto-secundario); font-size: var(--t-sm); }

.app--portal .zona-archivo input[type="file"] {
  max-width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--c-texto-secundario);
  font-size: var(--t-sm);
}

.app--portal .zona-archivo input[type="file"]::file-selector-button {
  min-height: var(--alto-toque);
  margin-right: var(--s-3);
  padding: var(--s-2) var(--s-4);
  border: 1px solid var(--c-acento-solido);
  border-radius: var(--r-md);
  background: var(--c-fondo-elevado);
  color: var(--c-acento);
  font: inherit;
  font-weight: var(--p-semibold);
  cursor: pointer;
}

@media (hover: none) {
  .zona-archivo__arrastre { display: none; }
}

/* ==========================================================================
   Comunidad como portada (auditoria UX 2026-10-21): reemplaza la tira de
   pestanas. Solo tokens.
   ========================================================================== */

/* «← Comunidad»: la unica salida hacia arriba de cada seccion. */
.volver-comunidad { padding-inline: 0; }

/* Tarjeta de la asamblea / votacion abierta: lo unico con acento en la
   pantalla (Von Restorff). Con votacion abierta, el borde se engrosa. */
.asamblea-destacada {
  display: grid;
  gap: var(--s-4);
  padding: var(--s-5);
  border: 1px solid var(--c-acento);
  border-radius: var(--r-lg);
  background: var(--c-acento-suave);
}
.asamblea-destacada--voto { border-width: 2px; }
.asamblea-destacada__cuerpo { display: grid; gap: var(--s-2); min-width: 0; }
.asamblea-destacada__cuerpo > * { margin: 0; }
.asamblea-destacada__rotulo {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  color: var(--c-acento);
  font-size: var(--t-sm);
  font-weight: var(--p-semibold);
}
.asamblea-destacada__icono { width: 1.125rem; height: 1.125rem; flex: none; }
.asamblea-destacada__accion { justify-self: stretch; }
@media (min-width: 48rem) {
  .asamblea-destacada { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
  .asamblea-destacada__accion { justify-self: end; min-width: 11rem; }
}

/* Portada: en el telefono, secciones y despues avisos (las tres secciones en
   la primera pantalla); desde 64rem, avisos a la izquierda y secciones a la
   derecha, en la rejilla del portal. */
.comunidad-portada { display: grid; gap: var(--s-8); align-items: start; }
.comunidad-portada > * { min-width: 0; }
@media (min-width: 64rem) {
  .comunidad-portada {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    grid-template-areas: "avisos secciones";
    gap: var(--s-rejilla);
  }
  .comunidad-portada__avisos { grid-area: avisos; }
  .comunidad-portada__secciones { grid-area: secciones; }
}

.portal__principal .comunidad-seccion { flex-wrap: nowrap; justify-content: flex-start; color: var(--c-texto); min-height: 4rem; }
.comunidad-seccion > .etiqueta,
.comunidad-seccion > .punto-aviso { margin-left: auto; flex: none; }
.comunidad-seccion__icono { width: var(--s-6); height: var(--s-6); flex: none; color: var(--c-acento); }
.comunidad-seccion__texto { display: grid; gap: 2px; min-width: 0; }
.comunidad-portada__avisos .lista__item { color: var(--c-texto); }

/* Punto de novedad sobre Comunidad en la navegacion. En la barra roja del
   telefono va blanco con aro del rojo de la barra: se ve sobre el rojo y
   sobre la pildora blanca del item activo. */
.navegacion__item { position: relative; }
.navegacion__punto {
  width: 0.625rem;
  height: 0.625rem;
  flex: none;
  border-radius: var(--r-full);
  background: var(--c-atencion-punto);
}
.navegacion--lateral .navegacion__contador + .navegacion__punto { margin-left: 0; }
.navegacion--lateral .navegacion__punto:first-of-type { margin-left: auto; }
@media (max-width: 47.99rem) {
  .navegacion--barra .navegacion__punto {
    position: absolute;
    top: var(--s-1);
    left: calc(50% + 0.5rem);
    background: var(--c-barra-marca-texto);
    box-shadow: 0 0 0 2px var(--c-barra-marca);
  }
}

/* Lateral del portal en tableta: alto de dedo, no de raton. */
@media (min-width: 48rem) {
  .app--portal .navegacion--lateral .navegacion__item { min-height: var(--alto-toque); }
}

/* Reglas | Documentos: alto de dedo (era 36 px); la tableta tambien es tactil. */
.pestanas--sub .pestanas__item { min-height: var(--alto-toque); }

/* Boleta: una pregunta, a medida de lectura. */
.boleta { max-width: var(--ancho-contenido); }
.boleta__paso legend { display: grid; gap: var(--s-1); margin-bottom: var(--s-3); padding: 0; }
.boleta__pregunta { font-size: var(--t-lg); }
.boleta__paso fieldset { margin: 0; padding: 0; border: 0; }
.boleta__listo { text-align: left; }

/* Notificaciones: mensaje a la izquierda, a donde lleva a la derecha. */
.notificacion { align-items: flex-start; }
.notificacion .pila-sm > * { margin: 0; }
.notificacion .pila-sm > * + * { margin-top: var(--s-1); }
@media (max-width: 47.99rem) {
  .notificacion { flex-direction: column; align-items: stretch; }
}
