/* nexel/www — capa de escritorio.
 *
 * Se carga SÓLO cuando `appVista()` devuelve 'escritorio' (ver
 * lib/chrome.php), después de app.css. Todo va scopeado bajo
 * `.vista-escritorio` para que no pueda tocar la vista móvil ni por
 * accidente, y para que en el celular ni siquiera se descargue.
 *
 * El HTML del contenido es idéntico en las dos vistas — acá sólo se
 * cambia cómo se acomoda. Lo único que no existe en escritorio es la
 * barra flotante inferior, y eso no se resuelve con display:none: el
 * chrome directamente no la renderiza.
 */

/* --------- anchos --------- */

/* `--inset` es el que hace que las barras (topnav, header) lleguen de
 * borde a borde pero su contenido quede alineado con el de las tarjetas:
 * el padding lateral crece hasta centrar una franja de `--ancho`, y nunca
 * baja de `--gutter` en ventanas angostas. Evita tener que envolver el
 * contenido de cada barra en un div contenedor. */
.vista-escritorio {
  --ancho:  1180px;
  --gutter: 24px;
  --inset:  max(var(--gutter), calc((100% - var(--ancho)) / 2));
  /* Alto de la barra de navegación. Va en variable porque el tirador se
   * cuelga de su borde inferior con `top`: si el número viviera suelto en
   * dos reglas, tocar una y no la otra dejaría la lengüeta flotando. */
  --topnav-h: 66px;
}

/* --------- shell --------- */

/* En escritorio el shell ocupa todo el ancho del viewport. El marco
 * redondeado con sombra que app.css aplica a partir de 640px es un
 * recurso de la vista móvil — sirve para simular un teléfono flotando
 * sobre el fondo, no para un portal de escritorio, donde el chrome tiene
 * que ir a sangre.
 *
 * `overflow: visible` además habilita el `position: sticky` de la topnav:
 * el `overflow: hidden` de app.css lo rompía. */
body.vista-escritorio { padding: 0; }

.vista-escritorio .app-shell,
.vista-escritorio .app-shell.page-listado,
.vista-escritorio .app-shell.page-detalle {
  max-width: none;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
  min-height: 100vh;
  padding-bottom: 40px;
}

/* --------- barra de navegación superior --------- */

.app-topnav {
  display: flex;
  align-items: center;
  gap: 26px;
  height: var(--topnav-h);
  padding-inline: var(--inset);
  /* Alto de las pastillas de navegación. Antes salía del padding + la
   * caja de línea del texto, o sea que dependía de la métrica de Poppins.
   * Va explícito porque el logo lo comparte: los dos tienen que medir lo
   * mismo, y una medida derivada no se puede copiar sin que se
   * desincronicen en cuanto alguien toque el font-size. */
  --pastilla: 38px;
  /* La barra de navegación es la que lleva el azul de marca en
   * escritorio; el header de abajo queda gris. En móvil es al revés (no
   * hay topnav y el color vive en el header), así que todo esto es
   * exclusivo de esta capa. */
  background: var(--primario);
  position: sticky;
  top: 0;
  z-index: 60;
  /* La barra queda fija al scrollear: la sombra la despega del contenido
   * que le pasa por debajo. Sin esto, al scrollear las cards se cortan
   * contra un borde plano y parece que se recortan solas. */
  box-shadow: 0 2px 12px rgba(16, 22, 54, .18),
              0 1px 3px  rgba(16, 22, 54, .10);
}

/* El logo es un PNG blanco (el mismo que usa cloud en su chrome oscuro),
 * así que depende de que la barra siga siendo azul: sobre fondo claro
 * quedaría invisible. */
.app-topnav-brand {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}
/* El logo va más bajo que la pastilla de "Inicio": a la par se comía la
 * barra. El PNG está recortado al dibujo (sin margen transparente), así que
 * su alto de caja es también su alto visible — el número de acá es lo que
 * se ve, no hay aire que descontar. Se achica sólo por CSS: la imagen no se
 * toca, y el `width: auto` mantiene la proporción. Centrado contra las
 * pastillas por el `align-items: center` de la barra. */
.app-topnav-brand img {
  height: 26px;
  width: auto;
  display: block;
}

.app-topnav-items {
  display: flex;
  gap: 4px;
  flex: 1;
  min-width: 0;
}

.app-topnav-item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: var(--pastilla);
  padding-inline: 16px;
  border-radius: 99px;
  font-size: 0.88rem;
  font-weight: 600;
  color: rgba(255, 255, 255, .8);
  white-space: nowrap;
  transition: background .15s, color .15s;
}
.app-topnav-item i { font-size: 0.95rem; }
.app-topnav-item:hover { background: rgba(255, 255, 255, .15); color: #fff; }
/* El último ítem del grupo es un <button> y no un link: no navega, abre el
 * chat de Nexo (ver lib/topnav.php). El navegador le pone fondo, borde y
 * su propia tipografía, así que la pastilla necesita el reset para salir
 * idéntica a las cuatro de al lado — mismo detalle que el último slot de
 * la barra de abajo en móvil (`.app-nav-item` en app.css). */
.app-topnav-nexo {
  background: none;
  border: none;
  font-family: inherit;
  cursor: pointer;
}
/* Sobre fondo azul el activo se invierte: pastilla blanca con texto azul.
 * Pintarlo de azul como antes lo haría desaparecer contra la barra. */
.app-topnav-item.active { background: #fff; color: var(--primario); }

/* Botón de menú: alineado a la derecha, separado del bloque de
 * navegación. Abre el cajón de apps (ver lib/topnav.php).
 *
 * Heredó la pastilla del ítem de cuenta que ocupaba este lugar, y se queda
 * con la variante BLANCA fija —la que allá aparecía sólo con sesión—
 * porque ahora es la única acción de la esquina y tiene que leerse como
 * tal contra el azul, esté quien esté navegando.
 *
 * Es un <button> y no un link: no navega, abre un modal. De ahí el reset,
 * el mismo que necesita `.app-topnav-nexo`. */
.app-topnav-menu {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  height: var(--pastilla);
  padding-inline: 16px;
  border: none;
  border-radius: 99px;
  font-family: inherit;
  font-size: .86rem;
  font-weight: 600;
  cursor: pointer;
  background: #fff;
  color: var(--primario);
  white-space: nowrap;
  transition: background .15s, color .15s;
}
.app-topnav-menu:hover { background: var(--acento-soft); color: var(--acento); }

/* Buscador de la barra (ver lib/topnav.php). Es la MISMA pastilla que el
 * botón de menú —mismo alto, mismo radio de 99px, mismo blanco— porque
 * comparten renglón y cualquier otra forma se leería como una pieza pegada
 * de otro lado. La lupa va adentro, así que la caja no tiene nada colgando
 * por fuera. */
.app-topnav-buscar {
  display: flex;
  align-items: center;
  gap: 6px;
  /* El único que puede ceder ancho cuando la ventana se angosta: las
   * pastillas de navegación son `white-space: nowrap` y su grupo tiene
   * `flex: 1` (o sea base 0, que no encoge). De ahí el `shrink: 1` con base
   * propia y un piso para que no se vuelva un campo de dos letras. */
  flex: 0 1 320px;
  min-width: 150px;
  height: var(--pastilla);
  padding-left: 16px;
  /* Menos aire del lado de la lupa: el botón ya trae el suyo, y con los 16
   * de la izquierda quedaba despegado del borde derecho. */
  padding-right: 5px;
  background: #fff;
  border-radius: 99px;
}
.app-topnav-buscar input {
  flex: 1;
  /* Mismo motivo que en `.app-search-card` (app.css): sin esto el ancho
   * mínimo automático de un <input> —unos 20 caracteres— le gana al
   * `flex: 1` y la pastilla no baja de ahí. */
  min-width: 0;
  border: none;
  outline: none;
  background: none;
  font-family: inherit;
  font-size: .88rem;
  color: var(--text);
  /* `type="search"` trae de fábrica la crucecita de limpiar y el redondeo
   * propio de WebKit. Se apagan los dos: el único control de la caja es la
   * lupa. El `type` se mantiene igual porque es lo que hace que Escape
   * limpie el campo y que los lectores de pantalla lo anuncien como
   * búsqueda. */
  appearance: none;
  -webkit-appearance: none;
}
.app-topnav-buscar input::-webkit-search-cancel-button { display: none; }
.app-topnav-buscar input::placeholder { color: #a3a9c4; }
/* Redondo y sin fondo: adentro de la pastilla blanca, un botón con caja
 * propia la partiría en dos. El color sale del azul de marca, que contra el
 * blanco es lo único que lo despega del texto tipeado. */
.app-topnav-buscar button {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border: none;
  border-radius: 99px;
  background: none;
  color: var(--primario);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: .95rem;
  cursor: pointer;
  transition: background .15s, color .15s;
}
.app-topnav-buscar button:hover { background: var(--acento-soft); color: var(--acento); }

/* --------- header --------- */

/* En escritorio el header no existe: la identidad y la navegación ya las
 * lleva la barra de arriba, y la búsqueda pasó a resolverse dentro del
 * panel de filtros. Al desaparecer, `.app-topstack` queda pegado a la
 * barra azul — y con él el ancla del panel y el tirador, que así caen
 * exactamente sobre su borde inferior sin necesidad de reposicionarlos. */
.vista-escritorio .app-header { display: none; }

/* La pila viaja pegada a la barra de navegación, que es sticky: el tirador
 * es una lengüeta de esa barra y tiene que seguir colgando de ella todo el
 * scroll, no irse con el contenido. Pegándola acá van juntos también el
 * ancla y el panel, que cuelga de ella en absoluto — si sólo se fijara el
 * tirador, abrir los filtros y scrollear los separaría.
 *
 * `sticky` y no `fixed`: con `top: var(--topnav-h)` la posición pegada es
 * exactamente la que ya tiene en el flujo (la barra es el primer hijo del
 * shell), así no hay salto al empezar a scrollear ni hay que devolverle el
 * alto al contenido como en móvil. Funciona porque el `overflow: hidden`
 * de `.app-shell` — que es lo que rompía sticky en móvil — acá está en
 * `visible` (ver más arriba).
 *
 * z-index 50: por debajo de `.app-topnav` (60), así la barra le pasa por
 * delante y el panel sigue metiéndose por detrás. Crea contexto de apilado,
 * o sea que el 30 del tirador y el 10 del ancla quedan encerrados acá
 * adentro — su orden relativo se mantiene y ninguno puede treparse a la
 * barra.
 *
 * La cabecera auto-ocultable sigue siendo de móvil: `cabecera.js` chequea
 * `position: fixed` antes de enganchar nada, y sticky no es fixed. */
.vista-escritorio .app-topstack {
  position: sticky;
  top: var(--topnav-h);
  z-index: 50;
  max-width: none;
  transition: none;
}

/* Escritorio no usa la grilla de tres columnas del móvil: acá el header
 * es un bloque de texto a la izquierda y las acciones a la derecha. */
.vista-escritorio .app-header-top {
  display: flex;
  justify-content: space-between;
}
.vista-escritorio .app-header-title {
  font-size: 2rem;
  color: var(--text);
}
.vista-escritorio .app-header-title .accent { color: var(--acento); }

/* Los botones circulares usaban un velo blanco translúcido sobre el azul.
 * Sobre gris hace falta el contrario: un velo oscuro. */
.vista-escritorio .app-back,
.vista-escritorio .app-icon-btn {
  background: rgba(16, 22, 54, .07);
  color: var(--text);
}
.vista-escritorio .app-back:hover,
.vista-escritorio .app-icon-btn:hover { background: rgba(16, 22, 54, .13); }
/* El punto de notificaciones se recortaba contra el azul del header. */
.vista-escritorio .app-icon-btn .dot { border-color: var(--bg); }

.vista-escritorio .app-search-card { max-width: 640px; }

/* --------- panel de filtros --------- */

/* Mismo mecanismo que en móvil (ancla + absoluto + grilla 0fr→1fr); acá
 * sólo cambian medidas y colores. Se alinea con el ancho del contenido en
 * vez de quedar a 10px del borde de la pantalla. */
.vista-escritorio .panel-filtros {
  left: var(--inset);
  right: var(--inset);
}
/* El aire de arriba tiene que dejar pasar al tirador, que cuelga 26px por
 * debajo de la barra: con estos 48 le quedan 22px de respiro antes del
 * primer filtro. */
.vista-escritorio .panel-filtros-body { padding: calc(var(--tuck) + 48px) 26px 24px; }

/* El tirador NO se toca acá: la lengüeta de app.css ya es el diseño de las
 * dos vistas. Lo único distinto es de qué borde cuelga — del header en
 * móvil, de la barra de navegación en escritorio — y eso lo resuelve la
 * posición de `.app-topstack`, no el botón.
 *
 * Un detalle que sí es de acá: la barra va en una capa por encima de la
 * pila (z 60 contra 50), así que su sombra cae sobre el nacimiento de la
 * lengüeta. Queda bien — ese degradado es lo que la hace leer como saliendo
 * de abajo de la barra — pero explica por qué acá se ve un pelín más
 * sombreada que en móvil, donde el header no tiene sombra. */

/* A 1180px de ancho, las secciones apiladas dejan un panel larguísimo con
 * una sola columna de chips. `display: contents` en el bloque de categoría
 * hace que sus secciones participen de la grilla del formulario en vez de
 * contarse como un único ítem. */
.vista-escritorio .panel-filtros-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0 30px;
  align-items: start;
}
.vista-escritorio .panel-filtros-form > [data-cat] { display: contents; }
/* Las dos acciones ocupan la última fila entera y se alinean a la
 * derecha, en línea: acá sobra ancho y apilarlas dejaría media pantalla
 * vacía al lado. El alternador va a la IZQUIERDA del envío, que es donde
 * el orden de lectura pone lo secundario antes de la salida. */
.vista-escritorio .panel-filtros-acciones {
  grid-column: 1 / -1;
  justify-self: end;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 10px;
}
.vista-escritorio .panel-filtros-submit {
  width: auto;
  min-width: 240px;
}
.vista-escritorio .panel-filtros-vista {
  width: auto;
  min-width: 180px;
}

/* --------- secciones --------- */

.vista-escritorio .app-section { padding: 26px var(--inset) 6px; }
.vista-escritorio .app-section-title { font-size: 1.2rem; margin-bottom: 16px; }
.vista-escritorio .app-section-title .link { font-size: 0.85rem; }

/* Los tiles ya no son una sección suelta: viven dentro del panel de
 * filtros, que en app.css les saca fondo, sombra y padding. La regla que
 * había acá les devolvía el padding (misma especificidad, archivo más
 * tardío) y rompía ese reset. Sólo queda el centrado, que en un panel de
 * 1180px sí hace falta. */
.vista-escritorio .tiles-row { justify-content: center; }

.vista-escritorio .app-chip-row {
  padding: 16px var(--inset) 4px;
  flex-wrap: wrap;
  overflow-x: visible;
}
.vista-escritorio .list-toolbar { padding: 16px var(--inset) 4px; }
.vista-escritorio .cta-panel { margin: 26px var(--inset) 4px; }

/* --------- LA grilla de avisos ---------
 * Es el cambio central de la vista: la misma lista de cards que en móvil
 * se apila en una columna, acá se acomoda en tantas columnas como entren.
 * `auto-fill` + `minmax` hace que se reajuste sola al ancho de la ventana
 * sin necesidad de breakpoints. */
.vista-escritorio .card-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 20px;
  padding: 0 var(--inset);
  align-items: stretch;
}
/* Dentro de una .app-section el inset lateral ya lo pone la sección. */
.vista-escritorio .app-section .card-list { padding: 0; }

/* --------- vista mapa ---------
 * Se alinea con el ancho del contenido, como el resto de la vista, y
 * puede ser más alto: acá no hay barra de navegación flotante comiéndose
 * el pie y la pantalla es apaisada, así que un mapa bajo se desperdicia.
 *
 * La tarjeta del pin no se toca: cuelga de su pin y la posiciona el JS,
 * así que no tiene una ubicación propia por vista. Acá sólo se le da un
 * poco más de ancho, que es lo que evita que el título de un aviso se
 * corte en dos líneas cuando sobra pantalla. */
.vista-escritorio .mapa-vista { margin: 0 var(--inset); }
/* Más ancha y con la foto más grande: acá sobra pantalla, y en 330px el
 * par de píldoras "ALQUILER · DEPARTAMENTO" se parte en dos renglones y el
 * título queda en tiras de cuatro palabras. Son las mismas medidas que la
 * tarjeta del mapa del back office. La foto sube sola con `--foto`, que es
 * de donde sale también el alto del cuerpo. */
.vista-escritorio .mapa-card {
  width: min(420px, calc(100% - 24px));
  --foto: 120px;
}
/* 200px = la barra de navegación + la franja de avisos + el respiro de
 * arriba y el padding del pie del shell. Con menos queda un hueco muerto
 * debajo del mapa; con más aparece scroll vertical en una página que no
 * tiene nada más abajo. */
.vista-escritorio .mapa-lienzo {
  height: calc(100vh - 200px);
  min-height: 460px;
}

/* Altura pareja por fila. `stretch` (el default de grid) ya iguala la
 * altura de las cajas blancas, pero por sí solo deja el contenido arriba
 * y un hueco abajo en las cards más cortas. Con la card en columna flex y
 * el body creciendo, la fila de metadatos se ancla al pie: los títulos
 * quedan arriba, los precios donde caigan y los metadatos alineados entre
 * sí a lo ancho de toda la fila.
 *
 * La variación de altura viene de los títulos de 1 vs. 2 líneas y de los
 * metadatos que envuelven a una segunda línea (los "Automatica"). */
.vista-escritorio .aviso-card {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.vista-escritorio .aviso-media { flex-shrink: 0; }
.vista-escritorio .aviso-body {
  flex: 1;
  display: flex;
  flex-direction: column;
}
.vista-escritorio .aviso-meta {
  margin-top: auto;
  padding-top: 6px;
}

.vista-escritorio .aviso-title { font-size: 0.98rem; }

/* --------- detalle --------- */

/* El detalle sí se mantiene angosto y centrado: una ficha de aviso a 1180px
 * de ancho se vuelve ilegible. El `min()` evita que toque los bordes en
 * ventanas de escritorio chicas. */
.vista-escritorio .detalle-card {
  width: min(940px, calc(100% - 2 * var(--gutter)));
  max-width: none;
  margin: 22px auto 0;
}

/* --------- sesión --------- */

/* Mismo criterio que el detalle: un formulario de login a todo el ancho
 * de la ventana es incómodo de leer y de completar. */
.vista-escritorio .auth-card {
  width: min(460px, calc(100% - 2 * var(--gutter)));
  margin: 30px auto 40px;
  padding: 30px 30px 26px;
}
.vista-escritorio .app-shell.page-auth { padding-bottom: 40px; }
.vista-escritorio .cuenta-grid { grid-template-columns: repeat(2, 1fr); }

/* /mi-cuenta es la única página de sesión con contenido debajo de la
 * tarjeta, así que se le da un poco más de ancho que a /ingresar: las
 * filas de actividad llevan miniatura, título, chapita y una o dos
 * líneas de texto, y en 460px el título se recorta casi siempre.
 *
 * Los dos bloques comparten el MISMO ancho a propósito: con anchos
 * distintos el borde saltaría al cambiar de sección. */
.vista-escritorio .page-cuenta .auth-card,
.vista-escritorio .cuenta-panel {
  width: min(560px, calc(100% - 2 * var(--gutter)));
  margin-inline: auto;
}
/* El aire de arriba lo daba el `padding-top` de la tira de pestañas, que
 * se eliminó el 2026-09-27: ahora lo pone el propio bloque. */
.vista-escritorio .page-cuenta .auth-card,
.vista-escritorio .cuenta-panel { margin-top: 24px; }
.vista-escritorio .cuenta-panel { margin-bottom: 20px; }
/* La tarjeta de perfil trae `margin: 30px auto 40px` de la regla de
 * arriba; acá las pestañas ya ocupan ese lugar. */
.vista-escritorio .page-cuenta .auth-card { margin-top: 12px; }
.vista-escritorio .spec-grid { grid-template-columns: repeat(4, 1fr); }
/* La barra del pie de la ficha. En escritorio los botones no estiran a lo
 * ancho de la tarjeta —que acá es enorme— sino que quedan a medida y
 * centrados, todos en UNA SOLA fila: acá sobra ancho y el salto de renglón
 * que hace falta en el teléfono no tiene sentido.
 *
 * Las columnas son implícitas y no una cuenta de cuántas acciones quedaron
 * habilitadas: la fila se arma sola con las que haya —cuatro, tres, dos o
 * una— y ninguna queda corrida a un lado del centro. A 200px por botón los
 * cuatro entran holgados en los 940px de la ficha; a 220 rozaban el borde. */
.vista-escritorio .detalle-actions {
  grid-template-columns: none;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 200px);
  justify-content: center;
}
/* El estirón del último botón impar es de la grilla de dos columnas del
 * teléfono (ver app.css). Acá están todos en el mismo renglón, y un
 * `1 / -1` se lo comería entero.
 *
 * Lo mismo con la fila entera de "Comprar" y con el compañero que le queda
 * suelto al final: los dos salen de esa misma grilla de a dos, que acá no
 * existe. En una sola fila la jerarquía la da el orden —"Comprar" primero—
 * y no el ancho.
 *
 * A cinco botones las columnas se achican solas (son `minmax(0, 200px)`) y
 * quedan en 180px cada una, que es de donde sale el techo del rótulo de
 * "Comprar" (ver detalle.php). */
.vista-escritorio .detalle-actions > :last-child:nth-child(odd) { grid-column: auto; }
.vista-escritorio .detalle-actions > .btn-comprar { grid-column: auto; }
.vista-escritorio .detalle-actions > .btn-comprar ~ :last-child:nth-child(even) { grid-column: auto; }

/* --------- menú de apps --------- */

/* Mismo modal que en móvil, sólo que acá sobra ancho: la grilla pasa a
 * cuatro columnas y la fila de apps entra completa de una, que es como
 * se lee un escritorio de verdad. */
.vista-escritorio .menu-apps-card {
  max-width: 460px;
  padding: 18px 22px 26px;
}
.vista-escritorio .menu-apps-grid {
  grid-template-columns: repeat(4, 1fr);
}

/* --------- misc --------- */

/* El sentinel del scroll infinito es un hijo directo de la sección, no de
 * la grilla, así que no necesita ocupar columna — pero sí centrarse sobre
 * el ancho completo. */
.vista-escritorio .scroll-sentinel { margin-top: 20px; }
