.app{
  min-height: 100vh;
  display:flex;
  flex-direction: column;
}

.app__main{
  flex:1;
  padding: var(--s-6) 0;
}

/* La columna implícita de un grid toma como mínimo el min-content del hijo más
   ancho, así que una sola tarjeta que no entra estira TODA la página y las
   demás quedan cortadas. minmax(0, 1fr) la limita al ancho disponible: si algo
   no entra, desborda solo esa tarjeta. */
.page{
  display:grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-5);
}

/* Una pantalla que necesita más ancho que el contenedor de la app. Vive dentro
   de `.u-container` (1120px) y se sale de él con un margen negativo que la
   mantiene centrada. No usa `transform`: un ancestro con transform se vuelve el
   contenedor de sus hijos `position: fixed`, y un modal adentro de la página
   dejaba de cubrir la pantalla. El `100vw` va con margen para no provocar
   scroll horizontal por culpa de la barra vertical. */
.page--wide{
  --page-wide-w: min(var(--container-wide), calc(100vw - 2 * var(--s-5)));
  width: var(--page-wide-w);
  margin-left: calc(50% - var(--page-wide-w) / 2);
}

.page__header{
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  gap: var(--s-5);
}

.page__title{
  display:flex;
  flex-direction:column;
  gap: var(--s-1);
}

.page__title h1{ margin:0; }

@media (max-width: 768px){
  .app__main{ padding: var(--s-4) 0; }

  .page{ gap: var(--s-3); }

  .page__header{
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--s-3);
  }
}