/* Exclivia · momentos.css — el muro.
 *
 * Móvil primero: lo que se lee aquí arriba es lo que ve un teléfono, y las
 * `@media` de abajo solo AGREGAN la segunda columna. Al revés —escribir el
 * escritorio y apagarlo con media queries— es como se acaba con un muro que en
 * un celular tiene tres columnas de 90 px.
 *
 * Ningún color escrito a mano: todo sale de las variables de `theme.css`, que
 * es lo que hace que el panel de Apariencia siga sirviendo para algo y que el
 * modo noche no haya que mantenerlo aparte.
 */

.mom {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem;
  padding-bottom: 2rem;
}

/* La columna ocupa lo que le da la rejilla: se probó estrecharla a 560 px y el
   muro se veía apretado en una pantalla grande. Lo que se acota es el VIDEO
   —ver `.mom-video`—, que era lo que de verdad estorbaba. */
.mom-col { display: flex; flex-direction: column; gap: .9rem; min-width: 0; }

/* La columna de al lado NO existe en el teléfono: se saca del flujo y del árbol
   de accesibilidad en vez de viajar para nada.

   La excepción es el video de presentación, que sí se ve y va delante de todo.
   La regla que lo saca está abajo, junto al resto de `.mom-intro`, para que
   quien toque el video lo vea — aquí quedaría a cuatro mil líneas de distancia. */
.mom-rail { display: none; }

/* ── Los aros ────────────────────────────────────────────────────────────── */

.mom-aros {
  display: flex;
  gap: .85rem;
  overflow-x: auto;
  padding: .25rem .1rem .35rem;
  /* En un celular la tira se recorre con el dedo y su barra sobra. */
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.mom-aros::-webkit-scrollbar { display: none; }

.mom-aro {
  flex: 0 0 auto;
  width: 4.6rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .35rem;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: inherit;
  font: inherit;
}

.mom-aro small {
  font-size: .72rem;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--exc-muted);
}

.mom-aro-foto {
  position: relative;
  display: grid;
  place-items: center;
  width: 4.1rem;
  height: 4.1rem;
  border-radius: 50%;
  padding: 2.5px;
  background: var(--exc-border);
}

/* El aro encendido: quien tiene algo que todavía no miré. Es un degradado del
   acento, no un color plano — un anillo apagado y otro encendido tienen que
   distinguirse de reojo, sin leer. */
.mom-aro.is-nuevo .mom-aro-foto {
  background: conic-gradient(from 210deg,
              var(--exc-accent), var(--exc-secondary), var(--exc-accent));
}

.mom-aro-foto .exc-avatar {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  border: 2.5px solid var(--exc-bg);
  object-fit: cover;
}

.mom-aro-mas {
  position: absolute;
  right: -2px;
  bottom: -2px;
  display: grid;
  place-items: center;
  width: 1.35rem;
  height: 1.35rem;
  border-radius: 50%;
  background: var(--exc-accent);
  color: var(--exc-accent-contrast);
  border: 2px solid var(--exc-bg);
  font-size: .7rem;
}

.mom-aro-nuevo .mom-aro-foto { background: var(--exc-border); }

/* ── El compositor ───────────────────────────────────────────────────────── */

.mom-comp {
  background: var(--exc-surface);
  border: var(--exc-border-width) solid var(--exc-border);
  border-radius: var(--exc-radius-card);
}

/* El renglón cerrado: la foto, el campo falso y el botón dorado.
   Ya no es UN botón sino tres piezas — un botón dentro de otro no es HTML
   válido y el navegador lo deshace por su cuenta. */
.mom-comp-cerrado {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .7rem .75rem;
}
.mom-comp-cerrado .exc-avatar { flex: 0 0 auto; }

/* Parece un campo y no lo es: al tocarlo se abre el compositor de verdad, con
   su textarea, su contador y sus botones. Dos sitios donde se escribe serían
   dos sitios que mantener —y el de aquí no sabría contar emojis, ni subir una
   foto, ni avisar de que va a la historia—. La pista de que es tocable la da
   la forma: un campo redondo sobre el fondo hundido de la tarjeta. */
.mom-comp-campo {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: .6rem;
  min-height: 42px;
  padding: .55rem .9rem;
  background: var(--exc-surface-2);
  border: var(--exc-border-width) solid transparent;
  border-radius: 999px;
  cursor: pointer;
  color: var(--exc-muted);
  font: inherit;
  text-align: left;
  transition: border-color .15s ease, background .15s ease;
}
.mom-comp-campo span {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* La cámara, dentro del campo y a la derecha. En el acento: es lo único de
   este renglón que promete algo más que escribir. */
.mom-comp-campo svg { flex: 0 0 auto; color: var(--exc-accent); font-size: 1.15rem; }
.mom-comp-campo:hover { border-color: var(--exc-accent); background: var(--exc-surface); }

/* El dorado NO se ve en el teléfono: ahí publicar ya está en el botón redondo
   de la barra de abajo, que además sigue al pulgar por todo el muro. Dos
   llamadas a lo mismo en una pantalla de 380 px dejan el campo sin sitio. */
.mom-comp-ir { display: none; flex: 0 0 auto; }

@media (min-width: 640px) {
  .mom-comp-ir { display: inline-flex; }
}

/* Abierto, en el TELÉFONO, es una hoja a pantalla completa: el teclado se come
   media pantalla y un formulario que quedara a medias entre el muro y el
   teclado sería imposible de usar con una mano. */
.mom-comp.is-abierto {
  position: fixed;
  inset: 0;
  /* Ver «Las capas» al final del archivo: el menú del sitio está en 1050. */
  z-index: 1110;
  border: 0;
  border-radius: 0;
  display: flex;
  flex-direction: column;
  background: var(--exc-surface);
}
.mom-comp.is-abierto .mom-comp-cerrado { display: none; }
.mom-comp.is-abierto .mom-comp-abierto { display: flex; flex-direction: column; min-height: 0; flex: 1; }

.mom-comp-barra {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  padding: .7rem .8rem;
  border-bottom: 1px solid var(--exc-border);
}
.mom-comp-barra strong { font-weight: 500; }

.mom-comp-cuerpo {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: .9rem;
  display: flex;
  flex-direction: column;
  gap: .75rem;
}

.mom-comp-fila { display: flex; gap: .7rem; align-items: flex-start; }

.mom-comp-texto {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  color: var(--exc-text);
  font: inherit;
  font-size: 1.05rem;
  line-height: 1.5;
  resize: none;
  outline: none;
  min-height: 5.5rem;
}
.mom-comp-texto::placeholder { color: var(--exc-muted); }

.mom-comp-media {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: .45rem;
}

.mom-comp-item {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--exc-radius-sm);
  overflow: hidden;
  background: var(--exc-surface-2);
}
.mom-comp-item img,
.mom-comp-item video { width: 100%; height: 100%; object-fit: cover; display: block; }

.mom-comp-item button {
  position: absolute;
  top: .2rem;
  right: .2rem;
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  cursor: pointer;
  font-size: .7rem;
}

/* Mientras sube. El velo tapa la miniatura entera a propósito: una barrita fina
   abajo no se ve en un teléfono al sol. */
.mom-comp-item.is-subiendo::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .45);
}
.mom-comp-item .mom-comp-aro {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  z-index: 1;
  color: #fff;
  font-size: .72rem;
}

.mom-comp-lugar {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  align-self: flex-start;
  padding: .3rem .6rem;
  border-radius: 999px;
  background: var(--exc-accent-soft);
  color: var(--exc-text);
  font-size: .82rem;
}
.mom-comp-lugar button {
  border: 0;
  background: none;
  cursor: pointer;
  color: inherit;
  display: grid;
  place-items: center;
  font-size: .7rem;
}

.mom-comp-pie {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .6rem;
}

.mom-comp-acciones { display: flex; gap: .35rem; flex-wrap: wrap; }

.mom-comp-btn {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .45rem .7rem;
  border: 0;
  border-radius: 999px;
  background: var(--exc-surface-2);
  color: var(--exc-text);
  cursor: pointer;
  font: inherit;
  font-size: .85rem;
}
.mom-comp-btn:hover { background: var(--exc-accent-soft); }
.mom-comp-btn svg { color: var(--exc-accent); }
.mom-comp-btn.is-on { background: var(--exc-accent-soft); }

.mom-comp-cuenta { font-size: .82rem; color: var(--exc-muted); font-variant-numeric: tabular-nums; }
.mom-comp-cuenta.is-poco { color: var(--exc-warning); }
.mom-comp-cuenta.is-lleno { color: var(--exc-danger); }

/* `.exc-choices` es una rejilla de columnas de 140 px como mínimo, que para tres
   opciones de una palabra deja tres cajas enormes y en un teléfono las parte en
   dos renglones. Aquí se quieren pastillas: flex, y que cada una mida lo que
   mide su texto. Lo mismo para elegir la especie de una mascota. */
.mom-comp-audiencia,
[data-mom-pet-especie] {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
}
.mom-comp-audiencia .exc-choice,
[data-mom-pet-especie] .exc-choice {
  font-size: .82rem;
  padding: .38rem .7rem;
  border-radius: 999px;
}

/* ── Las pestañas ────────────────────────────────────────────────────────── */

/* Subrayadas y no en píldora.
 *
 * La píldora las pintaba como un interruptor de tres posiciones, del mismo
 * peso visual que el compositor de encima y la primera tarjeta de debajo: tres
 * cajas con borde, una sobre otra. El subrayado dice lo mismo gastando una
 * línea, y deja la atención donde tiene que estar, que es el muro.
 *
 * La raya de abajo es de la TIRA, y la del acento se monta encima: así la
 * pestaña encendida no «flota» sin suelo cuando no hay ninguna activa —que es
 * lo que pasa mientras se navega de una a otra. */
.mom-tabs {
  display: flex;
  gap: .25rem;
  border-bottom: var(--exc-border-width) solid var(--exc-border);
}

.mom-tab {
  position: relative;
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .35rem;
  /* 44 px de alto: se toca con el pulgar sin apuntar. */
  min-height: 44px;
  padding: .55rem .4rem;
  color: var(--exc-muted);
  font-size: .92rem;
  white-space: nowrap;
}

/* El subrayado crece desde el centro hacia los dos lados. Es lo que convierte
   el cambio de pestaña en un gesto y no en un parpadeo — y como se dibuja con
   `left`/`right` y no con `transform`, no hace falta un segundo elemento ni
   medir nada. */
.mom-tab::after {
  content: '';
  position: absolute;
  left: 50%;
  right: 50%;
  bottom: calc(var(--exc-border-width) * -1);
  height: 2px;
  background: var(--exc-accent);
  border-radius: 2px 2px 0 0;
  transition: left .18s ease, right .18s ease;
}
.mom-tab.is-on { color: var(--exc-text); font-weight: 500; }
.mom-tab.is-on::after { left: 0; right: 0; }
.mom-tab:hover { opacity: 1; color: var(--exc-text); }

@media (prefers-reduced-motion: reduce) {
  .mom-tab::after { transition: none; }
}

/* ── El rótulo de la pantalla ─────────────────────────────────────────────
 *
 * Las tres pantallas del módulo son la misma lista de tarjetas, así que sin
 * esto la única pista de en cuál estás es un renglón marcado en un menú que en
 * el teléfono está guardado en un cajón. */
.mom-head { padding: .25rem .15rem 0; }
.mom-head h1 {
  margin: 0;
  font-size: 1.6rem;
  line-height: 1.15;
}
.mom-head p { margin: .15rem 0 0; font-size: .88rem; }

.mom-tag-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
}
.mom-tag-head strong { font-size: 1.2rem; color: var(--exc-accent); }

/* ── La tarjeta ──────────────────────────────────────────────────────────── */

.mom-lista { display: flex; flex-direction: column; gap: .9rem; }

.mom-card {
  background: var(--exc-surface);
  border: var(--exc-border-width) solid var(--exc-border);
  border-radius: var(--exc-radius-card);
  /* SIN `overflow: hidden`, y hace falta decir por qué: lo tenía para redondear
     las esquinas de la foto, que llegaba de borde a borde. Ahora la foto va con
     márgenes y con su propio radio —igual que la tira del plato y el bloque del
     video en espera—, así que ya nadie lo necesita… y sí estorbaba: recortaba
     el desplegable de los tres puntos en las tarjetas bajas, que se abría
     dentro de la caja y se cortaba por el borde de abajo. */
}

.mom-card-head {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .75rem .85rem .5rem;
}

.mom-autor { display: flex; align-items: center; gap: .6rem; flex: 1; min-width: 0; color: inherit; }
.mom-autor:hover { opacity: 1; }

/* El retrato de la firma, un punto más grande que el `-sm` del sitio.
   Con la firma en dos renglones —nombre con arroba arriba, sitio y hora
   abajo—, un avatar de 28 px se quedaba más bajo que el texto que acompaña y
   la cabecera se leía torcida. Va por CSS y no cambiando la clase en la vista:
   `Ui::avatar()` pinta iniciales cuando no hay foto y ésas heredan el tamaño
   de la caja, así que con una regla se mueven las dos cosas a la vez. */
.mom-card-head .mom-autor > .exc-avatar { width: 2.5rem; height: 2.5rem; font-size: .85rem; }
.mom-autor-txt { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.mom-autor-txt strong { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── La firma: el nombre y el arroba en el mismo renglón ──────────────────
 *
 * El nombre es lo que se reconoce de un vistazo; el arroba es lo que
 * identifica sin lugar a dudas. Estaba solo el segundo, que es el dato
 * correcto y el que menos ayuda a quien recorre el muro con el pulgar.
 *
 * En UN renglón y no en dos: debajo ya va el sitio y la hora, y una firma de
 * tres pisos deja la tarjeta con más encabezado que momento. */
.mom-autor-nom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .15rem .32rem;
  min-width: 0;
}
/* El arroba se ve COMPLETO (2026-09-27): no se recorta con puntos
   suspensivos. Si con los sellos no cabe, los SELLOS bajan de renglón
   (`flex-wrap`), y un arroba más largo que la tarjeta entera se parte por
   dentro en vez de salirse. */
.mom-autor-txt strong.mom-autor-nom { overflow: visible; white-space: normal; }
.mom-autor-quien {
  min-width: 0;
  overflow-wrap: anywhere;
}
.mom-autor-nom .mom-arroba {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: .82rem;
  font-weight: 400;
}

/* ── El menú de la tarjeta ────────────────────────────────────────────────
 *
 * Los tres puntos sustituyen al bote de basura que vivía a la vista en cada
 * momento propio. Era la única acción en firme de la tarjeta y encima la
 * irreversible. */
.mom-menu { position: relative; flex: 0 0 auto; }

.mom-menu-btn {
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--exc-muted);
  cursor: pointer;
  font: inherit;
  transition: background .15s ease, color .15s ease;
}
.mom-menu-btn:hover,
.mom-menu.is-on .mom-menu-btn { background: var(--exc-surface-2); color: var(--exc-text); }

.mom-menu-panel {
  position: absolute;
  top: calc(100% + .25rem);
  /* Anclado a la DERECHA: es la esquina en la que vive el botón, y anclarlo a
     la izquierda lo mandaría fuera de la tarjeta en cuanto el panel fuera más
     ancho que el botón, que es siempre. */
  right: 0;
  z-index: 5;
  min-width: 11rem;
  display: flex;
  flex-direction: column;
  padding: .3rem;
  background: var(--exc-surface);
  border: var(--exc-border-width) solid var(--exc-border);
  border-radius: var(--exc-radius);
  box-shadow: var(--exc-shadow-lg);
}
/* El atributo `hidden` NO gana solo: el `display` de arriba lo escribimos
   nosotros y en la cascada el autor va por encima de la hoja del navegador.
   Sin esta línea el panel se ve SIEMPRE. Es la misma regla que ya tienen el
   visor, el recortador y el estudio. */
.mom-menu-panel[hidden] { display: none; }

.mom-menu-item {
  display: flex;
  align-items: center;
  gap: .55rem;
  width: 100%;
  min-height: 40px;
  padding: .5rem .6rem;
  border: 0;
  border-radius: var(--exc-radius-sm);
  background: none;
  color: var(--exc-text);
  cursor: pointer;
  font: inherit;
  font-size: .88rem;
  text-align: left;
}
.mom-menu-item:hover { background: var(--exc-surface-2); }
/* Lo que no tiene vuelta se pinta como lo que es, y solo AL PASAR por encima:
   en rojo permanente, el menú entero se lee como una advertencia. */
.mom-menu-item.is-peligro:hover { color: var(--exc-danger); }
.mom-menu-item svg { flex: 0 0 auto; font-size: 1.05rem; }

/* El `@usuario` es un IDENTIFICADOR, no una frase: se escribe tal cual se
   registró. Sin esto, el navegador se lo pasa a la tipografía con sus
   ligaduras y sus mayúsculas «bonitas», y `@GonzaloMx` puede acabar pareciendo
   otro usuario del que de verdad es. */
.mom-arroba { text-transform: none; font-variant-ligatures: none; }
.mom-autor-txt small { display: flex; align-items: center; gap: .22rem; font-size: .76rem; }
.mom-autor-txt small svg { font-size: .8rem; }

.mom-texto {
  margin: 0;
  padding: 0 .85rem .7rem;
  /* Los saltos de línea que escribió la persona son suyos; los espacios de más
     no. `pre-line` respeta unos y colapsa los otros. */
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.mom-tag { color: var(--exc-accent); font-weight: 500; }

/* ── Los archivos ────────────────────────────────────────────────────────── */

/* La foto ya no llega de borde a borde: va con márgenes y con su propio radio,
   como la tira del plato y el bloque del video en espera.
 *
 * A sangre, la tarjeta se leía como dos piezas pegadas —un encabezado con
 * fondo y una imagen suelta debajo—; con el aire alrededor se lee como UNA
 * tarjeta con una foto dentro, que es lo que es. De paso, `overflow: hidden`
 * salió de `.mom-card` (ver allá arriba): lo único que necesitaba recortar era
 * esto, y de recortarse se encarga ahora ella misma. */
.mom-media {
  margin: 0 .85rem .15rem;
  border-radius: var(--exc-radius);
  overflow: hidden;
  background: var(--exc-surface-2);
}

.mom-media-uno .mom-foto,
.mom-video {
  display: block;
  position: relative;
  width: 100%;
  /* Segundo tope, además de la proporción acotada de `Momentos::proporcion()`.
     La proporción resuelve la FORMA; esto resuelve el tamaño en una pantalla
     baja —un portátil de 768 px de alto— donde un 4:5 en una columna ancha
     seguía comiéndose la ventana entera. Con esto siempre se ve el principio
     del momento siguiente, que es lo que invita a seguir bajando. */
  max-height: 62vh;
  overflow: hidden;
}
/* ENTERA, nunca recortada. La caja va acotada —`Momentos::proporcion()` y el
   tope de 62vh de arriba— y lo que sobra lo llena el fondo esmerilado de aquí
   abajo. Con `cover`, una foto vertical de teléfono perdía la mitad. */
.mom-media-uno .mom-foto img {
  position: relative;   /* por encima de su propio fondo */
  width: 100%; height: 100%;
  object-fit: contain;
  display: block;
}

/* El fondo: la MISMA foto, ampliada y desenfocada. Es lo que convierte las dos
   franjas muertas en algo que parece parte de la imagen — y a la vez dice de
   qué color es lo que hay fuera del encuadre.

   Es la misma técnica que el video (`.mom-video-fondo`); se declaran aparte
   porque uno sale del póster y el otro de la miniatura, y juntarlos en un
   selector obligaría a que los dos parciales pintaran la misma clase. */
.mom-foto-fondo {
  position: absolute;
  /* Se desborda a propósito: el desenfoque come los bordes y sin este margen
     queda un halo claro alrededor. */
  inset: -8%;
  background-size: cover;
  background-position: center;
  filter: blur(22px) saturate(1.2) brightness(.65);
  /* No es contenido: no se lee ni se toca. */
  pointer-events: none;
}

/* El video es lo ÚNICO que se acota, y se acota por ANCHO además de por alto.
 *
 * Con solo el tope de alto, en una tarjeta ancha la caja salía de 1 150 × 550 y
 * un clip vertical quedaba de 309 px en medio: el 73 % de la tarjeta era
 * desenfoque. Fijando el ancho, la caja mide lo mismo en un monitor de 27" que
 * en un portátil y el desenfoque vuelve a ser un marco en vez del protagonista.
 *
 * Va centrado y la FOTO no se toca: una foto se mira de un vistazo y se
 * agradece grande; un video hay que decidir si se reproduce, y para eso basta
 * con verlo. */
.mom-video {
  max-width: 460px;
  max-height: 46vh;
  margin-inline: auto;
  /* Toda la caja alterna reproducir y pausar, así que toda la caja se ve
     tocable. El botón grande de en medio sigue estando para quien no lo
     supone. */
  cursor: pointer;
}

/* El video se ve ENTERO —`contain`, nunca `cover`—: recortar una foto quita
   margen, recortar un video quita contenido. Lo que sobra a los lados lo llena
   su propio póster ampliado y desenfocado, detrás. */
.mom-video video {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.mom-video-fondo {
  position: absolute;
  /* Se desborda a propósito: el desenfoque come los bordes y sin este margen
     queda un halo claro alrededor. */
  inset: -8%;
  background-size: cover;
  background-position: center;
  filter: blur(22px) saturate(1.2) brightness(.65);
  /* No es contenido: no se lee ni se toca. */
  pointer-events: none;
}

.mom-media-grid { display: grid; gap: 2px; }
.mom-media-grid.n2 { grid-template-columns: 1fr 1fr; }
.mom-media-grid.n3 { grid-template-columns: 1fr 1fr; }
.mom-media-grid.n3 .mom-foto:first-child { grid-row: span 2; }
.mom-media-grid.n4 { grid-template-columns: 1fr 1fr; }

/* No hay `n5` ni `n6`, y es a propósito: la tarjeta dibuja CUATRO fotos como
   mucho y lo que pasa de ahí se cuenta en el `+N` de la última. Las hubo, y
   sobraban de una forma que se veía: la clase decía `n5` —seis columnas— pero
   solo llegaban cuatro hijos, así que la segunda fila ocupaba cuatro columnas
   de seis y dejaba un hueco. Un hueco en una rejilla de fotos se lee como una
   foto que no cargó. */

.mom-media-grid .mom-foto {
  position: relative;
  display: block;
  aspect-ratio: 1;
  overflow: hidden;
}
.mom-media-grid.n3 .mom-foto:first-child { aspect-ratio: auto; }

/* ENTERAS, nunca recortadas — la misma regla que la foto de una sola.
   Con `cover`, una foto vertical dentro de una celda cuadrada perdía la cabeza
   y los pies: la rejilla parecía el encuadre y no lo era. Lo que sobra lo llena
   `.mom-foto-fondo`, la misma foto ampliada y desenfocada detrás.

   Va ABSOLUTA, y eso no es un detalle: en el flujo, una foto de 588×1440 dentro
   de la celda grande de la rejilla de tres —que es la única con la proporción
   libre— estiraba esa columna a 767 px mientras la de al lado medía 630, y la
   tarjeta se quedaba con dos rectángulos negros a la derecha. Sacándola del
   flujo, el alto de cada celda lo decide la rejilla y NINGUNA foto puede
   empujarla.

   Y va SIN `z-index`: las tres piezas de la celda son hermanas posicionadas y
   se pintan en el orden del marcado —fondo, foto, el «+N» de la última—, que es
   exactamente el orden que hace falta. Con un `z-index: 1` aquí, la foto se
   subía por encima del `+N` y el contador de las que faltan desaparecía. */
.mom-media-grid .mom-foto img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  display: block;
}

.mom-mas {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(0, 0, 0, .5);
  color: #fff;
  font-size: 1.4rem;
  font-weight: 500;
}

.mom-play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 3.6rem;
  height: 3.6rem;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, .48);
  color: #fff;
  cursor: pointer;
  font-size: 1.5rem;
  backdrop-filter: blur(2px);
}
.mom-video.is-play .mom-play { display: none; }

.mom-dur,
.mom-mute {
  position: absolute;
  bottom: .55rem;
  padding: .12rem .45rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font-size: .72rem;
  font-variant-numeric: tabular-nums;
}
.mom-dur { right: .55rem; }

.mom-mute {
  left: .55rem;
  display: none;
  place-items: center;
  cursor: pointer;
  font-size: .8rem;
}
.mom-video.is-play .mom-mute { display: grid; }
.mom-video.is-audio .mom-mute { background: var(--exc-accent); color: var(--exc-accent-contrast); }

/* ── Reacciones ──────────────────────────────────────────────────────────── */

.mom-pie {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .5rem .6rem .6rem;
}

.mom-reacciones {
  display: flex;
  align-items: center;
  gap: .1rem;
  flex: 1;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.mom-reacciones::-webkit-scrollbar { display: none; }

.mom-react {
  display: inline-flex;
  align-items: center;
  gap: .22rem;
  flex: 0 0 auto;
  /* Ancla del halo de `.is-brinca::after`. Va aquí y no suelto más abajo: una
     declaración de `position` perdida en otro bloque es justo lo que
     `scripts/css_posiciones.php` existe para cazar. */
  position: relative;
  /* 40 px de alto: es el mínimo con el que un pulgar acierta sin ampliar. */
  min-height: 40px;
  padding: .3rem .42rem;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--exc-muted);
  cursor: pointer;
  font: inherit;
  font-size: .8rem;
  font-variant-numeric: tabular-nums;
  transition: transform .12s ease, background .15s ease, color .15s ease;
}
.mom-react svg { font-size: 1.15rem; }

/* ── El «−» que baja el impulso ─────────────────────────────────────────────
 *
 * Solo lo pinta el servidor para el admin, y solo donde hay impulso. Va PEGADO
 * a su reacción —sin el `gap` de la tira, con margen negativo— para que se lea
 * como parte de ese botón y no como una séptima reacción: en una fila de seis
 * iconos, uno más suelto se toca por error.
 *
 * Chico y apagado a propósito. Es una herramienta de mantenimiento, no algo que
 * se use a diario; compitiendo en peso con el corazón sería ruido en la tarjeta
 * de todo el mundo... salvo que aquí «todo el mundo» es una sola cuenta. */
.mom-react-baja {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  align-self: center;
  width: 1.15rem;
  height: 1.15rem;
  margin-left: -.14rem;
  padding: 0;
  font-size: .85rem;
  line-height: 1;
  color: var(--exc-muted);
  background: var(--exc-surface-2);
  border: 0;
  border-radius: 999px;
  cursor: pointer;
}
.mom-react-baja:hover { color: var(--exc-danger, #d33); }
/* El atributo lo pone y lo quita el JS al repintar, y en este proyecto una
   clase le gana al `hidden` del navegador más veces de las que parece. */
.mom-react-baja[hidden] { display: none; }

/* ── El color de cada reacción ──────────────────────────────────────────────
 *
 * Las seis tenían el mismo oro del acento, así que la fila de reacciones era
 * una hilera de iconos idénticos en color: cuál estaba puesta se leía por el
 * fondo, no de un vistazo. Con un color por reacción, «le di al corazón» y «le
 * di al avión» se distinguen sin leer.
 *
 * Esto es EXACTAMENTE lo que un emoji no deja hacer, y por lo que el sitio usa
 * SVG: el trazo es `currentColor`, así que el color entra por una variable y
 * no hay que dibujar seis iconos.
 *
 * ── Las dos trampas que hay aquí ────────────────────────────────────────────
 *
 * 1. **No van en `theme.css`.** Ese archivo lo GENERA `Theme::generate()` desde
 *    la tabla `settings` y se reescribe entero: lo que se escriba ahí a mano
 *    desaparece al primer cambio de color del admin.
 *
 * 2. **Cada color se declara DOS veces, una por tema.** Es el error que ya
 *    costó una tarde con `--exc-accent-soft`, que vivía solo en `:root`: en
 *    modo noche quedaba un parche crema con el texto casi blanco encima. Un
 *    color elegido mirando el modo claro es ilegible en el oscuro y quien lo
 *    eligió no tiene cómo enterarse.
 *
 * Los doce están medidos contra la superficie de SU tema —con el tinte ya
 * compuesto encima, que es el fondo real del número— y los doce pasan 4.5:1,
 * el mínimo de texto pequeño: el contador va en 12.8 px. Por eso los del modo
 * claro son más oscuros de lo que parecería natural: sobre blanco, un naranja
 * bonito se queda en 3.3:1 y el número deja de leerse.
 */
.mom-react[data-mom-react="love"]   { --mom-r: #c1134e; --mom-rs: rgba(193, 19, 78, .10); }
.mom-react[data-mom-react="fuego"]  { --mom-r: #b04600; --mom-rs: rgba(176, 70,  0, .10); }
.mom-react[data-mom-react="risa"]   { --mom-r: #8a5e00; --mom-rs: rgba(138, 94,  0, .12); }
.mom-react[data-mom-react="wow"]    { --mom-r: #6b4ce6; --mom-rs: rgba(107, 76, 230, .10); }
.mom-react[data-mom-react="patita"] { --mom-r: #0a7048; --mom-rs: rgba(10, 112, 72, .10); }
.mom-react[data-mom-react="avion"]  { --mom-r: #356089; --mom-rs: rgba(53,  96, 137, .10); }

[data-theme="dark"] .mom-react[data-mom-react="love"]   { --mom-r: #ff6b93; --mom-rs: rgba(255, 107, 147, .16); }
[data-theme="dark"] .mom-react[data-mom-react="fuego"]  { --mom-r: #ff8f40; --mom-rs: rgba(255, 143,  64, .16); }
[data-theme="dark"] .mom-react[data-mom-react="risa"]   { --mom-r: #f0c040; --mom-rs: rgba(240, 192,  64, .16); }
[data-theme="dark"] .mom-react[data-mom-react="wow"]    { --mom-r: #a790ff; --mom-rs: rgba(167, 144, 255, .16); }
[data-theme="dark"] .mom-react[data-mom-react="patita"] { --mom-r: #48d199; --mom-rs: rgba( 72, 209, 153, .16); }
[data-theme="dark"] .mom-react[data-mom-react="avion"]  { --mom-r: #8ab4dd; --mom-rs: rgba(138, 180, 221, .16); }

/* Al pasar por encima se ADELANTA su color, atenuado. Es lo que convierte la
   fila en algo que se explora: se ve de qué color va a ponerse antes de
   pulsar. En un teléfono no hay «encima», así que esto no le quita nada a
   nadie: allá lo que informa es el color al quedar puesta. */
.mom-react:hover { background: var(--exc-surface-2); color: var(--mom-r, var(--exc-text)); }

/* La mía, ya con su color. El `var(…, …)` de respaldo es a propósito: una
   reacción nueva en `Momentos::REACCIONES` sin color aquí sale con el oro del
   acento de siempre en vez de quedarse gris y parecer que no se guardó. */
.mom-react.is-mia {
  color: var(--mom-r, var(--exc-accent));
  background: var(--mom-rs, var(--exc-accent-soft));
}
.mom-react.is-mia svg { --exc-ico-w: 2; }

/* El brinco al pulsar: se pasa de largo y vuelve, en vez de crecer y encoger.
 * Ese rebote de más es lo que lo hace sentir un botón pulsado y no una
 * animación; son 260 ms, por debajo no se percibe el regreso.
 *
 * Y a la vez un destello del color de ESA reacción, que se apaga hasta el
 * tinte con el que se queda. Así el gesto confirma con el mismo color que va
 * a quedar puesto, en vez de con un gris cualquiera.
 *
 * El destello es el FONDO del propio botón y no un aro que crezca por fuera:
 * `.mom-reacciones` lleva `overflow-x: auto` para que la fila se pueda
 * arrastrar en un teléfono, y en cuanto un eje deja de ser `visible` el otro
 * también recorta. Un halo saliéndose de la caja se vería cortado arriba y
 * abajo, y encima ensancharía el área desplazable: la fila daría un tirón
 * lateral cada vez que alguien reacciona en la última. La escala se queda
 * corta a propósito por lo mismo. */
@keyframes mom-pop {
  0%   { transform: scale(1);    background-color: var(--mom-rs, var(--exc-accent-soft)); }
  30%  { transform: scale(1.22); background-color: var(--mom-r, var(--exc-accent)); }
  70%  { transform: scale(.96); }
  100% { transform: scale(1);    background-color: var(--mom-rs, var(--exc-accent-soft)); }
}

/* En el punto más alto el fondo es el color pleno, así que el icono y el
   número tienen que despegarse de él o desaparecen medio parpadeo. */
@keyframes mom-pop-tinta {
  0%, 100% { color: var(--mom-r, var(--exc-accent)); }
  30%      { color: var(--exc-surface); }
}

.mom-react.is-brinca {
  animation: mom-pop .26s ease-out, mom-pop-tinta .26s ease-out;
}

/* Quien pidió menos movimiento se queda con el color y sin los saltos. El
   color NO es decoración: es la información de qué reacción está puesta, así
   que eso se conserva siempre. */
@media (prefers-reduced-motion: reduce) {
  .mom-react { transition: none; }
  .mom-react.is-brinca { animation: none; }
}

.mom-react.is-cero span:empty { display: none; }

/* ── Colapsada, la tira enseña lo justo ───────────────────────────────────
 *
 * Seis iconos grises en cada tarjeta, doce tarjetas por pantalla: setenta y
 * dos. Eso ya no se lee como «hay seis formas de decir algo», se lee como una
 * barra de herramientas, y el corazón —que es casi todo lo que se toca— quedaba
 * como uno más de la fila.
 *
 * Se ven el corazón, SIEMPRE, y las que ya tienen cuenta. Un momento con nueve
 * patitas las enseña sin que nadie abra nada, que es justo lo que hay que ver:
 * cómo le fue. Las seis siguen en el HTML, así que el servidor no sabe nada de
 * esto y la tarjeta que llega por AJAX o la ficha a pantalla completa nacen
 * igual de bien.
 *
 * `is-cero` ya lo mantenía el JS para otra cosa (esconder el número vacío), así
 * que reaccionar y quitar la reacción repintan esto solos. */
.mom-reacciones .mom-react.is-cero { display: none; }
/* Las DOS primeras se ven siempre: son la misma respuesta partida en dos —«me
   identifica» y «te abrazo»— y esconder la segunda detrás de la carita deja lo
   que alguien contó sin más salida que un corazón. */
.mom-reacciones .mom-react[data-mom-react="love"],
.mom-reacciones .mom-react[data-mom-react="abrazo"],
.mom-reacciones.is-abierta .mom-react { display: inline-flex; }

/* La carita que abre el resto. Gris y sin color propio a propósito: no es una
   séptima reacción, es la puerta a las otras cinco. */
.mom-react-mas {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  min-height: 40px;
  padding: .3rem .42rem;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--exc-muted);
  cursor: pointer;
  font: inherit;
  transition: background .15s ease, color .15s ease;
}
.mom-react-mas svg { font-size: 1.15rem; }
.mom-react-mas:hover,
.mom-reacciones.is-abierta .mom-react-mas { background: var(--exc-surface-2); color: var(--exc-text); }

.mom-guardar {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  min-width: 40px;
  min-height: 40px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--exc-muted);
  cursor: pointer;
  font-size: 1.15rem;
}
.mom-guardar:hover { background: var(--exc-surface-2); color: var(--exc-text); }
.mom-guardar.is-on { color: var(--exc-accent); }
.mom-guardar.is-on svg { --exc-ico-w: 2; }

/* ── Vacíos y «más» ──────────────────────────────────────────────────────── */

.mom-vacio { padding: 2.5rem 1rem; text-align: center; }
.mom-vacio > svg { font-size: 2.6rem; color: var(--exc-muted); --exc-ico-w: 1.25; }
.mom-vacio h3 { margin-top: .6rem; }

.mom-mas-wrap { padding-top: .25rem; }

/* ── El perfil ───────────────────────────────────────────────────────────── */

/* Va DENTRO de `.mom-col`, la misma columna del muro: sin eso la portada se
   estiraba de borde a borde, el avatar quedaba cortado a la izquierda y
   «Editar perfil» se salía por la derecha. El menú del panel ya ocupa su
   franja; el contenido vive en lo que queda. */
.mom-perfil { padding-bottom: 2rem; }

/* ── El perfil público de la raíz (exclivia.com/usuario) ─────────────────── */

/* Abre SIN sesión y sin el menú del panel, así que se centra solo. */
/* La página pública NO lleva barra de arriba —su carcasa es `layouts/publico`,
   que solo pinta el cuerpo—, así que la portada puede empezar en el borde de
   la ventana. Ese `padding-block` de arriba era el hueco oscuro que se veía
   encima de la banda. */
.mom-pub { padding-block: 0 3rem; }

/* ── La barra de arriba ─────────────────────────────────────────────────────
 *
 * La carcasa de esta página va desnuda a propósito —sin el menú del panel—:
 * quien llega por un WhatsApp viene a ver una taquería, no a navegar Exclivia.
 * Pero desnuda del todo la dejaba sin una sola puerta de salida, así que la
 * barra lleva exactamente dos cosas: la marca y cómo entrar.
 *
 * Su contenido se alinea con el del perfil —mismo ancho máximo y mismo
 * acolchado que `.exc-container`— o el logotipo quedaría pegado al filo de la
 * ventana mientras la portada empieza cien píxeles más adentro. */
.mom-pub-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  max-width: 1180px;
  margin-inline: auto;
  padding: .75rem 1rem;
}
.mom-pub-marca { display: inline-flex; align-items: center; }
.mom-pub-marca .exc-logo-img  { height: 1.6rem; width: auto; display: block; }
.mom-pub-marca .exc-logo-text { font-size: 1.25rem; font-weight: 600; }

.mom-pub-nav {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  font-size: .9rem;
}
.mom-pub-nav a { color: var(--exc-muted); }
.mom-pub-nav a:hover { opacity: 1; color: var(--exc-text); }
/* El de entrar en el acento: de los dos es el único que hace algo por quien
   llegó, y en gris como el otro no se distingue de un enlace de pie de página. */
.mom-pub-nav .mom-pub-cta { color: var(--exc-accent); font-weight: 500; }

@media (min-width: 768px) {
  .mom-pub-bar { padding: 1.1rem 1.5rem; }
}

/* ── La portada ─────────────────────────────────────────────────────────────
 *
 * CON márgenes y esquinas redondas. Estuvo a sangre —de borde a borde— con el
 * argumento de que así «se lee como la portada de alguien»; puesta al lado de
 * la lámina, lo que pasaba es que la página parecía empezar en una foto. Con
 * aire alrededor, la portada, el retrato y el nombre se leen como UNA pieza, y
 * la foto deja de competir con el nombre por ser lo primero.
 *
 * 4:1 es la MISMA proporción que la del perfil de dentro, y no por casualidad:
 * el encuadre se elige una vez y tiene que valer en los dos sitios. */
/* Misma tarjeta de dos mitades que el perfil propio (`.mom-pf-*`), y por la
 * misma razón: sin ella la cabecera flota sobre el fondo de la página.
 *
 * Aquí importa más todavía — `exclivia.com/{usuario}` es la dirección que se
 * comparte y, muchas veces, la primera pantalla que alguien ve del sitio. */
.mom-pub-portada {
  position: relative;
  aspect-ratio: 4 / 1;
  border: var(--exc-border-width) solid var(--exc-border);
  border-bottom: 0;
  border-radius: var(--exc-radius-card) var(--exc-radius-card) 0 0;
  overflow: hidden;
  background: var(--exc-surface-2);
}
.mom-pub-portada img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Sin foto NO se pinta un recuadro gris: un degradado del acento se ve
   deliberado, y un gris permanente se ve roto. */
.mom-pub-portada.is-vacia {
  background: linear-gradient(120deg, var(--exc-accent-soft), var(--exc-surface-2) 60%);
}

/* ── La ficha ───────────────────────────────────────────────────────────────
 *
 * Retrato · datos · acciones. En el teléfono se apila y las acciones bajan al
 * final, que es donde caen el pulgar y la decisión. */
/* En el TELÉFONO el retrato va al lado del nombre, no encima.
   Cada uno en su renglón se comía media pantalla antes de decir nada: entre la
   portada y la primera pestaña había un retrato de 100 px solo, un nombre a dos
   renglones y tres líneas más, y la rejilla —que es a lo que se vino— empezaba
   fuera de la pantalla. Lado a lado, todo eso cabe de una vez. */
.mom-pub-ficha {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: .8rem;
  /* El lateral se queda en 0 —la ficha ya venía así y su contenido está
     medido para ese ancho—; lo que añade la tarjeta es el aire de abajo. */
  padding: .85rem 0 1.1rem;

  background: var(--exc-surface);
  border: var(--exc-border-width) solid var(--exc-border);
  border-top: 0;
  border-radius: 0 0 var(--exc-radius-card) var(--exc-radius-card);
  box-shadow: var(--exc-shadow);
}

/* El retrato NO se monta sobre la portada: montado tapa el centro de la foto
   —que en la de un negocio suele llevar su nombre escrito— y obliga a que todo
   lo demás baje.

   Y es un cuadrado redondeado, no un círculo: la mayoría de las cuentas que
   usan esta dirección son negocios, y un logotipo metido en un círculo se
   recorta por las esquinas, que es justo donde los logotipos ponen su nombre. */
.mom-pub-retrato { flex: 0 0 auto; }
.mom-pub-foto {
  width: 4.4rem;
  height: 4.4rem;
  border-radius: 1.1rem;
  border: var(--exc-border-width) solid var(--exc-border);
  background: var(--exc-surface);
  object-fit: cover;
  /* `Ui::avatar()` pinta iniciales cuando no hay foto; ese `<span>` hereda la
     caja y necesita centrar su texto. */
  display: grid;
  place-items: center;
  font-size: 1.3rem;
}

/* Base de 10rem y no de 16: con 16, en un teléfono de 360 px el bloque de datos
   no cabía al lado de un retrato de 70 px y se iba al renglón siguiente — que
   es de donde salía todo el hueco. */
.mom-pub-datos { flex: 1 1 10rem; min-width: 0; }

/* El NOMBRE manda, y el sello va pegado a él: lo que un sello afirma es que
   este nombre es de quien dice ser. `align-items: center` y no `baseline`
   porque el escudo es un dibujo, no una letra: cuadrado por su base queda
   colgando. */
/* El nombre es TEXTO CORRIDO y el sello va dentro de él, no un `flex` con el
   sello de segundo hijo.
 *
 * En flex, el nombre ocupa el renglón entero como un solo hijo y el sello se va
 * al siguiente él solo: un escudo azul flotando bajo el nombre, que es
 * exactamente como se veía en una tableta de 600 px. Como caja en línea, el
 * sello se comporta como un signo de puntuación y viaja pegado a la última
 * palabra.
 *
 * 1.3rem en el teléfono: a 1.85 un nombre de tres palabras se parte en dos
 * renglones y empuja todo lo de abajo. El titular crece por tramos, y el tramo
 * de en medio existe porque en una tableta el nombre comparte renglón con los
 * botones — que es donde se rompía. */
.mom-pub-nombre {
  margin: 0;
  font-size: 1.3rem;
  font-weight: 700;
  line-height: 1.25;
}
.mom-pub-nombre .exc-sello {
  display: inline-block;
  /* Alineado a la letra y no al centro de la caja: el escudo tiene más masa
     arriba, y centrado se ve colgando de la línea base. */
  vertical-align: -.12em;
  margin-left: .3rem;
  width: 1.15rem;
  height: 1.15rem;
  min-width: 1.15rem;
}

.mom-pub-arroba {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .35rem;
  margin: .25rem 0 0;
  color: var(--exc-muted);
  font-size: .88rem;
}
/* El arroba es un IDENTIFICADOR, no una frase: se escribe tal cual se registró,
   sin las ligaduras ni las mayúsculas «bonitas» de la tipografía. */
.mom-pub-at { text-transform: none; font-variant-ligatures: none; }
.mom-pub-giro { display: inline-flex; align-items: center; gap: .25rem; }

/* La BIO cruza la ficha entera y no vive en la columna de en medio.
 *
 * Dentro de `.mom-pub-datos` quedaba apretada entre el retrato y los botones:
 * en un escritorio de 1280 px esa columna mide unos 300, así que una bio de dos
 * frases salía a cinco renglones de cuatro palabras con media ficha en blanco a
 * la derecha.
 *
 * `width: 100%` es lo que le da su propio renglón también en el teléfono, donde
 * la ficha sigue siendo `flex`: sin él se metería a empujones en la fila del
 * retrato. En el escritorio manda el `grid-column` de más abajo. */
.mom-pub-bio {
  width: 100%;
  margin: .2rem 0 0;
  font-size: .95rem;
  line-height: 1.45;
  overflow-wrap: anywhere;
  /* En caracteres: una bio de mil cuatrocientos píxeles de ancho no se lee, se
     recorre. Y no centra nada — sigue alineada a la izquierda con el nombre. */
  max-width: 78ch;
}

.mom-pub-donde {
  display: flex;
  align-items: center;
  gap: .3rem;
  margin: .35rem 0 0;
  color: var(--exc-muted);
  font-size: .85rem;
}

/* Los tres números en UN renglón, y solo los que dicen algo. Estaban en una
   caja con separadores en medio de la ficha, y en una cuenta recién abierta eso
   son tres ceros enmarcados como si fueran el titular. */
.mom-pub-nums {
  margin: .35rem 0 0;
  color: var(--exc-muted);
  font-size: .85rem;
}
.mom-pub-nums b { color: var(--exc-text); font-weight: 600; }

/* ── Por qué la ciudad y los números se separan con HUECO y no con una raya ──
 *
 * Había una `|` pintada con `::before` sobre los números. Con la fila en un
 * solo renglón se veía bien, y esa fila ENVUELVE: la columna de datos es la de
 * en medio de la ficha —entre el retrato y los botones— y en cuanto el canal
 * tiene dos cifras («14 Momentos · 824 Seguidores») los números caen al
 * segundo renglón. La raya se iba con ellos y abría la línea: un palo suelto
 * delante del número, que es exactamente como se ve un error de la página.
 *
 * Medido en cuatro canales a 1400 y a 390 px: pasaba en los dos anchos y en
 * los dos con cifras. No es un caso raro — es el canal normal.
 *
 * Y no hay forma de arreglarlo con la raya puesta: CSS no sabe si un elemento
 * empieza renglón, así que cualquier `::before` condicional es adivinar. El
 * hueco no puede romperse nunca, en ningún idioma y a ningún ancho.
 *
 * Para que no se lean como una sola frase, el hueco entre bloques (1.35rem) es
 * claramente mayor que el `·` que separa una cifra de otra dentro del grupo. */

/* En el teléfono ocupan el ancho, debajo de la ficha: es la acción de la
   pantalla y ahí cae el pulgar. `width: 100%` sobre un hijo de un flex que
   envuelve lo manda al renglón siguiente sin una consulta de medios. */
.mom-pub-acciones {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  width: 100%;
}
/* `nowrap` en la etiqueta y una base más ancha. Con tres botones a 8rem en
   una fila de 340 px se aprietan hasta que el texto se parte dentro del
   botón —«Cómo / llegar», en dos renglones— y la fila queda más alta que los
   botones. Lo que tiene que envolver es la FILA, no las palabras. */
.mom-pub-acciones .exc-btn:not(.exc-btn-icon) { flex: 1 1 9.5rem; white-space: nowrap; }

/* ── Las pestañas y el vacío ────────────────────────────────────────────── */

.mom-pub-tabs { margin-top: 1.1rem; }

/* ══ Las herramientas del canal ═════════════════════════════════════════════
 *
 * Los VERBOS del canal, bajo la ficha y encima de las pestañas: «Ver el
 * recorrido», «Escríbenos». Salieron de la tira porque un verbo no es un lugar
 * que se hojee —y porque con dos herramientas encendidas la tira ya no cabía en
 * un teléfono de 390 px—. Ver el comentario de `publico.php`.
 *
 * A lo ANCHO en el teléfono, como cualquier página de enlaces: es lo que se
 * vino a hacer y el pulgar no tiene que apuntar. En cuanto hay sitio se ponen
 * de a dos, y con una sola no se estira de lado a lado — `flex: 1 1 18rem` le
 * da su ancho y el `max-width` le pone el techo.
 */

/* ══ El rail: el video de presentación y los verbos ═════════════════════════
 *
 * En escritorio esta pantalla es de DOS columnas, igual que el perfil de dentro
 * del panel: a la izquierda la portada, la ficha y lo que publica; a la derecha
 * un rail con el video arriba y los verbos debajo.
 *
 * ── Por qué así y no en una banda a lo ancho ───────────────────────────────
 *
 * Estuvo en una banda entre la ficha y las pestañas, y sobraba pantalla: el
 * contenido se quedaba en su columna y a la derecha quedaba una franja negra de
 * arriba abajo. Con el rail esa franja se usa, y el video —que es lo único del
 * perfil que se entiende sin leer— queda ARRIBA del todo, a la altura de la
 * portada, en vez de empujar las pestañas hacia abajo.
 *
 * ── En el teléfono NO hay rail ─────────────────────────────────────────────
 *
 * Ahí es una sola columna y el bloque se queda donde está en el HTML —después
 * de la ficha y antes de las pestañas—, que es el sitio correcto: el video
 * primero, los verbos después y las pestañas debajo. Por eso el orden del
 * documento es ése y el escritorio solo lo RECOLOCA con la rejilla; moverlo con
 * JavaScript sería la misma pieza en dos sitios según el ancho.
 *
 * La vista solo pinta este bloque si hay algo que poner dentro, y le cuelga
 * `has-intro` / `has-tools` diciendo qué trae. Hoy el CSS no las necesita —el
 * rail se acomoda solo con las dos que haya— pero se quedan porque son lo que
 * contesta «¿por qué este perfil no tiene rail?» mirando el HTML, sin tener que
 * leer el PHP.
 */

.mom-pub-banda {
  display: grid;
  /* `minmax(0, …)` y no `1fr`: `1fr` es `minmax(auto, 1fr)` y su mínimo sigue
     siendo el contenido, así que un rótulo largo estira la rejilla por encima
     de su padre. Es la trampa que ya pisó `.vol-wrap`. */
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
  margin-top: 1.1rem;
  align-items: start;
}

/* ── El techo del video ─────────────────────────────────────────────────────
 *
 * En el TELÉFONO su 3/4 sobre los 358 px de la columna son 477 px de los 844
 * de la pantalla: el video se comía la página entera y empujaba los verbos y
 * las pestañas fuera de la vista. Quien abría el perfil veía un video y nada
 * más, y tenía que adivinar que debajo había algo.
 *
 * Aquí NO hay tope en `rem`, y ése era el fallo: los 21rem se eligieron para el
 * TELÉFONO —dejaban la llamada «Activar mapa» de la tarjeta de abajo dentro del
 * pliegue en un 390×844— pero la regla se aplicaba en todos los anchos, y en el
 * rail de escritorio, que mide exactamente 21rem, cuadraba el video: 336 × 336.
 * Una medida pensada para el pliegue de un teléfono no puede mandar en una
 * columna de escritorio, donde no hay nada debajo compitiendo por el pliegue:
 * el rail es su propia columna.
 *
 * El tope del teléfono sigue existiendo, pero abajo y en `vh`, que es la unidad
 * que sabe de pliegues. */
.mom-pub-banda .mom-intro { max-height: 78vh; }

/* ── Y en una sola columna, el bloque no se va a lo ancho ───────────────────
 *
 * Sin esto, entre el teléfono y los 992 px del rail el video ocupaba la columna
 * entera: a 768 px quedaba una caja de 720 × 352, o sea 2:1 sobre un clip que
 * es 9:16. Con `object-position: center top` —que está puesto porque en un clip
 * de alguien hablando la cara va arriba— eso recortaba el video hasta enseñar
 * SOLO CIELO. El camión, que es de lo que va el clip, no salía.
 *
 * 26rem es lo más ancho que puede ser sin que el recorte se coma el asunto, y
 * de paso le da a los verbos un ancho de tarjeta en vez de una banda de lado a
 * lado. En un teléfono no cambia nada: 390 px ya son menos que 26rem. */
@media (max-width: 991px) {
  .mom-pub-banda { max-width: 26rem; }

  /* El pliegue del teléfono. A 9:16 y a todo lo ancho de la columna, el clip
     pide 637 px en un 390×844: el 75 % de la pantalla, con las pestañas y la
     tarjeta del mapa empujadas fuera. 62vh lo dejan en 523 y enseñan el 82 %
     del plano — contra el 51 % de antes, que era el cuadrado. Lo que se recorta
     sale de ABAJO, porque `object-position` es `center top` y en un clip de
     alguien presentándose lo que importa está arriba. */
  .mom-pub-banda .mom-intro { max-height: 62vh; }
}

/* ── El teléfono ACOSTADO ───────────────────────────────────────────────────
 *
 * 844 × 390: pasa de largo la consulta de arriba, que mira el ANCHO, y se
 * quedaba con la regla de escritorio. Medido: 416 × 242, o sea 1.72 —más ancho
 * que alto, el cuadrado otra vez y peor— con el 32 % del clip a la vista.
 *
 * Aquí no hay techo de alto que arregle nada: a 416 de ancho, 9:16 pide 740 px
 * sobre una pantalla de 390. Lo que se limita es el ANCHO, calculado desde el
 * alto disponible, y así la proporción se conserva entera en vez de recortarse.
 *
 * El precio es una tarjeta más angosta que la portada de arriba, que es
 * justo lo que la regla base evita a toda costa. Se acepta SOLO aquí: en
 * vertical esa estrechez rompe una columna de tarjetas alineadas, y en
 * horizontal la alternativa es enseñar un tercio de un video. */
@media (max-height: 560px) and (orientation: landscape) {
  .mom-pub-banda .mom-intro,
  .mom-rail > .mom-intro {
    max-height: 82vh;
    /* El mismo 82vh traducido a ancho por la proporción: la caja cabe entera
       y no hace falta que `cover` recorte nada. */
    max-width: calc(82vh * 9 / 16);
    margin-inline: auto;
  }
}

/* ── Las dos columnas ───────────────────────────────────────────────────────
 *
 * 992 px y `21rem` de rail, los mismos números que `.mom` —el muro y el perfil
 * de dentro—: dos anchos distintos para la misma idea se ven como un error de
 * página cuando alguien pasa de una pantalla a la otra.
 *
 * Todo lo demás se queda en la columna 1 y se coloca solo, en el orden del
 * documento.
 *
 * ── Y el rail tiene que ABARCAR las filas, no ocupar una ──────────────────
 *
 * Con `grid-row: 1` a secas, la fila 1 crece hasta el alto del rail: la portada
 * medía 193 px y la ficha aparecía 558 más abajo, con medio metro de nada en
 * medio. Medido antes de verlo en pantalla.
 *
 * `1 / -1` tampoco sirve: en una rejilla de filas IMPLÍCITAS —que es ésta, aquí
 * nadie declara `grid-template-rows`— el `-1` apunta a la última línea
 * EXPLÍCITA, que no existe, y el resultado depende del navegador.
 *
 * Así que se abarca un número alto a mano. Las filas que sobran miden cero y no
 * pintan nada; lo único que hace el `span` es que el alto del rail se reparta
 * entre todas en vez de caer sobre la primera. Esta columna tiene una decena de
 * hijos —portada, ficha, pestañas, sus paneles y el pie—, así que 100 es
 * holgura de sobra sin ser un número inventado. */
@media (min-width: 992px) {
  .mom-pub {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 21rem;
    column-gap: 1.5rem;
    align-items: start;
  }

  .mom-pub > * { grid-column: 1; }

  /* El pie es de la PÁGINA y no de la columna: centrado solo en la izquierda
     queda descuadrado respecto a todo lo que tiene encima.

     Aquí `-1` sí vale, y la diferencia con las filas del rail es exactamente
     ésta: las COLUMNAS están declaradas arriba, así que la última línea existe.
     Las filas no, y por eso allá hay que abarcar a mano. */
  .mom-pub > .mom-pub-pie { grid-column: 1 / -1; }

  .mom-pub > .mom-pub-banda {
    grid-column: 2;
    grid-row: 1 / span 100;
    align-self: start;
    margin-top: 0;

    /* Pegado, como el rail del muro. Lo que se desplaza al lado son los
       momentos del canal, y perder el video y las dos tarjetas al tercer
       desplazamiento es perder justo lo que se vino a hacer. `1rem` y no las
       `5rem` de `.mom`: aquella barra es FIJA y ésta se va con la página, así
       que dejarle ese hueco sería un agujero en cuanto la barra sube. */
    position: sticky;
    top: 1rem;

    /* La misma red que `.mom-rail`, y puesta ANTES de que muerda.
     *
     * Hoy esta banda lleva solo el video —597 px, con 287 de sobra en una
     * laptop— así que el fallo no se ve. Pero la construcción es idéntica, y la
     * tercera tarjeta que alguien añada aquí lo reproduce: un `sticky` más alto
     * que la ventana esconde su final para siempre. Ya pasó en el rail de
     * dentro; dejarlo sin arreglar aquí es esperar a que pase dos veces. */
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
  }
}

/* ══ Las tarjetas del rail ══════════════════════════════════════════════════
 *
 * Sustituyeron a una lista de botones sueltos. La diferencia no es de adorno:
 * un renglón que dice «Recorrido» le pide a quien lo lee que adivine que
 * detrás hay un mapa, y mucha gente no lo adivina — justo la que más lo
 * necesita. Cada tarjeta dice lo que es antes de que nadie toque nada.
 *
 * Son DOS: arriba lo que este canal es —su ruta— y abajo por dónde se le
 * habla. Un negocio de otro giro no tendrá la primera y sí la segunda.
 */

.mom-card {
  display: flex;
  flex-direction: column;
  gap: .7rem;
  padding: .95rem;
  background: var(--exc-surface);
  border: var(--exc-border-width, 1px) solid var(--exc-border);
  border-radius: var(--exc-radius);
}

.mom-card-head { display: flex; align-items: center; gap: .7rem; }

.mom-card-ico {
  flex: none;
  display: grid;
  place-items: center;
  width: 2.2rem;
  height: 2.2rem;
  border-radius: var(--exc-radius-sm, 10px);
  background: color-mix(in srgb, var(--exc-accent) 16%, transparent);
  color: var(--exc-accent);
  font-size: 1.15rem;
}

/* `min-width: 0` para que el `ellipsis` del título recorte de verdad: en flex
   el mínimo de un elemento es su contenido, no cero. */
.mom-card-tit { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .1rem; }

/* El título y su estado en la misma línea, el estado pegado a la derecha. Es
   lo que deja al subtítulo el ancho entero — antes se partía en dos. */
.mom-card-tit-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  min-width: 0;
}

.mom-card-tit strong {
  font-size: 1rem;
  font-weight: 600;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mom-card-tit small  { font-size: .8rem; line-height: 1.35; color: var(--exc-muted); }

/* ── La tapa del mapa ───────────────────────────────────────────────────────
 *
 * OJO: la imagen es una MUESTRA recortada de la lámina de diseño, no el
 * recorrido de esta ruta. Ver el comentario de `publico.php`, que dice qué hay
 * que hacer antes de lanzar.
 *
 * `object-fit: cover` y un alto fijo: la imagen mide 352×150 y el rail 21rem,
 * así que en un teléfono ancho se estira y en el rail se recorta un poco por
 * los lados. Recortar es lo correcto — deformar un mapa lo vuelve otro mapa. */
.mom-card-tapa {
  display: block;
  height: 8.5rem;
  border-radius: var(--exc-radius-sm, 10px);
  overflow: hidden;
  background: var(--exc-surface-2, var(--exc-surface));
}

.mom-card-tapa img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Lo que SÍ se puede afirmar de los minutos: que esta ruta los dice. El número
   exacto necesitaría además dónde está quien mira. */
.mom-card-dato {
  display: flex;
  align-items: center;
  gap: .4rem;
  margin: 0;
  font-size: .82rem;
  color: var(--exc-muted);
}

.mom-card-dato svg { flex: none; }

/* El botón. En el acento y a lo ancho: es lo único de la tarjeta que hace algo,
   y con el aspecto de los demás botones del rail no se distinguiría del resto
   del texto. */
.mom-card-cta {
  display: flex;
  align-items: center;
  gap: .5rem;
  width: 100%;
  padding: .7rem .9rem;
  border: 0;
  border-radius: var(--exc-radius-sm, 10px);
  background: var(--exc-accent);
  color: var(--exc-on-accent, #1a1a1a);
  font: inherit;
  font-weight: 600;
  font-size: .95rem;
  cursor: pointer;
}

.mom-card-cta:hover { filter: brightness(1.06); }
.mom-card-cta span:not(.mom-card-cta-mas) { flex: 1; text-align: left; }
.mom-card-cta-mas { flex: none; opacity: .75; }

/* Con el mapa ABIERTO la tapa sobra —ya se está viendo lo que invitaba a ver—
   y el botón se apaga: pedir hacer lo que acaba de hacerse es ruido. */
.mom-card-cta.is-active { background: color-mix(in srgb, var(--exc-accent) 22%, transparent); color: var(--exc-text); }
/* La clase la pone `publico.js`, no un `:has()`: esa decisión no se delega a
   un selector que no todos los navegadores entienden igual — es la misma
   regla que las clases `has-intro`/`has-tools` de la banda. */
.mom-card.is-abierta .mom-card-tapa { display: none; }

/* ── El plano de «Dónde estamos» ────────────────────────────────────────────
 *
 * Reusa la `.mom-card-tapa` de la ruta: mismo alto y mismo `cover`.
 *
 * ── Y la atribución va DENTRO del plano ────────────────────────────────────
 *
 * No es opcional —los datos son de OpenStreetMap (ODbL) y el estilo de CARTO—
 * pero debajo de la imagen se comía un renglón entero de una tarjeta de tres,
 * y en una columna de 21rem eso es pantalla que se le quita al mapa. En la
 * esquina de abajo dice exactamente lo mismo y es donde la pone Leaflet en
 * cualquier mapa del sitio, así que además se lee como lo que es.
 *
 * `right` y `bottom` declarados, no un absoluto suelto: sin anclaje se coloca
 * en su «posición estática» —el borde de arriba del contenedor— y acabaría
 * encima del plano en vez de en su esquina. Es lo que caza
 * `css_posiciones.php`.
 *
 * El fondo es claro a secas y no un token del tema: el mapa compuesto es
 * `light_all` SIEMPRE, también de noche, así que la pastilla vive sobre un
 * gris claro pase lo que pase. Un `--exc-surface` aquí la volvería negra sobre
 * blanco de noche y blanca sobre blanco de día. */
.mom-card-mapa { margin: 0; position: relative; }

.mom-card-mapa figcaption {
  position: absolute;
  right: .3rem;
  bottom: .3rem;
  padding: .05rem .3rem;
  border-radius: 5px;
  background: rgba(255, 255, 255, .74);
  color: #55524c;
  font-size: .58rem;
  line-height: 1.5;
  /* No se puede tocar: es un rótulo, no un control, y encima de un plano
     cualquier cosa que reciba el dedo estorba. */
  pointer-events: none;
}

/* «3 ubicaciones en el mapa» abre la pestaña con la lista entera. Es un BOTÓN
   y se pinta como los demás datos de la tarjeta: con borde sería un segundo
   verbo compitiendo con «Cómo llegar», que es el que de verdad se viene a
   pulsar. */
.mom-card-dato-btn {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: .82rem;
  color: var(--exc-muted);
  cursor: pointer;
  text-align: left;
}
.mom-card-dato-btn:hover { color: var(--exc-text); }

/* ── «¿Quieres formar parte de la plaza?» ───────────────────────────────────
 *
 * El único bloque del perfil que le habla a quien tiene un NEGOCIO. Se
 * distingue del resto del rail con un filete en el acento y nada más: con
 * fondo propio competiría con el plano de arriba, que es lo que la gente
 * viene a mirar.
 *
 * El botón reusa `.mom-card-cta` —el dorado a lo ancho de las demás
 * tarjetas— en vez de tener el suyo: dos botones iguales con dos reglas son
 * los que un día dejan de parecerse. */
.mom-card-renta { border-left: 3px solid var(--exc-accent); }
.mom-card-renta .mom-card-tit strong { white-space: normal; line-height: 1.25; }

/* ── Los renglones de «Atención y enlaces» ──────────────────────────────────
 *
 * El buzón y la página de daClic contestan la misma pregunta —«¿cómo les digo
 * algo?»— así que comparten caja. Sueltas competían con el mapa, que es otra
 * cosa. */
.mom-fila {
  display: flex;
  align-items: center;
  gap: .7rem;
  width: 100%;
  padding: .6rem .5rem;
  border: 0;
  border-radius: var(--exc-radius-sm, 10px);
  background: transparent;
  color: var(--exc-text);
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.mom-fila:hover { background: var(--exc-surface-2, color-mix(in srgb, var(--exc-text) 5%, transparent)); }

.mom-fila-ico {
  flex: none;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  color: var(--exc-accent);
  font-size: 1.1rem;
}

.mom-fila-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .05rem; }

.mom-fila-txt strong { font-size: .93rem; font-weight: 600; }

/* La segunda línea SE PARTE, no se recorta: «Quejas, sugerencias y comentarios»
   no cabe de una en un rail de 21rem, y cortada con puntos suspensivos pierde
   justo la palabra que le dice a alguien que ahí también caben las cosas
   buenas. */
.mom-fila-txt small {
  font-size: .79rem;
  line-height: 1.35;
  color: var(--exc-muted);
}

/* La de daClic sí: es una DIRECCIÓN, y partida en dos renglones deja de
   leerse como una dirección. */
.mom-fila-daclic .mom-fila-txt small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mom-fila-mas { flex: none; color: var(--exc-muted); }

/* Y el de daClic con SU color: la manita es de ellos, no de aquí. Mismo tono en
   claro y en noche — un logotipo no sigue el tema de quien lo mira. */
/* Todo el renglón con el tono legible, la manita incluida: a tamaño de
   letra un trazo se lee como texto, y con el índigo de marca quedaba más
   apagada que su propia dirección. */
.mom-fila-daclic .mom-fila-ico,
.mom-fila-daclic .mom-fila-mas,
.mom-fila-daclic .mom-fila-txt small { color: var(--exc-accent); }

.mom-fila-daclic .mom-fila-txt small { font-weight: 500; }

/* ── La pastilla de «Servicio activo» ───────────────────────────────────────
 *
 * MUESTRA, como el mapa: hoy nadie contesta si la ruta está operando en este
 * momento. El punto va en verde y NO en el acento del sitio porque es un
 * semáforo, no una marca: el oro de Exclivia aquí se leería como decoración.
 */
.mom-card-estado {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  font-size: .78rem;
  color: var(--exc-muted);
  white-space: nowrap;
}

.mom-card-estado::before {
  content: "";
  width: .5rem;
  height: .5rem;
  border-radius: 50%;
  background: #22c55e;
  /* El halo es lo que lo hace leerse como «encendido» y no como una viñeta. */
  box-shadow: 0 0 0 .2rem color-mix(in srgb, #22c55e 25%, transparent);
}

/* ── Guía inteligente ───────────────────────────────────────────────────────
 *
 * Texto a la izquierda y la muestra del mapa a la derecha. En el rail (21rem)
 * la imagen se queda en 7.5rem y el texto ocupa lo que sobra; por debajo de
 * 380 px de tarjeta la imagen se va, porque con ella el botón azul se queda
 * sin ancho y el párrafo sale a una palabra por renglón.
 */
/* La cabecera al ancho entero y el cuerpo debajo en dos: con la imagen al lado
   de la cabecera, «Guía inteligente» se partía en dos renglones. */
.mom-guia-cuerpo { display: flex; align-items: center; gap: .8rem; }

.mom-guia-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .5rem; }

.mom-guia-q { margin: 0; font-size: .92rem; font-weight: 600; }
.mom-guia-p { margin: 0; font-size: .82rem; line-height: 1.4; color: var(--exc-muted); }

.mom-guia-img {
  flex: none;
  width: 6.5rem;
  align-self: center;
  border-radius: var(--exc-radius-sm, 10px);
  overflow: hidden;
}

.mom-guia-img img { width: 100%; height: auto; display: block; }

@media (max-width: 380px) {
  .mom-guia-img { display: none; }
}

/* El azul de la guía. Es el color del «a pie» en cualquier mapa —el mismo que
   usa la muestra— y por eso no sale del acento del sitio: aquí significa una
   cosa concreta. */
.mom-card-ico.is-azul {
  background: color-mix(in srgb, #2563eb 20%, transparent);
  color: #2563eb;
}

.mom-card-cta.is-azul {
  background: #2563eb;
  color: #fff;
  justify-content: center;
}

.mom-card-cta.is-azul span:not(.mom-card-cta-mas) { flex: none; }
/* ── Y la tira AVISA cuando no cabe ─────────────────────────────────────────
 *
 * `.exc-tabs` se desliza con la barra escondida (`scrollbar-width: none`), así
 * que una pestaña cortada no tenía NADA que la anunciara: para quien mira, no
 * existía. Sacar los verbos deja a la Ruta 21 en dos pestañas, pero un
 * restaurante con carta, tiendas y empleo sigue llegando a cinco.
 *
 * El degradado va en un pseudo-elemento PEGADO al contenedor (`sticky`), no en
 * un `absolute` sobre la tira: dentro de algo que se desplaza, un absoluto
 * viaja con el contenido y el degradado se iría con él. Y se apaga solo al
 * llegar al final, con `animation-timeline: scroll()` donde el navegador lo
 * entiende; donde no, se queda fijo y sigue diciendo lo que tiene que decir.
 */
/* La clase la pone `publico.js` MIDIENDO la tira, porque el CSS no sabe si algo
   desborda. Sin ella el degradado se pintaba siempre: con dos pestañas holgadas
   quedaba una mancha gris encima de «Acerca de», anunciando un corte que no
   existía. Se comprueba al cargar y al girar el teléfono. */
.mom-pub-tabs { position: relative; }

.mom-pub-tabs.is-desborda::after {
  content: "";
  position: sticky;
  right: 0;
  flex: none;
  /* Ancho negativo a la izquierda: el degradado se dibuja ENCIMA de la última
     pestaña en vez de empujarla, que es lo que haría un elemento de ancho real
     dentro de un flex. */
  width: 2.5rem;
  margin-left: -2.5rem;
  align-self: stretch;
  pointer-events: none;
  background: linear-gradient(to right, transparent, var(--exc-bg));
}

@supports (animation-timeline: scroll(self inline)) {
  .mom-pub-tabs.is-desborda::after {
    animation: mom-tabs-fin linear both;
    animation-timeline: scroll(self inline);
    animation-range: calc(100% - 2.5rem) 100%;
  }
  @keyframes mom-tabs-fin { to { opacity: 0; } }
}

/* El vacío DICE lo que va a pasar aquí en vez de disculparse: es la primera
   impresión de un negocio que acaba de estrenar su dirección y la mandó por
   WhatsApp. El rombo es la figura de la marca —donde otras redes ponen una
   cámara tachada, que dice «aquí no hay nada»— en el oro del acento. */
.mom-pub-vacio { padding: 2.2rem 1rem; }
.mom-pub-vacio > svg { font-size: 2.2rem; color: var(--exc-accent); --exc-ico-w: 1.25; }
.mom-pub-vacio h3 { margin: .7rem 0 .25rem; font-size: 1.1rem; font-weight: 500; color: var(--exc-text); }
.mom-pub-vacio p  { margin: 0; font-size: .9rem; }

/* ── «Acerca de» ────────────────────────────────────────────────────────── */

/* `align-content: start` o el par se separa. Cada dato es un grid de dos
   filas —rótulo y valor— y en dos columnas la fila mide lo que mida el dato
   MÁS ALTO: con el horario de siete días al lado, el de enfrente repartía su
   sobrante entre las dos filas y dejaba «QUÉ ES» arriba del todo y «Comida»
   siete renglones más abajo, como si faltara algo en medio. */

/* ── Y a partir de la tableta, todo crece ───────────────────────────────────
 *
 * Móvil primero, como el resto del archivo: lo de arriba es lo que ve un
 * teléfono y esto solo AGREGA. Al revés —escribir el escritorio y encogerlo con
 * consultas de medios— es como la ficha acabó con un retrato de 100 px ocupando
 * su propio renglón en una pantalla de 360.
 *
 * El corte va en 560 px y no en 768: a 560 ya sobra ancho para que el retrato,
 * el nombre y los botones convivan en una fila, y esperar hasta 768 dejaría a
 * las tabletas pequeñas con la maqueta apretada del teléfono. */
@media (min-width: 560px) {
  /* ── De FLEX a REJILLA, y es lo que arregla la bio ───────────────────────
   *
   * En flex los cuatro hijos se reparten como pueden y `margin-left: auto` en
   * los botones apretaba la columna del medio contra el retrato. En rejilla
   * cada uno tiene su sitio dicho: retrato, datos y botones en la fila 1, y la
   * bio cruzando las tres columnas en la 2.
   *
   * `1 / -1` SÍ vale aquí —al revés que en el rail— porque las columnas están
   * declaradas: el `-1` apunta a la última línea explícita, que existe. Con
   * filas implícitas no habría a dónde apuntar.
   *
   * El teléfono se queda en flex: ahí todo va apilado y una rejilla de tres
   * columnas sería declarar una maqueta que nadie usa. */
  .mom-pub-ficha {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: start;
    column-gap: 1.1rem;
    row-gap: .85rem;
    padding-top: 1.1rem;
  }

  .mom-pub-retrato  { grid-column: 1; grid-row: 1; }
  .mom-pub-datos    { grid-column: 2; grid-row: 1; }
  /* `start` y no `center`: los botones se alinean con el NOMBRE, que es la
     primera línea de su columna. Centrados verticalmente quedaban flotando a
     la altura del arroba. */
  .mom-pub-acciones { grid-column: 3; grid-row: 1; justify-self: end; }

  /* La bio arranca en la columna 2 —bajo el NOMBRE— y no en la 1.
     Cruzando desde la primera empieza en el borde de la tarjeta, debajo del
     retrato, y se lee como un párrafo suelto en vez de como lo que esa cuenta
     dice de sí misma. Alineada con el nombre queda dentro del bloque de
     identidad, que es donde va. Llega hasta el final (`-1`) porque debajo de
     los botones no hay nada que respetar. */
  /* El distintivo va en la fila 2 —pegado a la identidad, que es lo que
     certifica— y la bio baja a la 3 SOLO cuando lo hay. Se resuelve con
     `:has()` y no con una clase que ponga la vista: la vista ya decide si lo
     pinta, y pedirle además que avise a la rejilla es el mismo dato en dos
     sitios. */
  .mom-pub-sello    { grid-column: 2 / -1; grid-row: 2; margin-top: 0; }
  .mom-pub-bio      { grid-column: 2 / -1; grid-row: 2; margin-top: 0; }

  .mom-pub-ficha:has(.mom-pub-sello) .mom-pub-bio { grid-row: 3; }

  .mom-pub-foto { width: 6.2rem; height: 6.2rem; border-radius: 1.4rem; font-size: 1.6rem; }

  /* Tramo de en medio: aquí el nombre comparte renglón con el retrato Y con los
     botones, así que a 1.85 se parte en dos. El titular grande espera a que
     haya ancho de verdad. */
  .mom-pub-nombre { font-size: 1.5rem; }
  .mom-pub-nombre .exc-sello { width: 1.25rem; height: 1.25rem; min-width: 1.25rem; }

  .mom-pub-arroba { margin-top: .3rem; font-size: .95rem; }
  .mom-pub-bio    { font-size: 1rem; line-height: 1.55; }
  .mom-pub-donde  { margin-top: .55rem; font-size: .88rem; }
  .mom-pub-nums   { margin-top: .55rem; font-size: .88rem; }

  /* Los botones vuelven a la derecha de la ficha, en su misma fila: ahí hay
     ancho de sobra y bajarlos dejaría un renglón medio vacío. */
  .mom-pub-acciones { width: auto; margin-left: auto; }
  .mom-pub-acciones .exc-btn:not(.exc-btn-icon) { flex: 0 0 auto; }

  .mom-pub-tabs { margin-top: 1.5rem; }

  .mom-pub-vacio { padding: 3rem 1rem; }
  .mom-pub-vacio > svg { font-size: 2.6rem; }
  .mom-pub-vacio h3 { margin-top: .9rem; font-size: 1.25rem; }
  .mom-pub-vacio p  { font-size: .95rem; }
}

/* Y el titular a su tamaño, cuando hay ancho para que lo sea. */
@media (min-width: 900px) {
  .mom-pub-nombre { font-size: 1.85rem; }
  .mom-pub-nombre .exc-sello { width: 1.4rem; height: 1.4rem; min-width: 1.4rem; }
}

@media (min-width: 640px) {
  /* La BIO ocupa el renglón entero: es el único de estos datos que puede ser
     largo. Por su clase y no por ser el primero — atado a `:first-child`, una
     cuenta sin bio dejaba a «Qué es: Servicios», dos palabras, estirado de lado
     a lado. */
  /* Y DÓNDE cuando trae mapa, por lo mismo: con la dirección de cada
     sucursal y una imagen de 640 px dentro, media columna lo deja todo
     apretado contra el horario de enfrente. Por la clase y no por ser el
     último — sin locales publicados ese dato es un renglón de dos
     palabras, y estirado de lado a lado se lee como un hueco. */
}

/* ── El pie ─────────────────────────────────────────────────────────────── */

.mom-pub-pie {
  margin-top: 2.5rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--exc-border);
  text-align: center;
  font-size: .85rem;
}
.mom-pub-pie a {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  color: var(--exc-muted);
}
.mom-pub-pie a:hover { opacity: 1; color: var(--exc-text); }
.mom-pub-pie .exc-logo-img  { height: 1.1rem; width: auto; }
.mom-pub-pie .exc-logo-text { font-size: 1rem; font-weight: 600; color: var(--exc-accent); }

/* El esmerilado de una cuenta privada.
 *
 * Son bloques VACÍOS: no hay ni un dato dentro. Mandar los momentos y
 * difuminarlos con CSS dejaría el contenido entero en el HTML, a un clic
 * derecho de distancia — la misma lección del precio oculto de Comercio.
 *
 * Entonces, ¿para qué el efecto? Para DECIR que hay algo. Sin él, un perfil
 * privado se ve idéntico a uno vacío y nadie pulsaría «seguir». */
.mom-esmerilado {
  position: relative;
  margin-top: 1.5rem;
  /* `pointer-events: none` porque no hay nada que tocar aquí, y `aria-hidden`
     en el marcado porque tampoco hay nada que leerle a nadie. */
  pointer-events: none;
  user-select: none;
}

/* Imita la SILUETA de la caja de números de verdad (`.mom-pf-nums`): una barra
   de tres segmentos, del ancho del contenido. Eran tres pastillas sueltas
   centradas, y en escritorio —donde todo lo demás va a la izquierda— se leían
   como tres botones flotando en medio de la nada en vez de como los números
   que están tapando. */
.mom-esm-nums {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 1px;
  margin-bottom: 1.25rem;
  border-radius: var(--exc-radius);
  overflow: hidden;
}
.mom-esm-nums span { height: 3.4rem; }

.mom-esm-rejilla {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 3px;
}
.mom-esm-rejilla span { aspect-ratio: 1; display: block; }

/* Un degradado en movimiento muy lento: se lee como «hay contenido» sin
   parecer que la pantalla se está cargando. Quien pidió menos movimiento en su
   sistema lo ve quieto — la regla global de `base.css` apaga la animación. */
.mom-esm-nums span,
.mom-esm-rejilla span {
  background: linear-gradient(100deg,
              var(--exc-surface-2) 30%,
              var(--exc-accent-soft) 50%,
              var(--exc-surface-2) 70%);
  background-size: 300% 100%;
  animation: mom-esm 5s ease-in-out infinite;
}

@keyframes mom-esm {
  0%   { background-position: 130% 0; }
  100% { background-position: -30% 0; }
}

/* El aviso se monta ENCIMA del esmerilado y sin fondo sólido: un panel opaco
   taparía la textura y volvería a dejar la pantalla como si estuviera vacía.
 *
 * Se monta POSICIONADO y no con un margen negativo. Estaba en `-11rem`, que es
 * media rejilla en un teléfono y cualquier cosa en lo demás: la rejilla son
 * tres celdas CUADRADAS, así que su alto es el ancho del contenido — 355 px en
 * un teléfono y 692 en escritorio. El mismo número no puede centrar las dos, y
 * en escritorio el aviso quedaba enterrado en el último tercio, fuera de la
 * primera pantalla.
 *
 * El envoltorio `.mom-privado` existe solo para esto: da el `position:
 * relative` contra el que se centra. El aviso NO puede ir dentro de
 * `.mom-esmerilado` —eso lo heredaría del `aria-hidden` y del
 * `pointer-events: none`, y es justo el texto que hay que leer y poder
 * seleccionar. */
.mom-privado { position: relative; }

.mom-esm-aviso {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 1rem;
  z-index: 1;
}
.mom-esm-aviso h3 { margin-top: .5rem; }

/* La portada lleva PROPORCIÓN, no alto fijo. Y es exactamente la misma que se
 * le pide al recortador (`data-crop="4:1"` en la vista).
 *
 * Antes tenía alto fijo y ancho fluido, así que su proporción real cambiaba con
 * la pantalla: 2.5:1 en un teléfono, 5.3:1 en una tableta, 6:1 en escritorio.
 * El recorte se pedía a 3:1, y con `object-fit: cover` encima:
 *
 *   · en escritorio la foto se estiraba al ancho y se le cortaba LA MITAD del
 *     alto — la persona encuadraba con cuidado y se perdía medio encuadre;
 *   · en el teléfono se le cortaban los lados.
 *
 * Y no había forma de arreglarlo eligiendo mejor el 3:1: ningún recorte puede
 * acertarle a una caja cuya proporción depende del ancho de la ventana. Con
 * `aspect-ratio` la caja es la misma en todas partes, así que lo que se recorta
 * es EXACTAMENTE lo que se ve.
 *
 * 4:1 y no 3:1: en la columna del perfil de escritorio —unos 1150 px— un 3:1
 * son 383 px de banda, casi un quinto de la pantalla de un portátil solo para
 * el encabezado. El precio es que en un teléfono estrecho la banda queda fina,
 * y se paga a gusto: una franja fina bien encuadrada se ve mejor que una gorda
 * a la que le falta la mitad.
 */
/* ── La cabecera del perfil es UNA tarjeta ──────────────────────────────────
 *
 * Portada y ficha son hermanas en el marcado, pero se pintan como una sola
 * pieza: la portada redondea arriba, la ficha redondea abajo y el borde corre
 * de una a otra sin costura.
 *
 * Antes las dos eran transparentes y el bloque entero —foto, nombre, cifras y
 * pestañas— flotaba sobre el fondo de la página sin nada que lo delimitara. En
 * modo noche eso pasaba porque el contraste del fondo ya separa; en claro, con
 * un papel crema y una portada vacía que también es crema, no se sabía dónde
 * empezaba el perfil. Al lado, «Sobre el canal» SÍ era una tarjeta blanca, así
 * que la mitad de la pantalla tenía secciones y la otra mitad no.
 */
.mom-pf-portada {
  position: relative;
  aspect-ratio: 4 / 1;
  border: var(--exc-border-width) solid var(--exc-border);
  /* Sin borde abajo: ahí es donde empalma con la ficha, y con los dos la línea
     saldría del doble de gruesa justo en medio de la tarjeta. */
  border-bottom: 0;
  border-radius: var(--exc-radius-card) var(--exc-radius-card) 0 0;
  overflow: hidden;
  background: var(--exc-surface-2);
}
.mom-pf-portada img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Sin foto NO se pinta un recuadro gris: un degradado del acento se ve
   deliberado, y un gris permanente se ve roto. */
.mom-pf-portada.is-vacia {
  background: linear-gradient(120deg, var(--exc-accent-soft), var(--exc-surface-2) 60%);
}

.mom-pf-cambiar {
  position: absolute;
  right: .6rem;
  bottom: .6rem;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .35rem .7rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, .5);
  color: #fff;
  cursor: pointer;
  font-size: .8rem;
}

/* El salto sobre la portada lo da EL AVATAR, no la fila entera.
 *
 * Estaba en la fila (`margin-top: -2.6rem` aquí) y en el teléfono daba igual
 * —la ficha es una columna y el avatar va primero—, pero en escritorio es una
 * FILA alineada por abajo y la columna de datos es más alta que el retrato:
 * al cuadrar los pies, la cabeza de los datos se metía DENTRO de la portada.
 * Y la portada es `position: relative`, así que se pinta encima de lo que va
 * después en el flujo: «@usuario · Cuenta privada» desaparecía entero y el
 * nombre quedaba partido a la mitad.
 *
 * Subirle la capa a la ficha no era el arreglo: el texto quedaría LEGIBLE
 * sobre la foto de portada solo por casualidad, y con una portada clara no se
 * leería nada. Con el salto en el avatar, el retrato sale de la banda —que es
 * lo único que tiene que salir— y el texto empieza donde la banda acaba.
 *
 * El resultado en el teléfono es idéntico al de antes: en una columna, un
 * margen negativo en el primer hijo sube todo lo demás con él. */
.mom-pf-ficha {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .5rem;
  text-align: center;
  /* El relleno LATERAL se queda en .5rem, el que tenía. Subirlo a 1rem le
     quitaba un centímetro de ancho a la fila de cifras y «Siguiendo» se caía
     a un segundo renglón. Lo que la tarjeta necesitaba era el de ABAJO: sin
     él, el último dato queda pegado al borde de la caja. */
  padding: 0 .5rem 1.25rem;

  background: var(--exc-surface);
  border: var(--exc-border-width) solid var(--exc-border);
  border-top: 0;
  border-radius: 0 0 var(--exc-radius-card) var(--exc-radius-card);
  /* La sombra la lleva SOLO la ficha, no las dos: puesta también en la
     portada dibujaría una línea oscura cruzando la tarjeta por la mitad,
     donde la sombra de arriba cae sobre el papel de abajo. */
  box-shadow: var(--exc-shadow);
}
.mom-pf-ficha > .mom-pf-avatar { margin-top: -2.6rem; }

.mom-pf-foto { border: 4px solid var(--exc-bg); background: var(--exc-surface); }
/* El NOMBRE es el título, y el sello va dentro de él.
 *
 * Estaba al revés —el arroba de título y el nombre debajo— y se cambió con la
 * lámina de los canales: a «Deportes SLP» se llega porque alguien lo nombró, y
 * lo que hay que reconocer primero es el nombre. El arroba no se pierde: va
 * justo debajo, igual que en la página pública.
 *
 * Es TEXTO CORRIDO y no un flex con el sello de segundo hijo: en flex el nombre
 * ocupa el renglón entero como único hijo y el sello se va solo al siguiente.
 * Es la misma lección que ya costó un arreglo en la página pública. */
.mom-pf-datos h1 {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.25;
}
.mom-pf-datos h1 .exc-sello {
  display: inline-block;
  /* Alineado a la letra y no al centro de la caja: el escudo tiene más masa
     arriba y centrado se ve colgando de la línea base. */
  vertical-align: -.12em;
  margin-left: .3rem;
  width: 1.25rem; height: 1.25rem; min-width: 1.25rem;
}

/* El arroba y qué ES esta cuenta, debajo del nombre. */
.mom-pf-datos .mom-pf-arroba {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  gap: .35rem;
  margin: .3rem 0 0;
  color: var(--exc-muted);
  font-size: .9rem;
}
/* El arroba es un IDENTIFICADOR, no una frase: se escribe tal cual se registró,
   sin las ligaduras ni las mayúsculas «bonitas» de la tipografía. */
.mom-pf-at { text-transform: none; font-variant-ligatures: none; }
.mom-pf-priv {
  display: inline-flex; align-items: center; gap: .2rem;
  --exc-ico: var(--exc-muted);
}

/* Dónde está y qué es, en un renglón: las dos contestan «de dónde es esto».
   El giro era una pastilla suelta en su propia fila. */
.mom-pf-datos .mom-pf-donde {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  gap: .2rem 1rem;
  margin-top: .45rem;
  color: var(--exc-muted);
  font-size: .88rem;
}
.mom-pf-donde span { display: inline-flex; align-items: center; gap: .3rem; }
.mom-pf-donde svg { color: var(--exc-accent); }

.mom-pf-datos p { margin: .15rem 0 0; }

/* La bio, un par de puntos más chica. En un perfil es el renglón más LARGO y a
   1 rem competía con el nombre por la mirada; a .88 se lee como lo que es —el
   texto que acompaña— y de paso caben tres renglones donde antes cabían dos. */
.mom-pf-bio {
  max-width: 34rem; margin-inline: auto;
  font-size: .88rem; line-height: 1.5;
  color: var(--exc-muted);
}

/* ── La tira del canal, en el perfil ──────────────────────────────────────
 *
 * La pastilla del giro y el botón de contacto, centrados con el resto de la
 * ficha. Es lo que aquí sustituye a la caja de comentarios de un perfil de
 * negocio: no se opina debajo, se escribe al lado.
 */
.mom-pf-canal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  margin-top: .7rem;
}

/* El giro es un DATO, no una acción: pastilla neutra, sin borde de acento y sin
   nada que invite a tocarla. Al lado del botón, cualquier color la convertiría
   en un segundo botón que no lleva a ningún sitio. */
.mom-pf-giro {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .25rem .7rem;
  border: 1px solid var(--exc-border);
  border-radius: 999px;
  background: var(--exc-surface-2);
  color: var(--exc-muted);
  --exc-ico: currentColor;
  font-size: .8rem;
  font-weight: 600;
}
.mom-pf-giro svg { width: 1em; height: 1em; }

/* Y el botón, con el mismo tratamiento suave que el de la tarjeta: se distingue
   de un enlace sin volverse el elemento más gritón de un perfil. Los 44 px son
   el mínimo que se toca con el pulgar sin apuntar. */
.mom-pf-verbo {
  display: inline-flex; align-items: center; gap: .45rem;
  min-height: 44px;
  padding: .5rem 1.1rem;
  border: 1px solid transparent;
  border-radius: var(--exc-radius);
  background: var(--exc-accent-soft);
  color: var(--exc-accent);
  --exc-ico: var(--exc-accent);
  font-size: .92rem;
  font-weight: 600;
  text-decoration: none;
}
.mom-pf-verbo:hover { border-color: var(--exc-accent); color: var(--exc-accent); }
.mom-pf-verbo svg { flex: none; font-size: 1.05rem; }
.mom-pf-nums {
  display: flex;
  justify-content: center;
  gap: 1.4rem;
  margin-top: .6rem;
  font-size: .82rem;
  color: var(--exc-muted);
}
.mom-pf-nums b { display: block; font-size: 1.05rem; color: var(--exc-text); font-weight: 500; }

.mom-pf-acciones { display: flex; gap: .5rem; }

.mom-pf-sub {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  margin: 1.5rem 0 .6rem;
}
.mom-pf-sub h3 { display: flex; align-items: center; gap: .4rem; margin: 0; font-size: 1.05rem; }
.mom-pf-sub h3 svg { color: var(--exc-accent); }

.mom-pf-pets {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: .6rem;
}

.mom-pet-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .2rem;
  padding: .8rem .6rem;
  background: var(--exc-surface);
  border: var(--exc-border-width) solid var(--exc-border);
  border-radius: var(--exc-radius-card);
  text-align: center;
  color: inherit;
  font: inherit;
  cursor: default;
}
.mom-pet-card img {
  width: 4.2rem;
  height: 4.2rem;
  border-radius: 50%;
  object-fit: cover;
  margin-bottom: .3rem;
}
.mom-pet-card b { font-weight: 500; }
.mom-pet-card small { font-size: .76rem; }

.mom-pet-sin {
  display: grid;
  place-items: center;
  width: 4.2rem;
  height: 4.2rem;
  border-radius: 50%;
  background: var(--exc-accent-soft);
  color: var(--exc-accent);
  font-size: 1.6rem;
  margin-bottom: .3rem;
}

.mom-pet-nueva { cursor: pointer; border-style: dashed; }

.mom-pet-editar {
  position: absolute;
  top: .35rem;
  right: .35rem;
  display: grid;
  place-items: center;
  width: 1.8rem;
  height: 1.8rem;
  border: 0;
  border-radius: 50%;
  background: var(--exc-surface-2);
  color: var(--exc-muted);
  cursor: pointer;
  font-size: .78rem;
}

.mom-pet-foto {
  display: grid;
  place-items: center;
  width: 6rem;
  height: 6rem;
  margin: 0 auto .5rem;
  border-radius: 50%;
  background: var(--exc-surface-2);
  cursor: pointer;
  overflow: hidden;
}
.mom-pet-foto img { width: 100%; height: 100%; object-fit: cover; }

/* La rejilla de momentos del perfil. Tres columnas también en el teléfono: es
   lo que hace que se lea como «lo que publica esta persona» y no como un muro
   otra vez. */
.mom-rejilla {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 3px;
  margin-top: 1rem;
}

.mom-celda {
  position: relative;
  aspect-ratio: 1;
  border: 0;
  padding: 0;
  background: var(--exc-surface-2);
  cursor: pointer;
  overflow: hidden;
}
.mom-celda img { width: 100%; height: 100%; object-fit: cover; display: block; }

.mom-celda-txt {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
  padding: .5rem;
  font-size: .74rem;
  line-height: 1.35;
  color: var(--exc-text);
  text-align: left;
}

.mom-celda-ico {
  position: absolute;
  top: .3rem;
  right: .3rem;
  color: #fff;
  font-size: .9rem;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .6));
}

/* ── Las hojas (editar perfil, editar mascota) ───────────────────────────── */

.mom-hoja {
  position: fixed;
  inset: 0;
  z-index: 1120;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(0, 0, 0, .45);
}

.mom-hoja-caja {
  width: 100%;
  max-width: 30rem;
  max-height: 92vh;
  overflow-y: auto;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: .75rem;
  background: var(--exc-surface);
  border-radius: var(--exc-radius-card) var(--exc-radius-card) 0 0;
}

.mom-hoja-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
}
.mom-hoja-head strong { font-weight: 500; }

.mom-hoja-pie { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.mom-hoja-pie .exc-btn:only-child { margin-left: auto; }

/* ── El visor de historias ───────────────────────────────────────────────── */

.mom-visor {
  position: fixed;
  inset: 0;
  z-index: 1140;
  display: flex;
  flex-direction: column;
  /* Negro y no `--exc-surface`: una historia se mira, y cualquier fondo con
     tinta compite con la foto. Es la única pantalla del sitio que no cambia
     con el tema, a propósito. */
  background: #000;
  color: #fff;
  touch-action: none;
}

.mom-visor-barras {
  display: flex;
  gap: 3px;
  padding: .5rem .6rem 0;
}

.mom-visor-barra {
  flex: 1;
  height: 2.5px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .3);
  overflow: hidden;
}
.mom-visor-barra i {
  display: block;
  height: 100%;
  width: 0;
  background: #fff;
}
.mom-visor-barra.is-hecha i { width: 100%; }

.mom-visor-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  padding: .6rem .7rem;
  position: relative;
  z-index: 2;
}

.mom-visor-quien { display: flex; align-items: center; gap: .55rem; min-width: 0; }
.mom-visor-quien .exc-avatar { width: 2.1rem; height: 2.1rem; }
.mom-visor-quien b { font-weight: 500; font-size: .92rem; }
.mom-visor-quien small { display: block; font-size: .74rem; opacity: .7; }

.mom-visor-x {
  display: grid;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  border: 0;
  border-radius: 50%;
  background: none;
  color: #fff;
  cursor: pointer;
  font-size: 1.1rem;
}

.mom-visor-cuerpo {
  flex: 1;
  min-height: 0;
  display: grid;
  place-items: center;
  position: relative;
  overflow: hidden;
}
.mom-visor-cuerpo img,
.mom-visor-cuerpo video {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

/* Un momento de solo texto también se mira: se pinta sobre el acento en grande,
   que es lo que hace que valga la pena tocarlo.
   El segundo tono se manda al 140 %, fuera del lienzo: `--exc-secondary` es un
   ocre oscuro y el texto va en `--exc-accent-contrast`, que está calculado para
   contrastar con el ACENTO. Con la parada dentro, la esquina de abajo dejaba
   texto oscuro sobre fondo oscuro. */
.mom-visor-solotexto {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  padding: 2rem;
  background: linear-gradient(150deg, var(--exc-accent), var(--exc-secondary) 140%);
  color: var(--exc-accent-contrast);
  font-size: clamp(1.2rem, 5vw, 2rem);
  line-height: 1.35;
  text-align: center;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.mom-visor-pie {
  padding: .5rem .7rem 1rem;
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: .5rem;
}
.mom-visor-pie .mom-visor-txt { font-size: .95rem; white-space: pre-line; overflow-wrap: anywhere; }

.mom-visor-react { display: flex; gap: .25rem; justify-content: center; }
.mom-visor-react .mom-react { color: rgba(255, 255, 255, .75); }

/* Aquí las seis se ven SIEMPRE, también las que están en cero.
 *
 * En el muro se colapsan porque son doce tarjetas en una pantalla que se
 * recorre con el pulgar; esto es lo contrario: una historia a la vez, a
 * pantalla completa, con toda la atención puesta y dos segundos para
 * contestar. Esconder cinco de las seis aquí sería pedir un toque de más
 * justo donde sobra sitio.
 *
 * Y su plantilla (`partes/visor.php`) no lleva la carita que abre el resto, así
 * que sin esta regla las que están en cero —que al clonarla son TODAS— se
 * quedaban escondidas y sin ninguna forma de sacarlas.
 *
 * Con `.is-cero` en el selector a propósito: empatar en especificidad con la
 * regla del muro y ganar por ir después deja el visor a merced de que alguien
 * reordene el archivo. */
.mom-visor-react.mom-reacciones .mom-react.is-cero { display: inline-flex; }

/* En el visor la reacción también toma SU color, pero SIEMPRE el del modo
   noche: aquí el fondo no es la superficie del tema, es la foto de alguien, y
   detrás de una historia siempre hay oscuro. Con los tonos del modo claro
   —pensados para leerse sobre blanco— el número se apagaba encima de una foto.
 *
 * La regla es de dos clases igual que `.mom-react.is-mia`, así que ganaría por
 * ORDEN si estuviera antes; está aquí abajo a propósito. Cambiarla de sitio la
 * rompe sin que nada avise: es la misma trampa de especificidad que ya cazó
 * dos veces `scripts/css_posiciones.php` en el calendario.
 *
 * Y el fondo es blanco translúcido, no el tinte de la reacción: sobre una foto
 * cualquiera, un tinte de color al 16 % no se ve, y lo que hace falta ahí es
 * separar el botón de la imagen. */
.mom-visor-react .mom-react.is-mia {
  color: var(--mom-r, var(--exc-accent));
  background: rgba(255, 255, 255, .14);
}

.mom-visor-react .mom-react[data-mom-react="love"]   { --mom-r: #ff6b93; }
.mom-visor-react .mom-react[data-mom-react="fuego"]  { --mom-r: #ff8f40; }
.mom-visor-react .mom-react[data-mom-react="risa"]   { --mom-r: #f0c040; }
.mom-visor-react .mom-react[data-mom-react="wow"]    { --mom-r: #a790ff; }
.mom-visor-react .mom-react[data-mom-react="patita"] { --mom-r: #48d199; }
.mom-visor-react .mom-react[data-mom-react="avion"]  { --mom-r: #8ab4dd; }

/* Las dos mitades invisibles: en un teléfono se avanza tocando, no buscando un
   botón. Van DEBAJO del pie y del encabezado (z-index 1) para no tragarse el
   toque en la X ni en las reacciones. */
.mom-visor-lado {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 32%;
  border: 0;
  background: none;
  cursor: pointer;
  z-index: 1;
}
.mom-visor-prev { left: 0; }
.mom-visor-next { right: 0; width: 68%; }

/* ── La columna de al lado, ya en pantalla grande ────────────────────────── */

@media (min-width: 992px) {
  .mom {
    grid-template-columns: minmax(0, 1fr) 21rem;
    align-items: start;
    gap: 1.5rem;
  }

  .mom-rail {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    position: sticky;
    /* Debajo de la barra superior, que es fija. */
    top: 5rem;

    /* ── Y RECORRIBLE cuando no cabe ──────────────────────────────────────
     *
     * Un `sticky` más alto que la ventana esconde su final PARA SIEMPRE: se
     * queda clavado arriba y lo que sobresale por abajo no se alcanza por mucho
     * que se baje la página — porque bajar la página no mueve el rail.
     *
     * Medido en el canal @guiapotosina, que lleva video + «Sobre el canal» +
     * «Herramientas de tu canal»: el rail pide 963 px y una laptop de 900 deja
     * 820, así que **143 px quedaban fuera**; en una pantalla de 720, 287. La
     * tarjeta de herramientas no se veía entera ni bajando del todo, que es
     * exactamente como se reportó.
     *
     * No se arregla encogiendo el video: mide 597 px porque los clips son 9:16
     * y recortarlo se come la mitad del plano — eso ya está decidido y escrito
     * en `.mom-intro`. Se arregla dejando que el rail se recorra por dentro.
     *
     * `6rem` = las `5rem` del `top` más `1rem` de aire abajo, para que la
     * última tarjeta no quede pegada al borde de la ventana.
     *
     * `overscroll-behavior: contain` es la mitad que no es obvia: sin él, al
     * llegar al final del rail el gesto SIGUE y arrastra la página de detrás —
     * se baja el rail y de pronto salta todo el muro. */
    max-height: calc(100vh - 6rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    /* Fina pero VISIBLE. Escondida (`none`, como en las tiras horizontales de
       esta misma hoja) no habría nada que anunciara que hay más abajo, que es
       el fallo que se venía a arreglar. */
    scrollbar-width: thin;
  }

  /* Y esta línea es la que hace que lo de arriba SIRVA.
   *
   * En un flex de columna con la altura limitada, los hijos traen
   * `flex-shrink: 1` de fábrica: en vez de desbordar, se APLASTAN para caber.
   * Medido con el `max-height` ya puesto y sin esto: `scrollHeight` y
   * `clientHeight` valían los mismos 804 px —o sea, nada que recorrer— y la
   * tarjeta de abajo seguía cortada, ahora además con el video espachurrado.
   *
   * Con `0`, cada tarjeta conserva su alto, el rail desborda de verdad y el
   * `overflow` de arriba tiene por fin algo que desplazar. */
  .mom-rail > * { flex-shrink: 0; }

  /* El compositor deja de ser una hoja: en escritorio hay sitio de sobra y
     abrir a pantalla completa para escribir dos renglones es violento.

     `sticky` y no `static`: abierto tiene que quedarse pegado igual que
     cerrado. Con `static` daba un salto al abrirlo —se despegaba de la barra y
     se iba con el desplazamiento— y otro al cerrarlo. La regla del pegado vive
     más abajo, en su bloque de 1024 px; ésta solo tiene que no deshacerla.

     `inset: auto` deshace el `inset: 0` de la hoja: heredado, un `sticky` con
     las cuatro anclas puestas se comporta como si estuviera clavado arriba a
     la izquierda de la columna. */
  .mom-comp.is-abierto {
    position: sticky;
    inset: auto;
    border: var(--exc-border-width) solid var(--exc-border);
    border-radius: var(--exc-radius-card);
  }

  .mom-hoja { align-items: center; }
  .mom-hoja-caja { border-radius: var(--exc-radius-card); }

  /* `flex-start` y no `flex-end`. Cuadrando los PIES, la columna de datos
     —que es más alta que el retrato— crecía hacia ARRIBA y se metía debajo de
     la portada. Cuadrando las cabezas, el bloque de texto empieza donde acaba
     la banda y crece hacia abajo, que es hacia donde hay sitio. El retrato
     sigue montado sobre la portada por su propio margen negativo. */
  .mom-pf-ficha { flex-direction: row; align-items: flex-start; text-align: left; gap: 1.2rem; }
  /* Un pelo de aire para que el arroba no salga pegado al filo de la banda. */
  .mom-pf-datos { flex: 1; min-width: 0; padding-top: .35rem; }
  .mom-pf-acciones { margin-top: .35rem; }
  .mom-pf-nums { justify-content: flex-start; }
  .mom-pf-bio { margin-inline: 0; }
  /* La portada YA NO cambia de alto aquí: su proporción es una sola para todas
     las pantallas, que es lo único que hace que el encuadre elegido sea el que
     se ve. Un alto distinto en escritorio era justo lo que rompía el recorte. */

  .mom-rejilla { gap: 6px; }

  /* El visor no ocupa la pantalla entera con el ratón: una historia vertical
     estirada a 1920 px de ancho es una foto de 400 px con dos franjas negras.

     El texto de dentro ya no se acota aparte —lo acota su lienzo—, o quedaba
     una plancha de color ancha con el texto encogido en medio. */
  .mom-visor-cuerpo img,
  .mom-visor-cuerpo video { max-width: 26rem; border-radius: var(--exc-radius-card); }

  /* Al lienzo se le acota el ALTO y no el ancho.
     Fijando las dos medidas, `aspect-ratio` deja de mandar y el fondo se
     estiraba a 9:19 o a lo que saliera: la historia dejaba de tener la forma
     con la que se decoró. 26 rem de ancho son 46 rem de alto en 9:16. */
  .mom-visor-lienzo { max-height: 46rem; border-radius: var(--exc-radius-card); }
}

/* ── Las piezas de la columna ────────────────────────────────────────────── */

.mom-yo { position: relative; padding: 0 1rem 1rem; text-align: center; overflow: hidden; }

.mom-yo-portada {
  height: 4.5rem;
  margin: 0 -1rem .5rem;
  background: linear-gradient(120deg, var(--exc-accent-soft), var(--exc-surface-2) 70%);
}
.mom-yo-foto { margin-top: -2.6rem; border: 3px solid var(--exc-surface); }
.mom-yo strong { display: block; margin-top: .4rem; font-weight: 500; }
.mom-yo-bio { margin: .5rem 0 0; font-size: .85rem; }

.mom-yo-nums {
  display: flex;
  justify-content: space-around;
  gap: .5rem;
  margin: .9rem 0;
  padding: .7rem 0;
  border-top: 1px solid var(--exc-border);
  border-bottom: 1px solid var(--exc-border);
  font-size: .72rem;
  color: var(--exc-muted);
}
.mom-yo-nums b { display: block; font-size: 1rem; color: var(--exc-text); font-weight: 500; }

.mom-yo-mascotas { display: flex; flex-direction: column; gap: .4rem; margin-bottom: .8rem; }

.mom-mascota-chip {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .4rem .5rem;
  border-radius: var(--exc-radius-sm);
  background: var(--exc-surface-2);
  text-align: left;
}
.mom-mascota-chip img { width: 2.1rem; height: 2.1rem; border-radius: 50%; object-fit: cover; }
.mom-mascota-chip b { display: block; font-size: .82rem; font-weight: 500; }
.mom-mascota-chip small { font-size: .72rem; }

.mom-mascota-ico {
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  background: var(--exc-accent-soft);
  color: var(--exc-accent);
}

.mom-sug, .mom-pets, .mom-market, .mom-ciudad { padding: .9rem 1rem; }

/* ── La tarjeta de mi ciudad ──────────────────────────────────────────────
 *
 * Lo primero de la columna. Dice qué ciudad está filtrando «Mi ciudad» —que
 * hasta hoy no se decía en ninguna parte— y es por donde se cambia. */
.mom-ciudad { display: flex; flex-direction: column; gap: .45rem; }

.mom-ciudad-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
}
.mom-ciudad-tit { display: inline-flex; align-items: center; gap: .4rem; min-width: 0; }
.mom-ciudad-tit svg { flex: 0 0 auto; color: var(--exc-accent); }
.mom-ciudad-tit b {
  font-size: 1.02rem;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mom-ciudad-cambiar {
  display: inline-flex;
  align-items: center;
  gap: .15rem;
  flex: 0 0 auto;
  color: var(--exc-muted);
  font-size: .76rem;
  white-space: nowrap;
}
.mom-ciudad-cambiar:hover { opacity: 1; color: var(--exc-accent); }
.mom-ciudad-cambiar svg { font-size: .85rem; }

/* La silueta. Muy apagada y con el trazo fino: es el fondo de la tarjeta, no
   un dibujo que haya que mirar. `opacity` y no un color a mano —que rompería
   el panel de Apariencia— porque tiene que apagarse igual en los dos modos. */
.mom-ciudad-arte {
  display: flex;
  justify-content: center;
  color: var(--exc-muted);
  opacity: .42;
}
.mom-ciudad-arte svg { font-size: 4.4rem; --exc-ico-w: 1; }

.mom-ciudad-nota { margin: 0; font-size: .8rem; line-height: 1.35; text-align: center; }
.mom-ciudad-alt { display: block; text-align: center; }
.mom-sug h4, .mom-pets h4, .mom-market h4 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .4rem;
  margin: 0 0 .7rem;
  font-size: .95rem;
  font-weight: 500;
}
.mom-pets h4 { justify-content: flex-start; }
.mom-pets h4 svg { color: var(--exc-accent); }

.mom-sug-fila { display: flex; align-items: center; gap: .55rem; padding: .35rem 0; }
.mom-sug-txt { flex: 1; min-width: 0; line-height: 1.25; }
.mom-sug-txt b { display: block; font-size: .85rem; font-weight: 500; }
.mom-sug-txt small { display: block; font-size: .74rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mom-sug-txt a { color: inherit; }

.mom-pets-tira { display: grid; grid-template-columns: repeat(4, 1fr); gap: .4rem; }

.mom-pet { text-align: center; color: inherit; min-width: 0; }
.mom-pet img { width: 100%; aspect-ratio: 1; border-radius: var(--exc-radius-sm); object-fit: cover; }
.mom-pet b { display: block; font-size: .72rem; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mom-pet small { font-size: .66rem; }

.mom-market-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }

.mom-market-item { color: inherit; min-width: 0; }
.mom-market-item img,
.mom-market-sin {
  width: 100%;
  aspect-ratio: 1;
  border-radius: var(--exc-radius-sm);
  object-fit: cover;
  display: block;
}
.mom-market-sin { display: grid; place-items: center; background: var(--exc-surface-2); color: var(--exc-muted); }
.mom-market-item b { display: block; margin-top: .25rem; font-size: .76rem; font-weight: 400; line-height: 1.25; }
.mom-market-item small { font-size: .76rem; color: var(--exc-accent); font-weight: 500; }

/* La dirección pública del perfil, dentro de la hoja de editar. */
.mom-url {
  display: flex;
  align-items: center;
  gap: .4rem;
  padding: .35rem .35rem .35rem .7rem;
  background: var(--exc-surface-2);
  border: var(--exc-border-width) solid var(--exc-border);
  border-radius: var(--exc-radius-sm);
}
.mom-url code {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--exc-accent);
}

/* ── La tarjeta de perfil DENTRO del menú lateral ─────────────────────────── */

/* Vive en la ranura que abre `layouts/sidebar.php`, encima de los enlaces. Se
   movió aquí desde la columna derecha: con el menú a la izquierda, tener la
   tarjeta al otro lado dejaba las dos cosas que hablan de la misma persona en
   extremos opuestos y el muro apretado en el canal de en medio.

   Sin `position` propia y sin `z-index`: el menú ya es `fixed` y una regla que
   le ponga `relative` a un hijo suyo es exactamente la trampa que caza
   `scripts/css_posiciones.php`. */
.exc-sidebar-top {
  padding: 0 .75rem .75rem;
  margin-bottom: .5rem;
  border-bottom: 1px solid var(--exc-border);
}

.mom-side {
  position: relative;
  border-radius: var(--exc-radius-card);
  background: var(--exc-surface-2);
  overflow: hidden;
  text-align: center;
  padding-bottom: .7rem;
}

.mom-side-portada {
  height: 3.6rem;
  background: linear-gradient(120deg, var(--exc-accent-soft), var(--exc-surface-2) 70%);
  background-size: cover;
  background-position: center;
}

.mom-side-yo {
  display: block;
  margin-top: -2.1rem;
  padding: 0 .6rem;
  color: inherit;
}
.mom-side-yo:hover { opacity: 1; }
.mom-side-yo strong {
  display: block;
  margin-top: .3rem;
  font-size: .92rem;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mom-side-yo small { font-size: .76rem; }

.mom-side-foto {
  border: 3px solid var(--exc-surface-2);
  background: var(--exc-surface);
}

.mom-side-bio {
  margin: .45rem .7rem 0;
  font-size: .78rem;
  color: var(--exc-muted);
  /* Dos renglones y basta: la barra es angosta y una bio de 160 caracteres
     empujaría los enlaces fuera de la pantalla en un portátil. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.mom-side-mascota {
  display: flex;
  align-items: center;
  gap: .45rem;
  margin: .6rem .6rem 0;
  padding: .3rem .45rem;
  border-radius: 999px;
  background: var(--exc-surface);
  color: inherit;
  text-align: left;
}
.mom-side-mascota img { width: 1.8rem; height: 1.8rem; border-radius: 50%; object-fit: cover; }
.mom-side-mascota .mom-mascota-ico { width: 1.8rem; height: 1.8rem; font-size: .9rem; }
/* `min-width: 0` en el hijo, no en el padre. Un elemento flex NO baja de su
   contenido por su cuenta (`min-width: auto`), así que con la raza y la edad
   juntas —«Pastor Ovejero Magallánico · 12 años»— el renglón empujaba la
   píldora fuera de la barra en vez de cortarse. Es la misma trampa del
   `absolute` sin ancla que ya cazó el revisor de posiciones. */
.mom-side-mascota > span { min-width: 0; }
.mom-side-mascota b,
.mom-side-mascota small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mom-side-mascota b { display: block; font-size: .76rem; font-weight: 500; }
.mom-side-mascota small { display: block; font-size: .68rem; }

/* El cumpleaños sale del gris de la raza: es el ÚNICO dato de esta tarjeta que
   caduca en 24 horas, y del mismo color no lo vería nadie.

   NO con `var(--exc-accent)`. Medido: el acento da 2.31:1 sobre la píldora
   blanca del modo claro, y esto es texto de 11 px —hacen falta 4.5:1—. Es la
   misma trampa del `--exc-accent-soft` que solo servía de día. Se usa el par
   dorado que ya está medido en las reacciones: 5.8:1 en claro y 12:1 en noche.

   El tamaño del icono NO se escribe: `.exc-ico` va en `em` y crece con su
   renglón solo. */
.mom-side-mascota .mom-cumple { color: #8a5e00; }
[data-theme="dark"] .mom-side-mascota .mom-cumple { color: #f0c040; }
.mom-side-mascota .mom-cumple .exc-ico { vertical-align: -.14em; margin-right: .18em; }

.mom-side-nums {
  display: flex;
  justify-content: space-around;
  gap: .3rem;
  margin: .7rem .4rem 0;
  padding-top: .6rem;
  border-top: 1px solid var(--exc-border);
  font-size: .66rem;
  color: var(--exc-muted);
}
.mom-side-nums b {
  display: block;
  font-size: .92rem;
  color: var(--exc-text);
  font-weight: 500;
}

/* Publicar, debajo de la tarjeta de quien mira.
   En un muro, escribir es LA acción, y con ratón no había ni un sitio fijo
   desde donde hacerlo: el renglón de arriba se va con el primer desplazamiento
   y el aro de «Crear» también. Aquí se queda quieto. */
.mom-side-publicar {
  gap: .45rem;
  margin: .8rem .4rem .2rem;
  /* El ancho lo pone `-block`; esto solo lo separa del borde del cajón, que en
     el teléfono es un cajón de verdad y pega los botones al filo. */
  width: auto;
}

/* El botón de «Historia» encendido tiene que verse a un metro: es el que decide
   si la cara de uno aparece arriba del muro de todos sus seguidores. Un `is-on`
   igual que el de los demás botones —solo un fondo más claro— era demasiado
   discreto para eso. */
.mom-comp-hist.is-on {
  background: var(--exc-accent);
  color: var(--exc-accent-contrast);
}
.mom-comp-hist.is-on svg { color: var(--exc-accent-contrast); }

/* Y dicho con letras. No es un `exc-hint` gris: es la consecuencia de lo que se
   acaba de encender, y tiene que leerse. */
.mom-comp-aviso {
  display: flex;
  align-items: flex-start;
  gap: .45rem;
  margin: 0;
  padding: .5rem .65rem;
  border-radius: var(--exc-radius-sm);
  background: var(--exc-accent-soft);
  color: var(--exc-text);
  font-size: .8rem;
  line-height: 1.4;
}
.mom-comp-aviso svg { flex: 0 0 auto; color: var(--exc-accent); margin-top: .1rem; }

/* ── El estudio de la historia ────────────────────────────────────────────── */

/* Los ocho fondos. Lista CERRADA (`Momentos::FONDOS`) y el color VIVE AQUÍ: la
   base solo guarda el nombre, así que cambiar una paleta no obliga a reescribir
   ninguna fila.
   
   Son de CONTENIDO, no de interfaz, y por eso llevan color propio en vez de
   salir de los tokens del tema: una historia se ve igual para quien la publicó
   en modo claro y para quien la mira en modo noche — si cambiara con el tema de
   cada quien, no sería el diseño de nadie. Los ocho están medidos contra el
   texto blanco que llevan encima. */
.mom-fondo-noche     { background: linear-gradient(160deg, #232526, #414345); }
.mom-fondo-atardecer { background: linear-gradient(160deg, #ff7e5f, #feb47b); }
.mom-fondo-menta     { background: linear-gradient(160deg, #11998e, #38ef7d); }
.mom-fondo-durazno   { background: linear-gradient(160deg, #ee9ca7, #ffdde1); }
.mom-fondo-uva       { background: linear-gradient(160deg, #654ea3, #eaafc8); }
.mom-fondo-oceano    { background: linear-gradient(160deg, #2193b0, #6dd5ed); }
.mom-fondo-bosque    { background: linear-gradient(160deg, #134e5e, #71b280); }
.mom-fondo-oro       { background: linear-gradient(160deg, #b8860b, #f5d76e); }

/* El durazno es el único claro de los ocho: sobre él, el texto blanco no se lee.
   Se le da tinta oscura en vez de sacarlo de la paleta — es el que más se usa
   para una historia alegre. */
.mom-fondo-durazno,
.mom-fondo-durazno .mom-est-texto { color: #2b1b1e; }

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

/* El lienzo ES la historia: mismo fondo, mismo texto, mismas calcomanías. Una
   previa que se parece pero no es la misma deja decidir un encuadre y publicar
   otro. */
.mom-est-lienzo {
  position: relative;
  aspect-ratio: 9 / 16;
  max-height: 44vh;
  margin-inline: auto;
  width: 100%;
  max-width: 15.5rem;
  border-radius: var(--exc-radius-card);
  overflow: hidden;
  color: #fff;
  /* Las calcomanías se arrastran encima: sin esto el navegador se lleva el
     gesto como scroll y no hay forma de recuperarlo. */
  touch-action: none;
}

.mom-est-texto {
  position: absolute;
  inset: auto 1rem 1.2rem;
  font-size: 1rem;
  line-height: 1.35;
  text-align: center;
  white-space: pre-line;
  overflow-wrap: anywhere;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .35);
}

.mom-est-barra {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .6rem;
  flex-wrap: wrap;
}

.mom-est-fondos { display: flex; gap: .35rem; flex-wrap: wrap; }

.mom-est-fondo {
  width: 1.9rem;
  height: 1.9rem;
  border: 2px solid transparent;
  border-radius: 50%;
  cursor: pointer;
  padding: 0;
}
.mom-est-fondo.is-on { border-color: var(--exc-text); }

.mom-est-ayuda { margin: 0; text-align: center; }

/* ── Las calcomanías ──────────────────────────────────────────────────────── */

/* La misma clase en el estudio y en la historia publicada: es lo que garantiza
   que lo que se colocó es lo que se ve. La posición va en PORCENTAJE —el `left`
   y el `top` los escribe el JS— porque una historia se mira en un teléfono de
   360 px y en un monitor, y en píxeles la calcomanía que se puso sobre una cara
   aparecería en el hombro. */
.mom-sticker {
  position: absolute;
  /* El centrado vive AQUÍ y la escala en su variable: si el JS escribiera el
     `transform` entero, borraría el centrado y la calcomanía saltaría al
     escalarla. */
  transform: translate(-50%, -50%) scale(var(--mom-s, 1));
  font-size: 2.2rem;
  line-height: 1;
  cursor: grab;
  user-select: none;
  touch-action: none;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .35));
}
.mom-sticker.is-elegida { outline: 2px dashed rgba(255, 255, 255, .9); outline-offset: 4px; }

/* En la historia YA PUBLICADA no se toca ni se arrastra: solo se mira. */
.mom-visor .mom-sticker,
.mom-card .mom-sticker { cursor: default; pointer-events: none; }

.mom-sticker-barra {
  position: absolute;
  left: 50%;
  bottom: .5rem;
  transform: translateX(-50%);
  display: flex;
  gap: .25rem;
  padding: .25rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, .6);
}
.mom-sticker-barra button {
  width: 1.9rem;
  height: 1.9rem;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .18);
  color: #fff;
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
}

/* ── La historia con estilo, en el visor ──────────────────────────────────── */

/* Reemplaza al degradado del acento que traía `.mom-visor-solotexto`: ahora el
   fondo lo elige quien publica. Sin estilo se queda el de antes. */
/* El lienzo es una HISTORIA: 9:16, del alto que quepa y el ancho detrás.
 *
 * Con `width: 100%` se estiraba a todo el cuerpo del visor: en un monitor el
 * fondo cubría 1 900 px, el texto quedaba perdido en medio de una plancha de
 * color y las calcomanías —que van en porcentaje— se iban a los extremos. Una
 * historia tiene forma, y esa forma es la misma en la que se decoró.
 *
 * Manda el ALTO y el ancho sale de la proporción: al revés, en una ventana baja
 * el lienzo se salía por abajo. `max-width: 100%` es el freno para una ventana
 * más ancha que alta. */
.mom-visor-lienzo {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 9 / 16;
  height: 100%;
  width: auto;
  max-width: 100%;
  margin-inline: auto;
  overflow: hidden;
  /* Blanco, igual que el estudio. Sin esto el texto salía con
     `--exc-accent-contrast` —tinta oscura— y la misma historia se veía de un
     color al decorarla y de otro al publicarla: exactamente lo que la previa
     existe para evitar. El durazno lo pisa abajo: es el único claro. */
  color: #fff;
}

/* Dentro del lienzo, el texto no trae fondo propio ni color propio: los pone el
   lienzo. Sin esto el degradado del acento se pintaba ENCIMA del fondo elegido y
   el fondo no se veía. */
.mom-visor-lienzo .mom-visor-solotexto {
  background: none;
  color: inherit;
  max-width: none;
}

/* El único fondo claro de los ocho. Va con `.mom-visor-lienzo` delante para
   ganarle al blanco de arriba por especificidad, y no por orden. */
.mom-visor-lienzo.mom-fondo-durazno { color: #2b1b1e; }

/* ── El `hidden` tiene que ganar ──────────────────────────────────────────── */

/* El atributo `hidden` del navegador es solo `display: none` en SU hoja, y
 * cualquier `display` escrito por nosotros lo pisa —el orden de la cascada pone
 * al autor por encima del navegador, sin mirar la especificidad—. Así que un
 * elemento con `display` propio y `hidden` puesto se sigue viendo.
 *
 * El resto del sitio ya lo resuelve así, componente por componente: hay siete
 * reglas `[hidden]` en `components.css` (`.exc-emoji`, `.exc-crop`,
 * `.exc-tabpanel`…). Momentos no tenía ninguna, y estos tres se apoyan en el
 * atributo para aparecer y desaparecer:
 *
 *   · `.mom-visor`   — la capa a pantalla completa de las historias
 *   · `.mom-hoja`    — editar perfil y editar mascota
 *   · `.mom-visor-x` — el botón de quitar la historia, que solo sale sobre lo mío
 *
 * Sin esto, el botón de quitar se enseñaría también sobre la historia de otra
 * persona: pulsarlo no rompería nada —el servidor comprueba el dueño y lo
 * rechaza— pero ofrecer un botón que después se rechaza es peor que no
 * ofrecerlo. */
.mom-visor[hidden],
.mom-hoja[hidden],
.mom-visor-x[hidden],
.mom-estudio[hidden] { display: none; }

/* Los dos botones del encabezado del visor, juntos y a la derecha. Sueltos, el
   `justify-content: space-between` de la barra dejaba el de quitar en mitad del
   encabezado, flotando sobre la historia. */
.mom-visor-acciones { display: flex; align-items: center; gap: .1rem; flex: 0 0 auto; }

/* El estudio, en pantalla grande: el lienzo a un lado y las opciones al otro.
 *
 * Apilados, el compositor abierto medía más que la ventana y la paleta de
 * fondos quedaba por debajo del borde — que es justo lo que hacía falta ver
 * para decidir. Al lado, todo cabe de una vez y no hay nada que bajar. En el
 * teléfono siguen apilados: ahí no hay ancho que repartir. */
@media (min-width: 992px) {
  .mom-estudio {
    display: grid;
    grid-template-columns: 15.5rem minmax(0, 1fr);
    align-items: start;
    gap: 1rem;
  }
  .mom-est-lienzo { margin-inline: 0; max-height: 34vh; }
  .mom-est-barra  { flex-direction: column; align-items: stretch; }
  .mom-est-fondos { justify-content: flex-start; }
  .mom-est-ayuda  { grid-column: 2; margin-top: -.4rem; text-align: left; }
}

/* El color propio, al final de la fila de fondos.
 *
 * Un `<input type="color">` trae su propio marco y su relleno del sistema, y al
 * lado de ocho círculos se veía como un cuadro gris pegado. Se le quita todo y
 * se le deja el color que el navegador pinta dentro, que es el que se eligió. */
.mom-est-libre {
  position: relative;
  overflow: hidden;
  cursor: pointer;
  /* La rejilla de cuadros: dice «aquí eliges tú» sin una etiqueta al lado. Se
     ve solo mientras el color no se ha tocado, porque el propio input la tapa
     en cuanto tiene valor. */
  background:
    conic-gradient(from 0deg, #f0506e, #ffb020, #2ecc71, #3aa0d1, #8e6ad1, #f0506e);
}
.mom-est-libre input[type="color"] {
  position: absolute;
  inset: -25%;
  width: 150%;
  height: 150%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  /* Sin esto, Chrome le pone un marco y un relleno propios y el círculo sale
     con un cuadro dentro. */
  -webkit-appearance: none;
  appearance: none;
  opacity: 0;
}
/* Elegido: se enseña el color de verdad y se apaga la rejilla de debajo. */
.mom-est-libre.is-on { border-color: var(--exc-text); }
.mom-est-libre.is-on input[type="color"] { opacity: 1; }
.mom-est-libre input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.mom-est-libre input[type="color"]::-webkit-color-swatch { border: 0; border-radius: 50%; }

/* ── Las capas ────────────────────────────────────────────────────────────────
 *
 * El sitio tiene su escala y hay que respetarla, porque el marco (barra y menú)
 * es `position: fixed` y no se aparta:
 *
 *     1030  la barra de arriba
 *     1050  el menú lateral
 *     1200  las ventanas del sitio (recortador de imagen, selector de iconos)
 *     2000  los avisos flotantes — por encima de todo, interrumpen
 *
 * Momentos nació con 60, 70, 75 y 80, que son números perfectamente razonables
 *… y que dejaban TODAS sus capas a pantalla completa por debajo del menú. El
 * síntoma engañaba: el visor de historias se abría bien y se veía casi entero,
 * pero su encabezado —justo donde vive el botón de borrar— caía detrás del menú,
 * así que el botón «no aparecía». Se buscó en el JavaScript, en los datos y en
 * el `hidden` antes de mirar el `z-index`.
 *
 * Las de aquí quedan entre las ventanas del sitio y los avisos, en el orden en
 * que se abren unas sobre otras:
 *
 *     1110  el compositor a pantalla completa (celular)
 *     1120  las hojas de perfil y mascota
 *     1130  el recortador de video    (se abre DESDE el compositor)
 *     1135  la ficha del momento      (se abre tocando una foto del muro)
 *     1140  el visor de historias
 *
 * Van por DEBAJO de las ventanas del sitio a propósito: el recortador de imagen
 * (1200) se abre DESDE la hoja de la mascota, y el selector de emojis desde el
 * compositor. Poner las de aquí por encima las habría dejado a las dos
 * enterradas —el recortador se abriría detrás de la hoja que lo llamó— que es
 * el mismo error, solo que al revés.
 *
 * Regla: cualquier capa nueva de este módulo va en este rango y se anota aquí.
 */

/* ══ La ficha del momento ═══════════════════════════════════════════════════
 *
 * Tocar una foto del muro la abre aquí y NO en otra pestaña. La foto manda —es
 * lo que se vino a ver— y los datos van debajo en el teléfono y al lado en el
 * escritorio, que es donde sí hay ancho para las dos cosas a la vez.
 *
 * Capa 1135: por encima del menú del sitio (1050) y por debajo del visor de
 * historias (1140) y del recortador (1200). Ver el bloque «Las capas» de arriba.
 */
.mom-ficha {
  position: fixed; inset: 0; z-index: 1135;
  display: flex; align-items: center; justify-content: center;
}

/* Sin esto el `hidden` no vale nada: un `display` de autor le gana siempre al
   atributo, y la ficha se quedaría abierta encima del muro para siempre. */
.mom-ficha[hidden] { display: none; }

.mom-ficha-back {
  position: absolute; inset: 0;
  background: rgba(0, 0, 0, .82);
  backdrop-filter: blur(2px);
}

.mom-ficha-x {
  position: absolute; top: .8rem; right: .8rem; z-index: 2;
  display: grid; place-items: center;
  width: 2.4rem; height: 2.4rem;
  color: #fff;
  background: rgba(0, 0, 0, .5);
  border: 0; border-radius: 999px;
  cursor: pointer;
}
.mom-ficha-x:hover { background: rgba(0, 0, 0, .75); }

.mom-ficha-panel {
  position: relative;
  display: flex; flex-direction: column;
  width: min(1100px, 100%);
  /* ── Altura DEFINIDA, no solo un tope ───────────────────────────────────
   *
   * `max-height` sola deja la altura en `auto`, o sea salida del contenido —
   * y entonces el `flex: 1` de la caja de la foto no tiene espacio libre que
   * repartir. Con la tira ya fuera del flujo, esa caja se quedaba en CERO y
   * la foto desaparecía.
   *
   * Con una altura definida el reparto funciona: la caja de la foto se lleva
   * lo que el pie deje, ni un píxel más. */
  height: 100dvh;
  max-height: 100dvh;
  overflow: hidden;
}

/* ── Las fotos ─────────────────────────────────────────────────────────────
 *
 * `overflow: hidden` + una tira que se desplaza: el carrusel es una sola
 * transformación, sin una librería y sin recolocar nodos en cada paso. */
.mom-ficha-media {
  position: relative;
  flex: 1; min-height: 0;
  overflow: hidden;
}

.mom-ficha-tira {
  /* ── ANCLADA, no al 100 % ────────────────────────────────────────────────
   *
   * `height: 100%` no resolvía. Su caja —`.mom-ficha-media`— saca su altura
   * del reparto flex de la columna, y un porcentaje contra una altura que el
   * navegador todavía está calculando cae a `auto`: la tira se quedaba con el
   * alto de su CONTENIDO.
   *
   * Medido en una pantalla de 640 px: la caja medía 444 y la tira 540, así que
   * la foto sobresalía 96 px y el `overflow: hidden` se los comía. En un
   * teléfono eso es el pie del cartel cortado justo donde está la hora del
   * último partido.
   *
   * Con `inset: 0` la tira mide exactamente su caja, sea cual sea — y a partir
   * de ahí el `height: 100%` de la diapositiva y el de la imagen sí tienen
   * contra qué resolver. La caja ya era `position: relative`.
   */
  position: absolute;
  inset: 0;

  display: flex;
  transition: transform .22s ease;
  /* El gesto horizontal es NUESTRO y el vertical del navegador: con
     `touch-action: none` se mata el desplazamiento de la ficha entera, y con
     `auto` el navegador se queda el arrastre antes de que llegue el
     `preventDefault`. `pan-y` reparte cada eje a quien le toca. */
  touch-action: pan-y;
}

/* Cada foto en su diapositiva: la foto entera y su fondo esmerilado detrás.
   La que manda el ancho de la tira es la DIAPOSITIVA (`flex: 0 0 100%`), no la
   imagen — con el `flex` puesto en la imagen, el fondo quedaba fuera de la
   cuenta y el carrusel se desalineaba una foto por cada paso. */
.mom-ficha-slide {
  position: relative;
  flex: 0 0 100%;
  height: 100%;
  overflow: hidden;
}

.mom-ficha-fondo {
  position: absolute;
  inset: -8%;
  background-size: cover;
  background-position: center;
  filter: blur(26px) saturate(1.2) brightness(.5);
  pointer-events: none;
}

/* La misma caja para la foto y para el VIDEO: los dos se ven enteros dentro
   de la diapositiva. `display: block` porque un `<video>` es inline por
   omisión y su línea base dejaba una franja bajo el reproductor. */
.mom-ficha-img {
  position: relative;   /* por encima de su fondo */
  display: block;
  width: 100%; height: 100%;
  object-fit: contain;
  user-select: none; -webkit-user-drag: none;
}

.mom-ficha-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  display: grid; place-items: center;
  width: 2.6rem; height: 2.6rem;
  color: #fff;
  background: rgba(0, 0, 0, .45);
  border: 0; border-radius: 999px;
  cursor: pointer;
}
.mom-ficha-nav[hidden] { display: none; }
.mom-ficha-nav.is-prev { left: .6rem; }
.mom-ficha-nav.is-next { right: .6rem; }
.mom-ficha-nav:hover:not(:disabled) { background: rgba(0, 0, 0, .7); }

/* Deshabilitado se ATENÚA, no desaparece: un botón que se esfuma en el primer
   extremo mueve al de al lado y se acaba pulsando el que no era. */
.mom-ficha-nav:disabled { opacity: .28; cursor: default; }

.mom-ficha-puntos {
  position: absolute; left: 0; right: 0; bottom: .7rem;
  display: flex; justify-content: center; gap: .35rem;
}
.mom-ficha-puntos[hidden] { display: none; }

.mom-ficha-punto {
  width: .45rem; height: .45rem; padding: 0;
  background: rgba(255, 255, 255, .45);
  border: 0; border-radius: 999px;
  cursor: pointer;
  transition: width .18s, background .18s;
}
.mom-ficha-punto.is-on { width: 1.1rem; background: #fff; }

/* ── Los datos ─────────────────────────────────────────────────────────── */
.mom-ficha-info {
  position: relative;
  flex: none;
  max-height: 52dvh;
  overflow-y: auto;
  background: var(--exc-surface);
}

/* Nace vacío mientras llega del servidor, y un bloque vacío con fondo se ve
   como una franja de color sin motivo. */
.mom-ficha-info:empty { background: none; }

.mom-ficha-card {
  padding: .9rem 1rem 1rem;
}

.mom-ficha-card .mom-texto { margin: .5rem 0 .2rem; }

/* ── Los dos medios cuerpos de la ficha ────────────────────────────────────
 *
 * La ficha tiene dos mitades —la foto y los datos— y hay dos pantallas donde
 * solo hay una de las dos. Sin estas reglas, la mitad que falta se queda como
 * un rectángulo vacío ocupando media pantalla, que es peor que no abrir nada.
 *
 * `is-sinfoto` — un momento de SOLO TEXTO abierto desde la rejilla del perfil.
 * Ahí cada momento ocupa su cuadro publique foto o no, y desde que la celda
 * abre la ficha en vez del visor, un momento de texto también se puede abrir.
 * Antes ese caso ni existía: el visor le pintaba un lienzo de color.
 *
 * `is-solofoto` — la página pública (`exclivia.com/{usuario}`), que abre sin
 * sesión. `POST /momentos/ficha` pide cuenta, así que ahí no hay datos que
 * traer; el autor, el texto y la fecha ya están en la tarjeta de debajo.
 */
.mom-ficha.is-sinfoto  .mom-ficha-media { display: none; }
.mom-ficha.is-solofoto .mom-ficha-info  { display: none; }

/* Sin foto, los datos dejan de ser el pie de una imagen y pasan a ser TODO lo
   que hay: el tope de media pantalla los dejaría con su propia barra de
   desplazamiento teniendo la pantalla entera libre. */
.mom-ficha.is-sinfoto .mom-ficha-info { max-height: 84dvh; }

/* ── El editor ─────────────────────────────────────────────────────────── */
.mom-edit { margin: .6rem 0 .2rem; }
.mom-edit[hidden] { display: none; }

.mom-edit-txt { width: 100%; resize: vertical; min-height: 4.5rem; }

.mom-edit-pie {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  margin-top: .5rem;
}

.mom-edit-cuenta {
  font-size: .78rem; font-variant-numeric: tabular-nums;
  color: var(--exc-muted);
}
.mom-edit-cuenta.is-poco  { color: var(--exc-warning, #d08700); }
.mom-edit-cuenta.is-lleno { color: var(--exc-danger, #d33); font-weight: 700; }

.mom-edit-aud { width: auto; flex: none; }

.mom-edit-nota { margin: .45rem 0 0; }

/* La salida manual del vacío sin ciudad. Debajo del botón y en pequeño: es el
   camino largo, no la opción principal. */
.mom-vacio-alt { display: inline-block; margin-top: .6rem; }

/* ── Escritorio: la foto a la izquierda y los datos a la derecha ────────── */
@media (min-width: 900px) {
  .mom-ficha { padding: 1.2rem; }

  .mom-ficha-panel {
    flex-direction: row;
    /* Lo mismo aquí: en fila, sin altura definida la caja de la foto se
       estira a la del PIE —196 px— y la foto se encoge con ella. */
    height: calc(100dvh - 2.4rem);
    max-height: calc(100dvh - 2.4rem);
    background: var(--exc-surface);
    border-radius: var(--exc-radius);
    box-shadow: 0 24px 60px rgba(0, 0, 0, .5);
  }

  /* El lienzo de la foto va en negro también aquí: sobre el color del tema,
     una foto clara y el panel se funden y no se ve dónde acaba la imagen. */
  .mom-ficha-media { background: #0c0d10; }

  .mom-ficha-info {
    flex: 0 0 22rem;
    max-height: none;
    border-left: 1px solid var(--exc-border);
  }

  /* Con una sola mitad, el panel deja de ser de dos columnas. Sin esto la
     caja seguiría midiendo los 1100 px de siempre y la columna que queda se
     pintaría pegada a un lado, con el resto en blanco. */
  .mom-ficha.is-sinfoto .mom-ficha-panel { width: min(34rem, 100%); }

  .mom-ficha.is-sinfoto .mom-ficha-info {
    flex: 1; max-height: none;
    border-left: 0;
  }

  /* La foto sola se queda con el ancho entero y sin el fondo del tema
     asomando por la derecha. */
  .mom-ficha.is-solofoto .mom-ficha-panel { background: #0c0d10; }

  .mom-ficha-x { top: 1.8rem; right: 1.8rem; }
}

/* ══ El compositor que no se va ════════════════════════════════════════════
 *
 * En ESCRITORIO se queda pegado bajo la barra de arriba: la columna es larga y
 * quien lleva veinte momentos leídos tenía que subir hasta el principio para
 * poder escribir algo.
 *
 * En el TELÉFONO no. Ahí esa barra son 60 px de los 640 que hay, con la barra
 * de arriba y el menú de abajo ya comiendo otros 120: pegarla deja el muro en
 * media pantalla. Para eso está el botón redondo del menú de abajo, que hace
 * lo mismo sin ocupar nada mientras no se usa.
 *
 * Ojo con `.mom-comp.is-abierto`, que es `position: fixed`: gana por
 * ESPECIFICIDAD —dos clases contra una— así que abrirlo a pantalla completa
 * sigue funcionando. Es la trampa que `scripts/css_posiciones.php` caza.
 */
@media (min-width: 992px) {
  .mom-comp,
  /* Abierto TAMBIÉN, y con la misma especificidad de dos clases que la regla
     que lo desmonta como hoja: si no, aquella gana y el compositor se despega
     justo al empezar a escribir. */
  .mom-comp.is-abierto {
    position: sticky;
    /* Un pelo por debajo de la barra para que se vea que son dos cosas. */
    top: calc(var(--exc-topbar-h) + .5rem);
    /* Por encima de las tarjetas que le pasan por debajo, y muy por debajo del
       menú del sitio (1050): esto no es una capa, es contenido pegado. */
    z-index: 5;
  }
}

/* ══ Abrir con efecto de menú de videojuego ════════════════════════════════
 *
 * La hoja no sube y ya: **se pasa de largo y vuelve**. Ese rebote es lo que
 * separa un menú de juego de un panel de formulario — el `cubic-bezier` con el
 * tercer control por encima de 1 es exactamente eso.
 *
 * Y lo de dentro NO entra todo junto: el encabezado, el campo y la fila de
 * botones llegan escalonados cada 45 ms. Un panel donde todo aparece a la vez
 * se lee como una imagen; escalonado se lee como algo que se está montando, y
 * de paso el ojo llega al campo de texto justo cuando el campo llega.
 */
@keyframes mom-sube {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

@keyframes mom-entra {
  from { opacity: 0; transform: translateY(14px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

/* Solo donde de verdad SUBE. En escritorio el compositor se despliega en su
   sitio, y una animación de «entrar desde abajo» sobre un bloque que no se
   mueve se ve como un parpadeo sin motivo. El corte es el mismo 992 px donde
   deja de ser hoja. */
@media (max-width: 991px) {
  .mom-comp.is-abierto {
    animation: mom-sube .34s cubic-bezier(.22, 1.4, .36, 1) both;
  }

  .mom-comp.is-abierto .mom-comp-barra  { animation: mom-entra .3s ease-out .06s both; }
  .mom-comp.is-abierto .mom-comp-cuerpo { animation: mom-entra .3s ease-out .11s both; }
  .mom-comp.is-abierto .mom-comp-pie    { animation: mom-entra .3s ease-out .16s both; }
}

/* El velo que apaga el muro de detrás. Sin él la hoja parece flotar sobre un
   muro que sigue vivo, y en un teléfono no se distingue qué está encima. */
.mom-velo {
  position: fixed; inset: 0;
  z-index: 1105;                    /* justo debajo del compositor (1110) */
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(2px);
  animation: mom-velo-entra .28s ease-out both;
}
.mom-velo[hidden] { display: none; }

@keyframes mom-velo-entra { from { opacity: 0; } to { opacity: 1; } }

/* Quien pidió menos movimiento abre y cierra sin nada de esto. La hoja sigue
   apareciendo: lo que se quita es el viaje, no la función. */
@media (prefers-reduced-motion: reduce) {
  .mom-comp.is-abierto,
  .mom-comp.is-abierto .mom-comp-barra,
  .mom-comp.is-abierto .mom-comp-cuerpo,
  .mom-comp.is-abierto .mom-comp-pie,
  .mom-velo { animation: none; }
}

/* ══ La tira del plato ═════════════════════════════════════════════════════
 *
 * Lo que convierte una foto de comida en algo que se puede usar: de dónde es,
 * cuánto costó y qué se puede hacer con eso hoy. Va entre la foto y las
 * reacciones — primero se ve el plato, luego el dato, y al final se reacciona.
 *
 * Se lee como una ETIQUETA pegada a la foto, no como una tarjeta aparte: un
 * bloque con su propio borde y su propia sombra parece un anuncio metido en
 * medio del momento, y esto es información del momento.
 */
.mom-comida {
  margin: .1rem .9rem .2rem;
  padding: .6rem .75rem;
  border-radius: var(--exc-radius);
  background: var(--exc-surface-2);
  border-left: 3px solid var(--exc-accent);
}

/* Lo de casa se distingue por el borde, no por otro color de fondo: son la
   misma cosa —un plato— y dos fondos distintos los haría parecer dos secciones
   del muro. */
.mom-comida.is-casa { border-left-color: var(--exc-success); }

.mom-comida-linea {
  display: flex; align-items: center; gap: .5rem;
  min-width: 0;
}
.mom-comida-linea > svg { flex: none; font-size: 1.05rem; color: var(--exc-muted); }

.mom-comida-que {
  display: flex; flex-direction: column; min-width: 0; line-height: 1.3;
}
.mom-comida-que strong { font-weight: 600; font-size: .92rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mom-comida-que small  { font-size: .78rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* El precio, a la derecha y con cifras de ancho fijo. Es LA pregunta que toda
   foto de comida provoca, así que se lee sin buscarlo. */
.mom-comida-precio {
  margin-left: auto;
  flex: none;
  font-size: .92rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--exc-accent);
}

/* La receta, plegada. Abierta de entrada empujaría las reacciones fuera de la
   pantalla en cada momento de cocina. */
.mom-comida-receta { margin-top: .5rem; }
.mom-comida-receta summary {
  font-size: .82rem; font-weight: 600; color: var(--exc-accent);
  cursor: pointer; list-style: none;
}
.mom-comida-receta summary::-webkit-details-marker { display: none; }
.mom-comida-receta p {
  margin: .4rem 0 0; font-size: .86rem; line-height: 1.5;
  color: var(--exc-text); white-space: pre-line;
}

.mom-comida-pie {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  margin-top: .55rem;
}

/* «Se me antoja». Se parece a una reacción pero NO lo es —lleva su palabra
   escrita— porque hace algo distinto: guarda el lugar en tu lista. */
.mom-antojo {
  display: inline-flex; align-items: center; gap: .35rem;
  min-height: 36px;
  padding: .3rem .7rem;
  font: inherit; font-size: .8rem; font-weight: 600;
  color: var(--exc-muted);
  background: var(--exc-surface);
  border: 1px solid var(--exc-border);
  border-radius: 999px;
  cursor: pointer;
  --exc-ico: var(--exc-muted);
  transition: color .15s, border-color .15s, background .15s;
}
.mom-antojo svg { font-size: 1rem; }
.mom-antojo b { font-variant-numeric: tabular-nums; }
.mom-antojo b:empty { display: none; }
.mom-antojo:hover { color: var(--exc-text); --exc-ico: var(--exc-text); }

/* Puesto, toma el naranja del fuego —el mismo de la reacción «está buenísimo»,
   porque es el mismo gesto de apetito— y NO el acento del sitio, que aquí ya lo
   usa el precio. */
.mom-antojo.is-on {
  color: #b04600;
  border-color: #b04600;
  background: rgba(176, 70, 0, .10);
  --exc-ico: #b04600;
}
[data-theme="dark"] .mom-antojo.is-on {
  color: #ff8f40;
  border-color: rgba(255, 143, 64, .55);
  background: rgba(255, 143, 64, .14);
  --exc-ico: #ff8f40;
}

.mom-antojo.is-brinca { animation: mom-pop .26s ease-out; }
@media (prefers-reduced-motion: reduce) { .mom-antojo.is-brinca { animation: none; } }

/* Los botones de `host` empujan a la derecha: lo que HACE quien mira va a un
   lado, lo que le lleva al negocio al otro. */
.mom-comida-accion { margin-left: auto; }
.mom-comida-accion + .mom-comida-accion { margin-left: 0; }

/* ── El plato, en el compositor ──────────────────────────────────────────── */
.mom-plato {
  display: flex; flex-direction: column; gap: .5rem;
  padding: .75rem;
  border-radius: var(--exc-radius);
  background: var(--exc-surface-2);
}
.mom-plato[hidden] { display: none; }

.mom-plato-donde { display: flex; gap: .4rem; }

.mom-plato-op {
  flex: 1;
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  min-height: 42px;
  font: inherit; font-size: .85rem; font-weight: 600;
  color: var(--exc-muted);
  background: var(--exc-surface);
  border: 1px solid var(--exc-border);
  border-radius: var(--exc-radius);
  cursor: pointer;
  --exc-ico: var(--exc-muted);
}
.mom-plato-op.is-on {
  color: var(--exc-accent);
  border-color: var(--exc-accent);
  background: var(--exc-accent-soft);
  --exc-ico: var(--exc-accent);
}

.mom-plato-fila { display: flex; gap: .5rem; }
.mom-plato-fila > * { min-width: 0; }
.mom-plato-fila .exc-input:first-child { flex: 1; }
/* El precio no necesita todo el ancho y al lado del negocio se lee mejor. */
.mom-plato-precio { flex: 0 0 7.5rem; text-align: right; }

.mom-plato [hidden] { display: none; }
.mom-plato .exc-hint:empty { display: none; }

/* ══ El botón de un canal ══════════════════════════════════════════════════
 *
 * Lo que aquí sustituye al comentario. Va entre los archivos y las reacciones
 * y ocupa TODO el ancho de la tarjeta: es la acción principal de esa
 * publicación y en las otras redes es justo lo que acaba escondido en una
 * esquina, del tamaño de un enlace, debajo de una caja de comentarios.
 *
 * Es `--exc-accent-soft` y no el acento sólido a propósito. Un botón dorado
 * lleno en cada tarjeta de canal convertiría el muro en una valla publicitaria
 * y las reacciones de debajo dejarían de verse; suave, se distingue de un
 * enlace del texto sin gritar. El acento entero se lo queda «Publicar», que es
 * la única acción del sitio que hace algo irreversible.
 */
.mom-verbo { padding: .1rem .6rem .35rem; }

.mom-verbo-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  width: 100%;
  /* 44 px es el mínimo que se toca con el pulgar sin mirar. Un botón de
     llamada a la acción que hay que apuntar no se toca. */
  min-height: 44px;
  padding: .55rem .8rem;
  font-size: .92rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--exc-accent);
  background: var(--exc-accent-soft);
  border: 1px solid transparent;
  border-radius: var(--exc-radius);
  --exc-ico: var(--exc-accent);
}
.mom-verbo-btn:hover {
  border-color: var(--exc-accent);
}
/* El texto no parte renglón ni empuja la tarjeta: «Get directions» en inglés
   mide casi el doble que «Cómo llegar». */
.mom-verbo-btn span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mom-verbo-btn svg { flex: none; font-size: 1.05rem; }

/* ── Y su bloque en el compositor ────────────────────────────────────────── */
.mom-vb {
  display: flex; flex-direction: column; gap: .5rem;
  padding: .75rem;
  border-radius: var(--exc-radius);
  background: var(--exc-surface-2);
}
/* Sin esto el bloque se ve estando `hidden`: el `display` de arriba lo escribe
   esta hoja y en la cascada el autor va por encima de la hoja del navegador,
   sin mirar especificidad. Es la misma regla que ya necesitaron `.mom-visor`,
   `.mom-hoja` y `.mom-estudio`. */
.mom-vb[hidden] { display: none; }

/* Las seis pastillas en una tira que se desliza, no en una rejilla: en un
   teléfono, seis chips en columnas de 140 px se parten en tres renglones y el
   bloque tapa el texto que se estaba escribiendo. Es la trampa que ya dejó
   `.exc-choices` en el perfil. */
.mom-vb-lista {
  display: flex;
  flex-wrap: nowrap;
  gap: .4rem;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: .15rem;
}
.mom-vb-lista::-webkit-scrollbar { display: none; }
.mom-vb-lista .exc-choice { flex: none; white-space: nowrap; }

/* ══ Los círculos del perfil ═══════════════════════════════════════════════
 *
 * Mascotas e intereses en una sola tira. Sustituyen a las tarjetas grandes de
 * mascota, que gastaban media pantalla en decir la raza y la edad de dos
 * perros — eso sigue estando, pero en la ficha, que es donde se consulta.
 *
 * Se desplaza a lo ancho en vez de envolver: envolviendo, un perfil con cinco
 * intereses y tres mascotas empuja los momentos fuera de la primera pantalla,
 * y los momentos son a lo que se vino.
 */
.mom-circ {
  display: flex;
  gap: .9rem;
  padding: .25rem .2rem .1rem;
  overflow-x: auto;
  scrollbar-width: none;
}
.mom-circ::-webkit-scrollbar { display: none; }

.mom-circ-uno {
  flex: 0 0 auto;
  display: flex; flex-direction: column; align-items: center; gap: .35rem;
  width: 4.6rem;
  padding: 0;
  background: none; border: 0;
  color: var(--exc-text);
  font: inherit; font-size: .72rem;
  text-align: center;
}
button.mom-circ-uno { cursor: pointer; }

.mom-circ-uno small {
  width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--exc-muted);
}

/* El aro. Es lo que hace que la fila se lea como una tira de retratos y no
   como una barra de iconos: el borde dorado los ata a la marca y el hueco
   interior deja respirar al dibujo. */
.mom-circ-aro {
  display: grid; place-items: center;
  width: 3.5rem; height: 3.5rem;
  border-radius: 50%;
  border: 2px solid var(--exc-accent);
  background: var(--exc-surface-2);
  color: var(--exc-accent);
  --exc-ico: var(--exc-accent);
  overflow: hidden;
  transition: transform .16s ease;
}
.mom-circ-aro svg { font-size: 1.5rem; }

/* Con foto, la imagen llena el aro y el borde queda separado: pegado al retrato
   parece un error de recorte. */
.mom-circ-aro.has-foto { padding: 2px; background: var(--exc-surface); }
.mom-circ-aro.has-foto img {
  width: 100%; height: 100%;
  object-fit: cover;
  border-radius: 50%;
  display: block;
}

button.mom-circ-uno:hover .mom-circ-aro { transform: scale(1.06); }
button.mom-circ-uno:focus-visible .mom-circ-aro { outline: 2px solid var(--exc-accent); outline-offset: 2px; }

/* El «+» va en gris: es una acción, no una cosa de la persona. En dorado se
   confundiría con un interés más y se contaría como parte del retrato. */
.mom-circ-mas .mom-circ-aro {
  border-style: dashed;
  border-color: var(--exc-border);
  color: var(--exc-muted);
  --exc-ico: var(--exc-muted);
}
.mom-circ-mas small { color: var(--exc-muted); }

@media (prefers-reduced-motion: reduce) {
  .mom-circ-aro { transition: none; }
  button.mom-circ-uno:hover .mom-circ-aro { transform: none; }
}

/* ── El selector, en «Editar perfil» ─────────────────────────────────────── */

.mom-int-lista { display: flex; flex-wrap: wrap; gap: .4rem; }

/* La casilla se esconde pero SIGUE ahí: es la que envía el formulario y la que
   entiende el teclado. Con `display: none` desaparecería del orden de
   tabulación y del árbol de accesibilidad; así solo deja de verse. */
.mom-int-op input {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}

.mom-int-op { display: inline-flex; cursor: pointer; }

.mom-int-op > span {
  display: inline-flex; align-items: center; gap: .35rem;
  min-height: 38px;
  padding: .35rem .7rem;
  font-size: .82rem; font-weight: 600;
  color: var(--exc-muted);
  background: var(--exc-surface);
  border: 1px solid var(--exc-border);
  border-radius: 999px;
  --exc-ico: var(--exc-muted);
  transition: color .15s, border-color .15s, background .15s;
}

.mom-int-op input:checked + span {
  color: var(--exc-accent);
  border-color: var(--exc-accent);
  background: var(--exc-accent-soft);
  --exc-ico: var(--exc-accent);
}

/* Con el tope alcanzado, los que NO están marcados se apagan. No se
   deshabilitan a medias ni se esconden: verlos apagados dice que existen y que
   hay que soltar uno para poder tomarlos. */
.mom-int-lista.is-lleno .mom-int-op input:not(:checked) + span {
  opacity: .4;
  cursor: not-allowed;
}

.mom-int-op input:focus-visible + span { outline: 2px solid var(--exc-accent); outline-offset: 2px; }

/* ── El avatar del perfil: aro y sello ───────────────────────────────────── */

.mom-pf-avatar { position: relative; display: inline-block; flex: none; }

/* El aro dorado. Va como `box-shadow` y no como `border` porque el avatar ya
   lleva uno de 4 px del color del fondo —el que lo despega de la portada— y dos
   bordes en el mismo elemento no se pueden. Así quedan los dos: el hueco del
   fondo por dentro y el oro por fuera. */
.mom-pf-avatar .mom-pf-foto {
  box-shadow: 0 0 0 2px var(--exc-accent);
}

/* El sello, en el hombro del retrato. A las cinco en punto y no arriba: ahí
   estorbaría a la cara, que es lo que se vino a mirar. */
.mom-pf-sello {
  position: absolute;
  right: -2px; bottom: 2px;
  display: grid; place-items: center;
  width: 1.6rem; height: 1.6rem;
  border-radius: 50%;
  /* El disco del color del fondo separa el sello del retrato: encima de una
     foto oscura, el escudo azul se perdía contra el pelo. */
  background: var(--exc-bg);
}
.mom-pf-sello .exc-sello { width: 1.3rem; height: 1.3rem; min-width: 1.3rem; }

/* La cámara para cambiar la foto, en el hombro contrario al sello.
 *
 * A las SIETE en punto: el sello vive a las cinco, y dos discos en la misma
 * esquina se tapan. Los dos abajo, donde no estorban a la cara —que es lo que
 * se vino a mirar—.
 *
 * En el color del acento y no en gris: es la única cosa de este retrato que se
 * puede TOCAR, y un disco gris sobre una foto se lee como parte de la foto. */
.mom-pf-cam {
  position: absolute;
  left: -2px;
  bottom: 2px;
  display: grid;
  place-items: center;
  /* 2.1rem y no 1.6 como el sello: el sello se mira y esto se toca. Sigue
     siendo pequeño para el pulgar, y por eso el retrato entero es la zona
     cómoda: quien falle le da a la foto y no pasa nada. */
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  /* El anillo del color del fondo lo despega del retrato, igual que el sello:
     sobre una foto clara, el disco dorado se fundía con ella. */
  border: 2px solid var(--exc-bg);
  background: var(--exc-accent);
  color: var(--exc-accent-contrast);
  cursor: pointer;
  transition: transform .15s ease;
}
.mom-pf-cam:hover { transform: scale(1.06); }
.mom-pf-cam svg { font-size: 1.05rem; }

/* El foco se ve: el `<input>` de dentro está `hidden`, así que quien llega con
   el tabulador aterriza en la etiqueta y sin esto no habría forma de saberlo.
   `:focus-within` y no `:focus` — el que recibe el foco es el campo. */
.mom-pf-cam:focus-within { box-shadow: 0 0 0 3px var(--exc-accent-soft); }

@media (prefers-reduced-motion: reduce) {
  .mom-pf-cam { transition: none; }
  .mom-pf-cam:hover { transform: none; }
}

/* ── Los números, SIN caja ───────────────────────────────────────────────── */

/* Estuvieron en un recuadro con separadores —«dentro de una tabla se leen como
   una tabla»— y la lámina de los canales los saca. Tiene razón: enmarcados
   pesaban más que el nombre, y en una cuenta recién abierta eran tres ceros
   presentados como el titular de la pantalla. Sueltos y en línea se leen igual
   y dejan de competir.
   La cifra encima de su palabra, que es como se lee un número de un vistazo. */
.mom-pf-nums {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem 1.6rem;
  margin-top: .8rem;
  font-size: .76rem;
  color: var(--exc-muted);
  text-align: center;
}

.mom-pf-nums > span,
.mom-pf-nums > a {
  display: flex; flex-direction: column; gap: .1rem;
}

.mom-pf-nums b {
  display: block;
  font-size: 1.15rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--exc-text);
}

/* «Guardados» es un ENLACE y los otros tres son texto. Se le quita la
   apariencia de enlace para que la fila se lea pareja —cuatro cifras, no tres
   y un botón— y se le devuelve la señal al pasar por encima. */
.mom-pf-nums a { color: inherit; text-decoration: none; }
.mom-pf-nums a:hover b { color: var(--exc-accent); }

/* Los botones envuelven en el teléfono: «Seguir» y «Mensaje» juntos no caben
   en 360 px sin cortar el texto de uno de los dos. */
.mom-pf-acciones { flex-wrap: wrap; }

/* ══ El buscador de razas ══════════════════════════════════════════════════
 *
 * Un `<input>` de verdad con una lista debajo. No es un `<select>`: hay
 * cientos de razas y ninguna lista está completa, así que además de elegir hay
 * que poder registrar la que falte.
 */
.mom-raza { position: relative; }

.mom-raza-lista {
  position: absolute;
  top: calc(100% + 4px); left: 0; right: 0;
  z-index: 5;                    /* dentro de la hoja, por encima del campo de abajo */
  margin: 0; padding: .25rem;
  max-height: 14rem;
  overflow-y: auto;
  list-style: none;
  background: var(--exc-surface);
  border: 1px solid var(--exc-border);
  border-radius: var(--exc-radius);
  box-shadow: var(--exc-shadow-lg);
}
/* Sin esto el `hidden` no vale nada: un `display` de autor le gana al atributo
   y la lista se quedaría abierta encima del campo de la fecha. */
.mom-raza-lista[hidden] { display: none; }

.mom-raza-op {
  padding: .5rem .6rem;
  border-radius: var(--exc-radius-sm);
  font-size: .9rem;
  cursor: pointer;
}
.mom-raza-op:hover { background: var(--exc-surface-2); }

/* «Registrar “X”» se distingue de las que ya existen: es crear algo, no
   elegirlo, y confundir las dos cosas llena el catálogo de duplicados que
   alguien creyó estar eligiendo. */
.mom-raza-op.is-nueva {
  margin-top: .25rem;
  border-top: 1px solid var(--exc-border);
  border-radius: 0 0 var(--exc-radius-sm) var(--exc-radius-sm);
  color: var(--exc-accent);
  font-weight: 600;
}

/* ══ El video que se publica primero y se prepara después ═══════════════════
 *
 * Ocupa el MISMO hueco que va a ocupar el video, con su `aspect-ratio` puesta
 * desde la vista. Sin eso el muro daría un salto en el momento exacto en que
 * el clip aterriza — justo cuando la persona está mirando para comprobar que
 * entró.
 */
.mom-prep {
  position: relative;
  /* Con los MISMOS márgenes que la foto de al lado (`.mom-media`): este bloque
     ocupa su sitio exacto —es el momento mientras el video se prepara— y a
     sangre daba un salto lateral en el instante en que uno se convertía en el
     otro. */
  margin: 0 .85rem .15rem;
  overflow: hidden;
  border-radius: var(--exc-radius);
  background: var(--exc-surface-2);
}

/* La portada de verdad, entera y sin recortar: es el cuadro que el navegador
   sacó del trozo elegido. Un rectángulo gris con un texto sería exactamente la
   espera que veníamos a quitar, solo que en otro sitio. */
.mom-prep img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
}

/* Y encima, un velo. La portada tiene que verse —es lo que dice QUÉ se está
   publicando— pero atenuada, o el rótulo de arriba no se lee sobre una foto
   clara. */
.mom-prep-capa {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: .5rem;
  padding: 1rem;
  text-align: center;
  color: #fff;
  background: rgba(0, 0, 0, .55);
}
.mom-prep-capa strong { font-size: .9rem; font-weight: 500; }
.mom-prep-capa small  { font-size: .74rem; opacity: .82; max-width: 24ch; }
.mom-prep-capa .exc-ico { font-size: 1.6rem; }

/* El aro. Gira y ya: no finge un porcentaje. La subida no reporta progreso
   —`fetch` no lo da— y una barra que avanza sola es una mentira que se nota
   cuando se queda parada al 90 %. Lo que informa de verdad es el rótulo de
   al lado, que sí sabe cuánto falta. */
.mom-prep-aro {
  width: 2rem; height: 2rem;
  border: 2px solid rgba(255, 255, 255, .28);
  border-top-color: #fff;
  border-radius: 50%;
  animation: mom-prep-gira .9s linear infinite;
}
@keyframes mom-prep-gira { to { transform: rotate(360deg); } }

/* Sin animación: el aro se queda quieto y visible. Quitarlo dejaría la tarjeta
   sin ninguna señal de que algo está pasando. */
@media (prefers-reduced-motion: reduce) {
  .mom-prep-aro { animation: none; border-top-color: rgba(255, 255, 255, .6); }
}

.mom-prep-btns { display: flex; gap: .4rem; margin-top: .2rem; }

/* Falló. El velo se tiñe de rojo pero NO tapa la portada: quien llega aquí
   tiene que reconocer cuál de sus videos es el que no salió. */
.mom-prep.is-fallido .mom-prep-capa { background: rgba(120, 22, 18, .68); }
.mom-prep.is-fallido .exc-ico { color: #ffb3ac; }

/* ══ Pantalla completa ══════════════════════════════════════════════════════
 *
 * Arriba a la derecha: abajo a la izquierda está el sonido y abajo a la derecha
 * la duración. Y arriba, porque en un teléfono el pulgar cae en la mitad de
 * abajo de la pantalla — que es justo donde NO conviene tener un botón que
 * cambia de pantalla, al lado de los dos que ya están.
 */
.mom-full {
  position: absolute;
  top: .55rem;
  right: .55rem;
  display: grid;
  place-items: center;
  width: 1.9rem;
  height: 1.9rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font-size: .8rem;
  cursor: pointer;
}
.mom-full:hover { background: rgba(0, 0, 0, .78); }

/* El navegador no puede: se esconde. La clase la pone el JS UNA vez en el
   `<html>`, así que también cubre las tarjetas que llegan después por AJAX. */
.exc-sin-fs .mom-full { display: none; }

/* Los dos iconos conviven en el marcado y aquí se elige cuál se ve. */
.mom-full-out { display: none; }
.mom-video.is-full .mom-full-in  { display: none; }
.mom-video.is-full .mom-full-out { display: block; }

/* ── Dentro de la pantalla completa ────────────────────────────────────────
 *
 * `!important` sobre `aspect-ratio`, y no es pereza: la proporción se escribe
 * en el atributo `style` de la caja —es un DATO calculado en PHP, no una
 * decisión de diseño— y un estilo en línea le gana a cualquier clase. Sin esto,
 * un clip vertical a pantalla completa seguiría encajonado en su 4:5 con dos
 * franjas negras enormes arriba y abajo.
 *
 * Se declara para los dos selectores por separado: una lista con `:fullscreen`
 * y `:-webkit-full-screen` juntos la descarta ENTERA el navegador que no
 * conozca uno de los dos, y entonces no se aplicaría en ninguno.
 */
.mom-video:fullscreen {
  aspect-ratio: auto !important;
  width: 100%;
  height: 100%;
  border-radius: 0;
  background: #000;
}
.mom-video:-webkit-full-screen {
  aspect-ratio: auto !important;
  width: 100%;
  height: 100%;
  border-radius: 0;
  background: #000;
}

/* El video, entero y centrado. `contain` y no `cover`: recortar un video a
   pantalla completa es tirar la mitad de lo que se grabó, que es lo mismo que
   ya se decidió para el muro. */
.mom-video:fullscreen video          { object-fit: contain; }
.mom-video:-webkit-full-screen video { object-fit: contain; }

/* El fondo desenfocado se queda: en un monitor ancho, un clip vertical con dos
   franjas negras a los lados se ve peor que con su propio color detrás. */

/* Y los controles crecen con la pantalla: a 1.9 rem en un monitor de 27" el
   botón de salir queda del tamaño de una uña. */
.mom-video:fullscreen .mom-full,
.mom-video:fullscreen .mom-mute {
  width: 2.8rem; height: 2.8rem; font-size: 1.1rem;
  top: 1.2rem; right: 1.2rem;
}
.mom-video:fullscreen .mom-mute { top: auto; bottom: 1.2rem; left: 1.2rem; right: auto; }
.mom-video:-webkit-full-screen .mom-full,
.mom-video:-webkit-full-screen .mom-mute {
  width: 2.8rem; height: 2.8rem; font-size: 1.1rem;
  top: 1.2rem; right: 1.2rem;
}
.mom-video:-webkit-full-screen .mom-mute { top: auto; bottom: 1.2rem; left: 1.2rem; right: auto; }

/* ══ El marco esmerilado del video ══════════════════════════════════════════
 *
 * La caja del video está acotada a 460 px y centrada, y su fondo desenfocado es
 * hijo suyo — así que llegaba hasta 460 px y ni un píxel más. Lo que quedaba a
 * los lados en una tarjeta ancha era el fondo LISO de la tarjeta: dos franjas
 * oscuras muertas, justo lo que el desenfoque venía a evitar. La foto no tiene
 * ese tope y por eso a ella sí le llegaba de lado a lado.
 *
 * Este marco ocupa el ancho completo y lleva el esmerilado; el video se queda
 * exactamente igual de acotado que antes, centrado encima.
 */
.mom-video-marco {
  position: relative;
  width: 100%;
  overflow: hidden;
}

/* El desenfoque va en un `::before` y no en el propio marco: un `filter` sobre
   el contenedor desenfocaría también el video y todos sus botones.

   El póster se lee de `--mom-poster`, que se hereda del `style=` del marco. Sin
   la variable no hay imagen y el pseudo-elemento se pinta transparente — que es
   exactamente lo que debe pasar mientras un video no tenga póster todavía. */
.mom-video-marco::before {
  content: '';
  position: absolute;
  /* Se desborda a propósito: el desenfoque come los bordes y sin este margen
     queda un halo claro alrededor.

     En PÍXELES y no en `-8%`, porque el desborde tiene que ser mayor que el
     desenfoque y el porcentaje depende del ancho: en un teléfono un 8% son
     treinta píxeles y el desenfoque son sesenta, así que el halo reaparecería
     justo donde no se puede comprobar de un vistazo. */
  inset: -70px;
  background-image: var(--mom-poster);
  background-size: cover;
  background-position: center;

  /* Mucho más desenfoque que el de una foto (22px) y bastante más apagado.
     Se compararon cuatro ajustes sobre el mismo fotograma: hasta 44px el panel
     se sigue leyendo como una SEGUNDA COPIA de la imagen —se distinguen las
     formas, el texto de la pantalla del fondo— y compite con el video en vez de
     acompañarlo. Eso era lo que se veía raro. A 60px pasa a ser color ambiente
     y el video vuelve a ser lo único que se mira.

     Y la saturación BAJA de 1: subirla es lo natural cuando el fondo es un
     adorno, pero aquí el fondo es del mismo fotograma que el video, y realzarlo
     lo convierte en el elemento más vivo de la tarjeta. */
  filter: blur(60px) saturate(.9) brightness(.45);
  pointer-events: none;
}

/* Y el video SE APOYA en el panel. Sin la sombra, sus bordes se funden con el
   desenfoque —mismos colores, mismo fotograma— y no se sabe dónde acaba el
   video y empieza el fondo: se lee como una imagen mal recortada en vez de como
   un clip puesto encima. */
.mom-video { box-shadow: 0 10px 34px rgba(0, 0, 0, .55); }

/* En pantalla completa no hay panel debajo: la sombra sobraría y en un borde
   podría dibujar una línea. Por SEPARADO, como los demás: juntos en una lista,
   el navegador que no conozca uno de los dos descarta la regla entera. */
.mom-video:fullscreen { box-shadow: none; }
.mom-video:-webkit-full-screen { box-shadow: none; }

/* ══ El sello de verificación en la tarjeta de la barra ═════════════════════
 *
 * En el hombro del retrato, exactamente como en el perfil público. Al lado del
 * nombre no cabe: esta columna es angosta y el nombre ya corta con puntos
 * suspensivos, así que un sello ahí se quedaría fuera o partiría el renglón.
 */
.mom-side-retrato {
  position: relative;
  display: inline-block;
  line-height: 0;   /* sin esto el <a> deja un hueco bajo la foto */
}

/* A las cinco en punto y no arriba: ahí estorbaría a la cara. */
.mom-side-sello {
  position: absolute;
  right: -1px; bottom: 1px;
  display: grid; place-items: center;
  width: 1.15rem; height: 1.15rem;
  border-radius: 50%;
  /* El disco del color del fondo lo separa del retrato: sobre una foto oscura,
     el escudo se perdía contra el pelo. Es el mismo remedio del perfil. */
  background: var(--exc-bg);
}
.mom-side-sello .exc-sello { width: .95rem; height: .95rem; min-width: .95rem; }

/* ══ El área de mascotas ════════════════════════════════════════════════════ */

/* Quién sale en la foto, en la tarjeta del muro. Entre el texto y los archivos
   y no en el pie: lo que hace es DECIR de quién es el momento, así que
   pertenece al encabezado. */
.mom-conquien {
  display: flex; align-items: center; flex-wrap: wrap; gap: .3rem;
  margin: 0 0 .5rem;
  padding: 0 .9rem;
  font-size: .8rem;
  color: var(--exc-muted);
}
.mom-conquien .exc-ico { font-size: .95rem; }
.mom-conquien a { color: var(--exc-text); }
.mom-conquien-sep { opacity: .5; }

/* ── Su página ───────────────────────────────────────────────────────────── */

.mom-mas-cab {
  display: flex; flex-direction: column; align-items: center;
  gap: .35rem;
  padding: 1.4rem 1rem 1.1rem;
  text-align: center;
}

.mom-mas-retrato { position: relative; display: inline-block; line-height: 0; }
.mom-mas-retrato img {
  width: 112px; height: 112px; border-radius: 50%;
  object-fit: cover;
  border: 3px solid var(--exc-surface-2);
}
.mom-mas-sinfoto {
  display: grid; place-items: center;
  width: 112px; height: 112px; border-radius: 50%;
  background: var(--exc-surface-2);
  color: var(--exc-muted);
  font-size: 2.4rem;
}

/* La patita, en el hombro. Es la marca de que esto es una mascota y no una
   persona: sin ella, un retrato redondo con un nombre debajo es exactamente la
   carátula de un perfil cualquiera. Mismo sitio y mismo remedio que el sello de
   verificación — el disco del color del fondo lo separa de la foto. */
.mom-mas-patita {
  position: absolute;
  right: 2px; bottom: 4px;
  display: grid; place-items: center;
  width: 2rem; height: 2rem; border-radius: 50%;
  background: var(--exc-accent);
  color: var(--exc-accent-contrast);
  font-size: 1rem;
  box-shadow: 0 0 0 3px var(--exc-bg);
}

.mom-mas-nombre { margin: .7rem 0 0; font-size: 1.5rem; font-weight: 500; }
.mom-mas-meta   { margin: 0; font-size: .88rem; color: var(--exc-muted); }

.mom-mas-dueno {
  display: inline-flex; align-items: center; gap: .4rem;
  margin-top: .5rem; padding: .25rem .7rem .25rem .25rem;
  border-radius: 999px;
  background: var(--exc-surface-2);
  color: inherit;
  font-size: .82rem;
}

/* ── El renglón que lleva a otra pantalla desde una hoja ───────────────────
 *
 * Va FUERA del formulario, al pie de la hoja: no es un campo que se guarde con
 * lo demás. Se pinta como un renglón de menú y no como un botón — un botón al
 * lado de «Guardar cambios» compite con él, y lo que se viene a hacer aquí es
 * guardar. */
.mom-hoja-ir {
  display: flex; align-items: center; gap: .8rem;
  margin-top: 1.2rem;
  padding: .8rem .9rem;
  border: 1px solid var(--exc-border);
  border-radius: var(--exc-radius);
  color: inherit;
  text-decoration: none;
}
.mom-hoja-ir:hover { background: var(--exc-surface-2); color: inherit; }

/* `min-width: 0` para que el texto largo se corte dentro de su caja en vez de
   empujar la flecha fuera del renglón. */
.mom-hoja-ir span { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.mom-hoja-ir small { font-size: .78rem; line-height: 1.35; }

/* La flecha del final no se encoge: es lo que dice que esto lleva a otro sitio. */
.mom-hoja-ir > svg:last-child { flex: none; opacity: .7; }

/* ── La barra del perfil: pestañas y cómo se ven ────────────────────────────
 *
 * Las dos cosas en un renglón, a los extremos: a la izquierda QUÉ se enseña
 * (todo o solo multimedia) y a la derecha CÓMO (tarjetas o rejilla). Son
 * preguntas distintas y por eso no se mezclan en un solo grupo de pestañas —
 * cuatro pastillas seguidas obligarían a leerlas todas para saber cuál es cuál.
 */
.mom-pf-barra {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1.2rem;
}

/* Las pestañas ya vienen del componente del sitio (`.exc-tabs`), que es una
   tira con su raya abajo. Aquí solo se le quita el margen inferior: la barra
   ya lo pone, y sumados dejaban un hueco del alto de una tarjeta. */
.mom-pf-tabs { margin-bottom: 0; flex: 1; min-width: 0; }

.mom-pf-vista {
  display: flex;
  gap: .2rem;
  flex: 0 0 auto;
  padding: .2rem;
  border: var(--exc-border-width) solid var(--exc-border);
  border-radius: var(--exc-radius);
  background: var(--exc-surface);
  /* Se levanta lo que mide la raya de las pestañas, para que los dos bloques
     queden alineados por abajo en vez de escalonados. */
  margin-bottom: .35rem;
}
.mom-pf-v {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--exc-radius-sm);
  color: var(--exc-muted);
}
.mom-pf-v:hover { opacity: 1; color: var(--exc-text); background: var(--exc-surface-2); }
.mom-pf-v.is-on {
  background: var(--exc-accent-soft);
  color: var(--exc-accent);
  opacity: 1;
}

/* En el teléfono la barra se apila: las pestañas a todo lo ancho y el selector
   debajo, alineado a la derecha. Lado a lado, con dos pestañas y dos iconos, el
   renglón se parte solo y queda peor. */
@media (max-width: 559px) {
  .mom-pf-barra { flex-direction: column; align-items: stretch; gap: .5rem; }
  .mom-pf-vista { align-self: flex-end; margin-bottom: 0; }
}

/* ── La columna de un canal ─────────────────────────────────────────────── */

.mom-rc { padding: .9rem 1rem; }
.mom-rc h4 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  margin: 0 0 .6rem;
  font-size: .95rem;
}
.mom-rc-bio { margin: 0 0 .7rem; font-size: .9rem; line-height: 1.5; overflow-wrap: anywhere; }
.mom-rc-dato {
  display: flex;
  align-items: center;
  gap: .45rem;
  margin: 0 0 .4rem;
  font-size: .88rem;
}
.mom-rc-dato svg { flex: 0 0 auto; color: var(--exc-accent); }
.mom-rc-verbo { margin-top: .8rem; gap: .4rem; }

.mom-rc-lista { display: flex; flex-direction: column; gap: .7rem; }

/* Cada momento reciente: miniatura y dos renglones. Es un `<span>` y no un
   enlace mientras no exista la ficha de un momento suelto, así que no lleva ni
   cursor de mano ni color de enlace: la forma dice lo que hace. */
.mom-rc-item {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  color: inherit;
}
.mom-rc-item img {
  flex: 0 0 auto;
  width: 3.4rem;
  height: 3.4rem;
  object-fit: cover;
  border-radius: var(--exc-radius-sm);
  background: var(--exc-surface-2);
}
.mom-rc-txt { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.mom-rc-txt b {
  font-size: .85rem;
  font-weight: 500;
  line-height: 1.35;
  /* Dos renglones y punto: el tercero convierte la columna en otro muro. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.mom-rc-txt small { font-size: .76rem; }

/* En escritorio la ficha es una FILA —retrato, datos, botones— así que lo de
   dentro se alinea a la izquierda. En el teléfono se apila y va centrado, que
   es como estaba y como se lee bien en una columna angosta: por eso el centrado
   es la base y esto solo lo deshace cuando hay ancho.

   Va aquí abajo y no dentro del bloque de 992 px de más arriba a propósito: ese
   bloque es el de la maqueta —quién va al lado de quién— y esto es tipografía
   de la ficha. Mezclarlos hace que mover la maqueta se lleve por delante la
   alineación del texto sin que nadie lo relacione. */
@media (min-width: 992px) {
  .mom-pf-datos .mom-pf-arroba,
  .mom-pf-datos .mom-pf-donde,
  .mom-pf-nums { justify-content: flex-start; }

  .mom-pf-nums > span,
  .mom-pf-nums > a { text-align: left; }
}

/* ── El pie en la página pública ────────────────────────────────────────────
 *
 * Las reacciones son enlaces, no botones: sin sesión no hay a quién guardarles
 * nada y tocarlas lleva a entrar. Heredan `.mom-react` entero, así que se ven
 * exactamente igual que en el muro — lo que cambia es a dónde van, no cómo se
 * leen. Solo hay que quitarles el subrayado, que un `<a>` trae de fábrica. */
a.mom-react { text-decoration: none; }

/* La invitación, en el hueco donde en el muro va el marcador.
 *
 * El color, el borde y el alto los pone `.exc-btn.exc-btn-outline` — aquí solo
 * lo que un botón del sitio no sabe de este contexto: que no encoja y que no
 * parta su texto en dos renglones dentro de una fila de iconos. Repetir aquí el
 * color sería tener el botón pintado en dos sitios, y el día que cambie el tema
 * uno de los dos se queda atrás. */
.mom-pie-entrar { flex: none; white-space: nowrap; }

/* Las SEIS a la vista en la página pública.
 *
 * En el muro las de cero se esconden y la carita abre el resto; aquí no hay
 * carita, así que la regla de colapsar dejaba el pie de una publicación nueva
 * completamente VACÍO — una franja en blanco bajo la foto que no se lee como
 * «todavía nadie reacciona», se lee como que algo se rompió. Y de paso el
 * corazón tampoco salía: la regla que lo salva es `[data-mom-react="love"]`, y
 * aquí son enlaces sin ese atributo.
 *
 * Gana por especificidad (0,4,0 contra 0,3,0), no por ir después. */
.mom-reacciones.is-lectura .mom-react.is-cero { display: inline-flex; }

/* Apagadas, para que las que SÍ tienen cuenta se lean de un vistazo y las otras
   se queden como lo que son: la invitación a hacerlo. */
.mom-reacciones.is-lectura .mom-react.is-cero { color: var(--exc-muted); opacity: .55; }
.mom-reacciones.is-lectura .mom-react.is-cero:hover { opacity: 1; }

/* ── Compartir ──────────────────────────────────────────────────────────────
 *
 * Igual que el marcador: los dos son «qué hago YO con esto» y viven al otro
 * lado de la barra, lejos de las reacciones, que son «qué le digo al autor».
 * Mismo tamaño y mismo gris — dos botones vecinos de distinto peso hacen que
 * uno parezca el principal y el otro un descuido. */
.mom-compartir {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  min-width: 40px;
  min-height: 40px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--exc-muted);
  cursor: pointer;
  font-size: 1.15rem;
}
.mom-compartir:hover { background: var(--exc-surface-2); color: var(--exc-text); }

/* ── La publicación sola (`exclivia.com/m/{ref}`) ──────────────────────────── */

.mom-solo { padding-top: 1.2rem; padding-bottom: 2rem; }
.mom-solo-lista { margin-bottom: 1rem; }

/* La puerta al perfil de quien publicó. Va después de la tarjeta y con la
   misma forma que ella: es una continuación, no un anuncio. */
.mom-solo-autor {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .8rem 1rem;
  color: inherit;
  text-decoration: none;
  background: var(--exc-surface);
  border: var(--exc-border-width) solid var(--exc-border);
  border-radius: var(--exc-radius);
}
.mom-solo-autor:hover { border-color: var(--exc-accent); }
.mom-solo-autor-txt {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; line-height: 1.35;
}
.mom-solo-autor > svg { flex: none; color: var(--exc-muted); }

/* ══ Un video de fuera (TikTok, YouTube) ════════════════════════════════════
 *
 * La proporción se declara en CSS y no se mide en el navegador: sin ella el
 * hueco nace en cero y la página pega un salto cuando el iframe termina de
 * cargar, justo debajo de donde la persona estaba leyendo. */
.mom-vid {
  position: relative;
  margin: .2rem 0 0;
  border-radius: var(--exc-radius);
  overflow: hidden;
  background: #0b0c0f;
}

/* ── El halo de detrás ──────────────────────────────────────────────────────
 *
 * Un TikTok es VERTICAL: metido en una tarjeta ancha deja dos franjas muertas
 * a los lados y el video se ve flotando, solo, como pegado encima.
 *
 * Con una foto eso se resuelve repitiendo la MISMA imagen desenfocada detrás
 * (`.mom-ficha-fondo`). Aquí no se puede: el video vive en un iframe de otro
 * origen y el navegador no deja leer ni un píxel de dentro — ni con CSS, ni
 * con canvas, ni con nada. Es la misma frontera que impide que su JavaScript
 * toque este sitio, y está bien que exista.
 *
 * Así que el halo es PROPIO y decorativo: tres manchas de color desenfocadas.
 * No finge ser el video —eso sería prometer una miniatura que no tenemos— pero
 * llena las franjas y hace que el video se lea como algo puesto sobre una
 * superficie, no suelto en el vacío. */
.mom-vid::before {
  content: '';
  position: absolute;
  inset: -20%;
  background:
    radial-gradient(40% 48% at 24% 22%, rgba(var(--exc-accent-rgb), .62), transparent 72%),
    radial-gradient(36% 44% at 80% 74%, rgba(226, 103, 154, .48), transparent 72%),
    radial-gradient(46% 52% at 52% 102%, rgba(90, 169, 230, .38), transparent 72%);
  filter: blur(34px) saturate(1.35);
  pointer-events: none;
}

/* La FACHADA es compacta y la misma para los dos: no tiene miniatura que
   enseñar, así que un 9:16 en el muro son seiscientos píxeles de caja oscura
   entre dos publicaciones — media pantalla de teléfono para decir «aquí hay un
   TikTok». */
.mom-vid { aspect-ratio: 16 / 7; }

/* ── Con el video ya dentro ─────────────────────────────────────────────────
 *
 * `:has(iframe)` en vez de una clase que ponga el JavaScript: el estado ya está
 * en el DOM —hay un iframe o no lo hay— y duplicarlo en una clase es el segundo
 * sitio que un día dice otra cosa.
 *
 * La caja pasa a ser un MARCO: se queda a todo el ancho, con su halo, y el
 * video se centra dentro. El alto lo pone el propio video, así que la
 * proporción de la caja se suelta. */
.mom-vid:has(iframe) {
  aspect-ratio: auto;
  display: grid;
  place-items: center;
  padding: .9rem;
}

.mom-vid iframe {
  position: relative;   /* por encima de su halo */
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 12px;
  /* La sombra es lo que lo despega del fondo: sin ella el video y el halo se
     leen como una sola mancha y vuelve a parecer pegado. */
  box-shadow: 0 12px 38px rgba(0, 0, 0, .55);
}

/* TikTok es vertical y YouTube apaisado. Con una sola proporción, uno de los
   dos sale con dos franjas negras del tamaño de media tarjeta.
   El tope de 70vh no es un capricho: un 9:16 a lo ancho del muro en un
   escritorio mide más de una pantalla, y entonces no se ve el video — se ve un
   trozo de video. */
.mom-vid-tiktok iframe {
  width: min(100%, 340px);
  height: auto;
  aspect-ratio: 9 / 16;
  max-height: 70vh;
}
.mom-vid-youtube iframe {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
}

/* ── La fachada ─────────────────────────────────────────────────────────── */
.mom-vid-tapa {
  position: relative;   /* por encima del halo */
  display: grid;
  place-items: center;
  gap: .5rem;
  width: 100%;
  height: 100%;
  padding: 1rem;
  border: 0;
  cursor: pointer;
  background: none;
  color: var(--exc-text);
}
.mom-vid-tapa:hover .mom-vid-play { transform: scale(1.08); }

.mom-vid-play {
  display: grid;
  place-items: center;
  width: 3.4rem;
  height: 3.4rem;
  font-size: 1.5rem;
  color: #fff;
  background: rgba(0, 0, 0, .35);
  border: 2px solid rgba(255, 255, 255, .75);
  border-radius: 999px;
  backdrop-filter: blur(4px);
  transition: transform .15s ease;
}
.mom-vid-marca { font-size: .85rem; color: rgba(255, 255, 255, .75); }

/* ── La salida al original ──────────────────────────────────────────────── */
.mom-vid-ir {
  position: absolute;
  /* ARRIBA y no abajo: el reproductor de TikTok pone ahí su propio
     «Watch now», y dos botones encimados hacen que se toque el que no era.
     Arriba el halo está libre en los dos estados. */
  right: .6rem;
  top: .6rem;
  padding: .25rem .6rem;
  font-size: .75rem;
  color: #fff;
  text-decoration: none;
  background: rgba(0, 0, 0, .55);
  border-radius: 999px;
  backdrop-filter: blur(4px);
}
.mom-vid-ir:hover { background: rgba(0, 0, 0, .85); }

/* ── Las otras cuentas, dentro de «Editar perfil» ────────────────────────────
 *
 * Estaban DEBAJO del botón de guardar y ahí no las veía nadie: un botón a todo
 * lo ancho se lee como el final de la hoja. Ahora van antes, y lo que las
 * separa de los campos es esta raya y su título — no la distancia.
 */
.mom-hoja-otras {
  margin: 1.5rem 0 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--exc-border);
}

.mom-hoja-otras .exc-label { margin-bottom: .6rem; display: block; }
.mom-hoja-otras .mom-hoja-ir + .mom-hoja-ir { margin-top: .4rem; }

/* ══ El video de presentación del perfil ═════════════════════════════════════
 *
 * Lo primero de la columna. La idea y el efecto vienen del `chat-sidebar__hero`
 * de ligueo.ai: el video a sangre y un degradado encima que lo funde con la
 * tarjeta, para que parezca parte de la columna y no un recuadro pegado.
 *
 * Lo que cambia respecto de allá es el alto. Ligueo lo fija en 533 px porque su
 * columna es la protagonista de la pantalla; aquí el riel acompaña a un muro,
 * así que va por PROPORCIÓN y con un techo en `vh`: en un portátil de pantalla
 * baja, un vídeo de 500 px se come la columna entera y empuja «a quién seguir»
 * fuera de la vista sin que nadie sepa que está ahí.
 *
 * ── La proporción es 9:16, y estuvo mal ────────────────────────────────────
 *
 * Estaba en 3:4 con un techo de `min(46vh, 21rem)`, y el techo APRETABA antes
 * que la proporción: medido en el rail de escritorio, la caja salía de
 * **336 × 336 — un cuadrado perfecto**, y en el teléfono 358 × 336, más ancha
 * que alta. Los clips son de **392 × 720** (0.544, o sea 9:16 de sobra), así
 * que con `object-fit: cover` **se veía el 54 % del video**: casi la mitad del
 * plano recortada, y el 3:4 escrito aquí no llegó a aplicarse ni una vez.
 *
 * Ahora la proporción es la del clip y el techo va SOLO en `vh` — el que
 * protege de una ventana baja—, sin el tope en `rem` que era el que cuadraba
 * la caja. Un número en `rem` no sabe cuánto mide la pantalla; un `vh` sí, que
 * es exactamente lo que ese techo viene a resolver.
 */
.mom-intro {
  position: relative;
  padding: 0;                 /* a sangre: la tarjeta no le pone margen */
  overflow: hidden;

  /* `width: 100%` NO sobra, y esto costó una captura para verlo.
   *
   * Con el ancho en `auto` —lo normal en una tarjeta— la proporción manda
   * sobre las DOS medidas, así que en cuanto el techo de `vh` aprieta el
   * navegador no recorta el alto: ESTRECHA la tarjeta para conservar el 3:4.
   * La caja salía más angosta que la portada y que todo lo que va debajo, y
   * en una columna de tarjetas alineadas eso se ve como un error de página.
   *
   * Con el ancho fijado, la proporción solo decide el alto y el techo lo
   * recorta. Lo que sobra se lo come `object-fit: cover`, que es su trabajo. */
  width: 100%;
  aspect-ratio: 9 / 16;

  /* 78vh y no 46: a 21rem de ancho, 9:16 pide 597 px, y con 46vh en una
     ventana de 900 el techo los recortaría a 414 — volveríamos al cuadrado por
     otro camino. 78vh deja pasar la proporción entera en cualquier pantalla de
     768 px de alto para arriba y solo muerde en una ventana de verdad baja,
     que es para lo que está. */
  max-height: 78vh;
}

.mom-intro-v {
  width: 100%; height: 100%;
  object-fit: cover;
  /* `center top` y no `center`: en un clip vertical de alguien hablando, lo que
     importa es la cara, y está arriba. Centrado, un recorte se come la frente. */
  object-position: center top;
  display: block;
}

/* El degradado. Va del color de la tarjeta abajo a transparente al 55 %, que es
   la mezcla exacta de ligueo: lo justo para que el borde inferior desaparezca
   sin apagar el video. */
.mom-intro-glow {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--exc-surface) 0%, transparent 55%);
  pointer-events: none;
}

/* El botón de pausa.
 *
 * No es un adorno ni una cortesía: un video que se mueve solo más de cinco
 * segundos TIENE que poder pararse (WCAG 2.2.2). Y esto está en lo primero que
 * ve quien entra a un perfil, así que quien no puede leer con algo moviéndose
 * al lado se queda sin poder leer la página.
 *
 * Arriba a la derecha, sobre el degradado, y se ve siempre — no solo al pasar
 * el ratón: en un teléfono no hay ratón, y un control que solo aparece al pasar
 * por encima no existe para más de la mitad de quien entra. */
.mom-intro-pausa {
  position: absolute;
  top: .5rem; right: .5rem;
  z-index: 2;
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border: 0; border-radius: 999px;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  cursor: pointer;
  backdrop-filter: blur(4px);
}
.mom-intro-pausa svg { width: 1em; height: 1em; }
.mom-intro-pausa:hover { background: rgba(0, 0, 0, .75); }

/* ── Y en el TELÉFONO, donde no hay riel ─────────────────────────────────────
 *
 * `.mom-rail` está en `display:none` hasta los 992 px, así que el video —que
 * vive dentro— no lo vería nadie en un teléfono: justo donde se mira un perfil.
 *
 * No se pinta dos veces. Un segundo `<video>` escondido con CSS sigue siendo un
 * archivo que el navegador se baja, y en datos móviles eso es pagar dos veces
 * por el mismo clip. Lo que se hace es DESHACER la caja del riel (`contents`):
 * sus tarjetas dejan de tener un padre y se convierten en hijas de la rejilla,
 * y ahí se apagan todas menos ésta.
 *
 * Apagar por defecto y encender una —y no al revés— es lo que hace que la
 * tarjeta que alguien añada mañana al riel no aparezca sola en el teléfono.
 *
 * `order: -1` la manda delante de la columna: es «el primer bloque», y lo demás
 * —la portada, la ficha, los momentos— baja. Que es exactamente lo que se pidió.
 */
@media (max-width: 991.98px) {
  .mom-rail        { display: contents; }
  .mom-rail > *    { display: none; }
  .mom-rail > .mom-intro {
    display: block;
    order: -1;
    /* El techo sube —a todo lo ancho el video es el protagonista— pero NO se
       quita: a 9:16 sin tope, en un teléfono el clip ocupa tres cuartos de la
       primera pantalla y el NOMBRE de quien lo publicó queda a un scroll de
       distancia. Un video de alguien a quien no se sabe quién es no presenta a
       nadie. Con 62vh asoman la portada y el retrato, que es la pista — los
       mismos que usa el rail de la pública, porque es el mismo pliegue. */
    max-height: 62vh;
  }
}

/* ── Que no se lleven las fotos ──────────────────────────────────────────────
 *
 * La tercera capa de la protección, y la que sigue valiendo aunque
 * `medios.js` no llegue a cargar — una pestaña con el JS a medias no puede
 * dejar el contenido de la gente más abierto que una con todo puesto.
 *
 * `-webkit-touch-callout: none` es la que más trabaja, y no tiene sustituto:
 * **Safari en iPhone NO manda `contextmenu` en la pulsación larga**, así que
 * ahí el manejador del guion no se entera de nada y la hoja de «Guardar en
 * Fotos» sale igual. Esto es lo único que la cierra, y el teléfono es donde
 * se mira el 90 % de esto.
 *
 * `-webkit-user-drag: none` repite lo del `dragstart` del guion a propósito:
 * en Safari el arrastre de una imagen empieza sin pasar por ese evento.
 *
 * `user-select: none` evita el otro camino tonto: seleccionar alrededor de la
 * foto y copiar, que en varios navegadores se lleva la imagen dentro.
 *
 * Y lo que esto NO es: un candado. La foto ya está en la máquina de quien
 * mira y una captura de pantalla no la impide nadie. Se cierran las puertas
 * fáciles. */
.mom-media img,
.mom-media video,
.mom-celda img,
.mom-ficha-img,
.mom-intro-v,
.mom-visor-cuerpo img,
.mom-visor-cuerpo video {
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
}

/* ══ El compositor de la maqueta ═══════════════════════════════════════════
 *
 * Va AL FINAL del archivo y no junto a las reglas del compositor de arriba: lo
 * que hay allí sigue siendo el esqueleto —la hoja, el velo, el recorte de las
 * miniaturas— y esto es su cara nueva. Mezclarlas obligaría a leer trescientas
 * líneas para saber cuál gana, y aquí gana lo de abajo sin discusión.
 */

/* ── El borde dorado ──────────────────────────────────────────────────────
 *
 * Solo ABIERTO. Cerrado el compositor es un renglón más de la columna y un
 * marco de color ahí lo convierte en un anuncio; abierto es la única cosa de
 * la pantalla que está pidiendo algo, y el marco es lo que lo dice sin una
 * palabra.
 *
 * El acento y no un oro escrito a mano: el tema sale de la tabla `settings` y
 * un `#c9a227` aquí sería el primero en quedarse fuera el día que alguien
 * cambie el color del sitio. */
.mom-comp.is-abierto {
  border-color: var(--exc-accent);
  box-shadow: 0 0 0 3px var(--exc-accent-soft);
}

/* ── Quién lo ve, en tarjetas ─────────────────────────────────────────────
 *
 * `fieldset` de verdad, con su `legend`: son tres opciones excluyentes y ésa
 * es la etiqueta que un lector de pantalla anuncia antes de leerlas. Con un
 * `<div>` y un `<p>` encima, quien navega así oye tres nombres sueltos sin
 * saber de qué se le está preguntando. Hay que apagarle el marco y el relleno
 * que trae de fábrica. */
.mom-aud {
  border: 0;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
  gap: .5rem;
}

.mom-aud-titulo {
  grid-column: 1 / -1;
  padding: 0;
  font-size: .82rem;
  font-weight: 600;
  color: var(--exc-muted);
}

.mom-aud-op {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .6rem .7rem;
  border: var(--exc-border-width) solid var(--exc-border);
  border-radius: var(--exc-radius);
  background: var(--exc-surface);
  cursor: pointer;
  transition: border-color .15s, background .15s;
  /* Sin esto, una descripción larga ensancha su columna de la rejilla y las
     tres tarjetas dejan de medir lo mismo: las cajas de una rejilla llevan
     `min-width: auto` y no encogen por debajo de su contenido. Ya costó una
     tarde en los contadores del mapa. */
  min-width: 0;
}

.mom-aud-op > svg { flex: 0 0 auto; color: var(--exc-muted); font-size: 1.15rem; }
.mom-aud-n { font-size: .88rem; font-weight: 600; min-width: 0; }

/* La frase de la ELEGIDA, debajo de la fila. Antes iba una dentro de cada
   tarjeta: seis renglones de letra chica para elegir entre tres cosas, y
   cuatro de ellos describiendo algo que no se eligió. */
.mom-aud-pista {
  margin: .5rem 0 0;
  font-size: .78rem;
  line-height: 1.4;
  color: var(--exc-muted);
}

.mom-aud-op:hover { border-color: var(--exc-accent); }

.mom-aud-op.is-on {
  border-color: var(--exc-accent);
  background: var(--exc-accent-soft);
}
.mom-aud-op.is-on > svg { color: var(--exc-accent); }

/* Apagada por el interruptor de «sin mi nombre». Se ATENÚA y no se esconde:
   tres opciones que desaparecen al tocar un interruptor se leen como que la
   pantalla se rompió, y la razón de por qué se cerraron está escrita justo
   debajo del interruptor que las cerró. */
.mom-aud-op.is-off {
  opacity: .42;
  cursor: not-allowed;
  border-color: var(--exc-border);
  background: var(--exc-surface);
}
.mom-aud-op.is-off:hover { border-color: var(--exc-border); }

/* ── La promesa ───────────────────────────────────────────────────────── */
.mom-comp-privacidad {
  display: flex;
  align-items: flex-start;
  gap: .45rem;
  margin: 0;
  font-size: .78rem;
  line-height: 1.4;
  color: var(--exc-muted);
}
.mom-comp-privacidad svg { flex: 0 0 auto; color: var(--exc-success); margin-top: .1em; }

/* ── Sin nombre y cuánto dura ─────────────────────────────────────────── */
.mom-comp-opciones {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  padding: .7rem;
  border: var(--exc-border-width) solid var(--exc-border);
  border-radius: var(--exc-radius);
  background: var(--exc-bg-soft);
}

/* El interruptor. Es un `<label>` con su `<input type="checkbox">` dentro y
   escondido: así lo enciende la barra espaciadora, entra en el orden del
   tabulador y un lector de pantalla lo anuncia como lo que es. Dibujar una
   pastilla con dos `<div>` y un `click` deja todo eso fuera. */
.mom-sw {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  cursor: pointer;
  /* Que no se estire a lo ancho de la caja: al lado va el desplegable. */
  flex: 1 1 15rem;
  min-width: 0;
}
.mom-sw input { position: absolute; opacity: 0; width: 0; height: 0; }

.mom-sw-pista {
  flex: 0 0 auto;
  width: 2.35rem;
  height: 1.3rem;
  margin-top: .1rem;
  border-radius: 999px;
  background: var(--exc-border);
  transition: background .15s;
  display: block;
  position: relative;
}
.mom-sw-bola {
  position: absolute;
  top: .15rem;
  left: .15rem;
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  background: var(--exc-surface);
  box-shadow: var(--exc-shadow);
  transition: transform .15s;
}
.mom-sw input:checked + .mom-sw-pista { background: var(--exc-accent); }
.mom-sw input:checked + .mom-sw-pista .mom-sw-bola { transform: translateX(1.05rem); }

/* El anillo del foco va en la PISTA y no en el `<input>`, que mide cero: sin
   esto, quien llega con el tabulador no ve dónde está parado. */
.mom-sw input:focus-visible + .mom-sw-pista {
  outline: 2px solid var(--exc-accent);
  outline-offset: 2px;
}

.mom-sw-txt { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.mom-sw-txt strong { font-size: .86rem; font-weight: 600; }
.mom-sw-txt small { font-size: .74rem; color: var(--exc-muted); line-height: 1.35; }

.mom-dura { display: flex; align-items: center; gap: .45rem; flex: 0 0 auto; }
.mom-dura > span { font-size: .8rem; color: var(--exc-muted); white-space: nowrap; }
.mom-dura select { min-width: 8.5rem; }

/* ── Los dos botones del final ────────────────────────────────────────── */
.mom-comp-enviar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: .5rem;
  flex-wrap: wrap;
}

/* El de publicar ocupa lo que le sobre y el de guardar mide su texto: son dos
   caminos del mismo formulario y uno de los dos es el que se quiere. */
.mom-comp-enviar-btn { flex: 1 1 11rem; justify-content: center; }

/* En la hoja del teléfono la barra de arriba ya lleva su «Publicar», así que
   abajo se queda solo el borrador y el principal a todo lo ancho: dos botones
   dorados en la misma pantalla se disputan el pulgar. */
@media (max-width: 720px) {
  .mom-comp-enviar { flex-direction: column-reverse; align-items: stretch; }
  .mom-comp-enviar .exc-btn { width: 100%; justify-content: center; }
  .mom-comp-opciones { flex-direction: column; align-items: stretch; }
  .mom-dura { justify-content: space-between; }

  /* Un `flex: 1 1 …` reparte el ANCHO cuando los hermanos van en FILA; en
     columna reparte el ALTO. Los dos de aquí lo llevan para el escritorio, y
     sin esto el interruptor dejaba medio teléfono de hueco bajo su pista y el
     botón de publicar salía de tres centímetros de alto. */
  .mom-sw,
  .mom-comp-enviar-btn { flex: 0 0 auto; }
}

/* En un teléfono, una sola columna. Con dos caben apretadas y la tercera se
   queda sola en su renglón, que se lee como que falta una cuarta. */
@media (max-width: 560px) {
  .mom-aud { grid-template-columns: minmax(0, 1fr); }
}

/* La cabecera del muro y el centro de privacidad ESTABAN AQUÍ.
 *
 * Se quitaron los dos de la pantalla (ver `views/index.php` y
 * `views/partes/rail.php`), y su CSS se va con ellos en vez de quedarse de
 * adorno: 90 líneas que nadie pinta son 90 líneas que el siguiente lee, y
 * un `.mom-head-hero` sin dueño se copia a otro sitio creyendo que sirve.
 */

/* La firma del final de la columna. */
.mom-rail-firma {
  margin: .25rem 0 0;
  padding: 0 .4rem;
  text-align: center;
  font-family: var(--exc-font-display);
  font-size: .92rem;
  color: var(--exc-muted);
}

/* El recordatorio de «lo publicaste sin tu nombre», en la firma de la tarjeta.
   Solo lo ve su autor — ver `partes/autor.php`. */
.mom-anon-mio {
  display: inline-flex;
  align-items: center;
  gap: .2rem;
  color: var(--exc-accent);
  font-weight: 600;
}

/* El avatar de quien publica sin nombre: un icono neutro y no unas iniciales.
   Ver `partes/autor.php` — «AC» de «Alguien de tu ciudad» se lee como las
   iniciales de una persona real. */
.mom-anon-av {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--exc-bg-soft);
  color: var(--exc-muted);
  border: var(--exc-border-width) solid var(--exc-border);
}

/* ══ El compositor compacto ════════════════════════════════════════════════
 *
 * Cerrado es un renglón; abierto es el campo, sus botones y UNA fila plegada
 * con todo lo demás. Antes, publicar una foto con un pie obligaba a pasar por
 * encima de tres tarjetas de audiencia, un interruptor y un desplegable para
 * llegar al botón — en el teléfono, media hoja de scroll para algo que la
 * inmensa mayoría de las veces no se toca.
 */

/* ── La pastilla de audiencia de la barra ─────────────────────────────────
 *
 * Ocupa el sitio del segundo «Publicar», que se fue. Enseña lo único del
 * formulario que no se puede corregir después de pulsar: a quién le llega.
 */
.mom-comp-chip {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  flex: 0 0 auto;
  padding: .3rem .5rem .3rem .45rem;
  border: var(--exc-border-width) solid var(--exc-border);
  border-radius: 999px;
  background: var(--exc-surface);
  color: var(--exc-text);
  font: inherit;
  font-size: .8rem;
  font-weight: 600;
  cursor: pointer;
  max-width: 11rem;
  min-width: 0;
}
.mom-comp-chip:hover { border-color: var(--exc-accent); }
.mom-comp-chip span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mom-comp-chip-ico { display: inline-flex; flex: 0 0 auto; color: var(--exc-accent); }
.mom-comp-chip > svg:last-child { flex: 0 0 auto; color: var(--exc-muted); font-size: .95rem; }
.mom-comp-chip[aria-expanded="true"] > svg:last-child { transform: rotate(180deg); }

/* ── El contador, pegado al campo ─────────────────────────────────────── */
.mom-comp-cuenta { text-align: right; }

/* ── La sección plegable ──────────────────────────────────────────────── */
.mom-ops {
  border: var(--exc-border-width) solid var(--exc-border);
  border-radius: var(--exc-radius);
  background: var(--exc-bg-soft);
  overflow: hidden;
}

.mom-ops-cab {
  display: flex;
  align-items: center;
  gap: .5rem;
  width: 100%;
  padding: .65rem .7rem;
  border: 0;
  background: none;
  color: var(--exc-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.mom-ops-cab:hover { background: var(--exc-surface); }
.mom-ops-cab > svg:first-child { flex: 0 0 auto; color: var(--exc-accent); }

.mom-ops-tit { font-size: .86rem; font-weight: 600; flex: 0 0 auto; }

/* El resumen de lo que hay dentro. Se come el espacio que sobra y se recorta
   antes que el título: en un teléfono estrecho vale más perder «En un mes»
   que el nombre de la sección, porque sin él la fila no dice de qué va. */
.mom-ops-resumen {
  flex: 1 1 auto;
  min-width: 0;
  text-align: right;
  font-size: .78rem;
  color: var(--exc-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mom-ops-flecha { display: inline-flex; flex: 0 0 auto; color: var(--exc-muted); transition: transform .15s; }
.mom-ops.is-abierta .mom-ops-flecha { transform: rotate(180deg); }

/* `display` PROPIO, así que hace falta devolverle el `hidden` a mano: en este
   proyecto una regla de la hoja le gana al atributo del navegador, que solo
   vive en la hoja del agente de usuario. Ya costó una tarde en el visor y en
   el recortador. */
.mom-ops-cuerpo {
  display: grid;
  gap: .75rem;
  padding: 0 .7rem .75rem;
  border-top: var(--exc-border-width) solid var(--exc-border);
  padding-top: .75rem;
}
.mom-ops-cuerpo[hidden] { display: none; }

/* Dentro del panel las cajas ya no llevan marco: el panel ES el marco, y tres
   bordes anidados convierten una fila en un cajón de cajones. */
.mom-ops-cuerpo .mom-comp-opciones {
  border: 0;
  background: none;
  padding: 0;
}

/* ── El teléfono ──────────────────────────────────────────────────────── */
@media (max-width: 720px) {
  /* El pie se queda pegado abajo. Con las opciones abiertas, el botón de
     publicar caía por debajo del borde y había que desplazarse hasta el final
     de la hoja para poder pulsarlo — justo lo que este rediseño viene a
     quitar. El fondo es opaco porque el contenido pasa POR DEBAJO. */
  .mom-comp.is-abierto .mom-comp-enviar {
    position: sticky;
    bottom: 0;
    z-index: 2;
    margin: 0 -.75rem -.75rem;
    padding: .75rem;
    background: var(--exc-surface);
    border-top: var(--exc-border-width) solid var(--exc-border);
  }

  /* Y la cabecera del panel se parte en dos renglones: título arriba y
     resumen debajo. En una sola fila, con el icono y la flecha, al resumen le
     quedaban cuatro caracteres antes de los puntos suspensivos. */
  .mom-ops-cab { flex-wrap: wrap; }
  .mom-ops-resumen { flex-basis: 100%; text-align: left; order: 3; }
}

/* ── «Abierto ahora» del canal ───────────────────────────────────────────────
 *
 * Es una PASTILLA y no un renglón más de la fila de datos, porque no es un dato
 * de la cosa: es su disponibilidad AHORA. Es lo primero que se mira y lo único
 * que caduca — la misma distinción que el chat hace entre `datos` y `estado`.
 *
 * El color no es la única señal: lleva el texto escrito («Abierto · cierra
 * 10:00 pm»). Uno de cada doce hombres no distingue el verde del rojo, y una
 * pastilla que solo cambia de color no le dice nada.
 */
.mom-pf-abierto {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  padding: .2rem .55rem;
  border-radius: 999px;
  font-size: .78rem;
  font-weight: 600;
  border: 1px solid transparent;
}
.mom-pf-abierto svg { font-size: .9rem; flex: 0 0 auto; }

.mom-pf-abierto.is-si {
  color: var(--exc-success);
  background: color-mix(in srgb, var(--exc-success) 12%, transparent);
  border-color: color-mix(in srgb, var(--exc-success) 35%, transparent);
}
/* Cerrado va en NEUTRO y no en rojo: estar cerrado a las once de la noche es lo
   normal, no una alarma. El rojo se guarda para lo que sí está mal. */
.mom-pf-abierto.is-no {
  color: var(--exc-muted);
  background: var(--exc-surface-2);
  border-color: var(--exc-border);
}

/* La tarjeta de herramientas del canal, en su columna. Solo la ve quien lo
   lleva, así que se distingue del resto con el acento en el borde: el resto de
   la columna habla del canal hacia fuera y ésta es la única que hace algo. */
.mom-rc-her { border-color: color-mix(in srgb, var(--exc-accent) 45%, var(--exc-border)); }
.mom-rc-her h4 { display: flex; align-items: center; gap: .4rem; }
.mom-rc-her h4 svg { color: var(--exc-accent); font-size: 1.05rem; }
.mom-rc-her-ir {
  margin-top: .7rem;
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
}

/* Los siete días del canal, en «Acerca de».
 *
 * Se enseñan TODOS, también los cerrados: una lista con huecos obliga a
 * adivinar qué día falta, y «cerrado» es una respuesta tan buena como una hora.
 */
/* El día se escribe en minúscula en español («lunes») y la mayúscula inicial la
   pone el CSS: así la misma clave sirve para el inglés, donde va capitalizado
   de por sí, sin dos juegos de textos. */

/* HOY resaltado: es el renglón que se viene a mirar. Con el acento y no con un
   fondo, que a siete renglones seguidos los convierte en una tabla rayada. */

/* ══ La tira del PUESTO ══════════════════════════════════════════════════════
 *
 * Cuando un canal anuncia una vacante. Hermana de `.mom-comida` y en el mismo
 * sitio de la tarjeta —entre la foto y las reacciones—, porque hace lo mismo:
 * convertir una publicación en algo que se puede usar sin abrir nada.
 *
 * Vive aquí y no en `canales` por lo mismo que la de comida: es una tira DENTRO
 * de la tarjeta del muro y tiene que peinarse con su CSS, no con el de otro
 * módulo. Lo único que viene de fuera son los datos.
 */
.mom-vac {
  margin: .75rem 0 0;
  padding: .8rem .9rem;
  border-radius: var(--exc-radius-card);
  border: 1px solid var(--exc-border);
  background: var(--exc-surface-2);
}

/* Publicada de verdad se marca con un filete del acento. En revisión se queda
   neutra: el estado del trámite es del negocio, no de quien mira, y pintarlo
   como una advertencia haría dudar de la vacante. */
.mom-vac.is-lista { border-left: 3px solid var(--exc-accent); }

.mom-vac-top { display: flex; align-items: flex-start; gap: .7rem; }

.mom-vac-ico {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 34px; height: 34px;
  border-radius: 10px;
  font-size: 1rem;
  --exc-ico-w: 1.6;
  color: var(--exc-accent);
  background: var(--exc-accent-soft);
}

.mom-vac-que { flex: 1; min-width: 0; }

.mom-vac-nom {
  margin: 0;
  font-size: .95rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: .4rem;
  flex-wrap: wrap;
}

.mom-vac-chip {
  padding: .1rem .4rem;
  border-radius: 999px;
  font-size: .68rem;
  font-weight: 600;
  color: var(--exc-accent);
  background: var(--exc-accent-soft);
}

.mom-vac-meta {
  margin: .2rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: .1rem .7rem;
  font-size: .82rem;
  color: var(--exc-muted);
}
/* El sueldo es lo que más se mira de un anuncio de trabajo, así que se lee
   primero: en el color del texto y en negrita, no en el gris de los demás. */
.mom-vac-sueldo { font-weight: 700; color: var(--exc-text); }

.mom-vac-pie {
  display: flex;
  align-items: center;
  gap: .75rem;
  margin-top: .75rem;
  padding-top: .65rem;
  border-top: 1px solid var(--exc-border);
}

/* El proveedor: su marca y su nombre, a la izquierda del botón. El logotipo NO
   se tiñe —una marca ES sus colores— y por eso va como `<img>` y no por
   `Icon::svg()`, que toma el color de su contexto. */
.mom-vac-via {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  flex: 1;
  min-width: 0;
  font-size: .74rem;
  color: var(--exc-muted);
}
.mom-vac-via img { flex-shrink: 0; border-radius: 4px; }

/* Y cuando YA pasó la revisión, ese mismo hueco lleva el sello. Es la misma
   pastilla de la pestaña de Empleo y por la misma razón: sin ella, una vacante
   aprobada se leía en el muro exactamente igual que una que nadie ha mirado, y
   las dos cosas no valen lo mismo para quien está decidiendo si escribe.

   En AZUL y no en el oro del sitio: lo que afirma no lo firma Exclivia, lo
   firma SuperEmpleos — es su revisión. Pintarlo del acento de aquí sería
   ponerle nuestra cara a la palabra de otro. */
.mom-vac-ok {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  flex: 1;
  min-width: 0;
  padding: .25rem .6rem;
  border-radius: 999px;
  font-size: .74rem;
  font-weight: 600;
  background: rgba(37, 99, 235, .14);
  color: #7ba7ff;
}
/* La pastilla NO crece: hereda el hueco de `.mom-vac-via`, que es `flex: 1`
   para empujar el botón a la derecha, y con fondo propio eso la convertía en
   una barra azul de lado a lado. El empujón lo hace el margen. */
.mom-vac-ok { flex: 0 1 auto; margin-right: auto; }
.mom-vac-ok img { flex-shrink: 0; border-radius: 4px; }
:root[data-theme="light"] .mom-vac-ok { color: #1d4ed8; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .mom-vac-ok { color: #1d4ed8; }
}

.mom-vac-btn { font-size: .82rem; padding: .4rem .8rem; white-space: nowrap; }

/* En revisión y sin contacto puesto no hay a dónde mandar a nadie, así que se
   DICE en vez de pintar un botón apagado que se toca y no hace nada. */
.mom-vac-espera {
  font-size: .76rem;
  font-weight: 600;
  padding: .25rem .6rem;
  border-radius: 999px;
  color: var(--exc-muted);
  background: var(--exc-surface);
  white-space: nowrap;
}

@media (max-width: 480px) {
  /* El nombre del proveedor se va y queda su marca: en 360 px, «vía
     SuperEmpleos» y «Postúlate en SuperEmpleos» en el mismo renglón dejan al
     botón partido en dos líneas. El logotipo sigue diciendo de quién es. */
  .mom-vac-via span,
  .mom-vac-ok span { display: none; }
  /* Sin letras, la pastilla del sello sobra: queda el logotipo, como en el
     otro caso. */
  .mom-vac-ok { padding: 0; background: none; flex: none; }
}

/* Qué pide el negocio: CV o solicitud. En la tira del muro, junto al sueldo y
   la ciudad. Solo se pinta cuando pide algo CONCRETO —con «cualquiera» no se
   escribe, porque es lo que hace todo el mundo y en cada tarjeta sería ruido. */
.mom-vac-pide {
  padding: .05rem .4rem;
  border-radius: 999px;
  font-size: .72rem;
  font-weight: 600;
  color: var(--exc-text);
  background: var(--exc-surface);
  border: 1px solid var(--exc-border);
}

/* El botón de «te falta tu CV».
 *
 * En ámbar y en contorno, no en el acento ni en rojo: no es la acción que la
 * persona venía a hacer —quería postularse— pero tampoco está rota. Es un paso
 * que le falta, y el color lo dice sin alarmar. Misma familia que los avisos de
 * «encendida pero vacía» del catálogo de herramientas. */
.mom-vac-btn.is-falta {
  color: var(--exc-warning);
  border-color: color-mix(in srgb, var(--exc-warning) 45%, var(--exc-border));
  background: color-mix(in srgb, var(--exc-warning) 8%, transparent);
  --exc-ico-w: 1.8;
  gap: .35rem;
}
.mom-vac-btn.is-falta:hover {
  background: color-mix(in srgb, var(--exc-warning) 15%, transparent);
}

/* ══ EL ORDEN DE LAS FOTOS DE UN MOMENTO ═════════════════════════════════════
 *
 * Dentro del editor de la ficha. La primera es la PORTADA —lo único que se ve
 * en la rejilla del perfil y en la tarjeta del muro— y por eso lleva su rótulo:
 * sin él, «la primera» es una convención que hay que adivinar.
 */

.mom-edit-orden {
  margin-top: .8rem;
  padding-top: .8rem;
  border-top: 1px solid var(--exc-border);
}

.mom-edit-orden-t {
  margin: 0 0 .5rem;
  font-size: .78rem;
  font-weight: 600;
  color: var(--exc-muted);
}

.mom-orden-tira {
  margin: 0 0 .45rem;
  padding: 0 0 .3rem;
  list-style: none;
  display: flex;
  gap: .5rem;
  /* Se desliza de lado: diez fotos no caben, y envolverlas en varias filas
     rompe la idea de «orden» — con dos renglones, «la siguiente» deja de estar
     a la derecha. */
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
}

.mom-orden-it {
  position: relative;
  flex: 0 0 auto;
  width: 64px;
  border-radius: 10px;
  overflow: hidden;
  border: 2px solid transparent;
  line-height: 0;
}
/* La portada se distingue por el BORDE y por su rótulo, no solo por ir primera:
   deslizando la tira, la primera se sale de la vista y entonces no hay forma de
   saber cuál era. */
.mom-orden-it.es-primera { border-color: var(--exc-accent); }

.mom-orden-it img {
  width: 64px;
  height: 64px;
  object-fit: cover;
  display: block;
}

.mom-orden-video {
  position: absolute;
  top: 3px; left: 3px;
  display: grid;
  place-items: center;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font-size: .6rem;
  --exc-ico-w: 2;
}

.mom-orden-pri {
  position: absolute;
  top: 0; left: 0; right: 0;
  padding: .1rem 0;
  font-size: .58rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  text-align: center;
  line-height: 1.4;
  color: #fff;
  background: var(--exc-accent);
  /* Solo en la primera. Se esconde con `display` y no con `opacity`: un rótulo
     transparente lo sigue leyendo un lector de pantalla, y diría que las cinco
     fotos son la portada. */
  display: none;
}
.mom-orden-it.es-primera .mom-orden-pri { display: block; }

/* ── Las flechas ───────────────────────────────────────────────────────────── */

.mom-orden-btns {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex;
}

.mom-orden-btns button {
  flex: 1;
  padding: .18rem 0;
  border: 0;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  cursor: pointer;
  line-height: 1;
  font-size: .72rem;
  --exc-ico-w: 2.2;
}
.mom-orden-btns button:hover:not(:disabled) { background: var(--exc-accent); }

/* En el borde se APAGA en vez de desaparecer: un botón que se va deja la tira
   moviéndose bajo el dedo, y el siguiente toque cae en el que no era. */
.mom-orden-btns button:disabled { opacity: .3; cursor: default; }

/* ── La tira de la TIENDA ────────────────────────────────────────────────────
 *
 * De qué local de un centro comercial es esta oferta. Misma familia que la tira
 * del plato y la del puesto: entre la foto y las reacciones.
 *
 * El color de la tienda pinta SOLO el filete de la izquierda. Es un hex libre
 * —la marca registrada de alguien, no un gusto— y no hay forma de saber si
 * contrasta: el amarillo de Coppel sobre blanco no se lee. Sobre tres píxeles,
 * un color feo se ve feo y el texto se sigue leyendo.
 */
.mom-local {
  display: flex; align-items: center; gap: .65rem;
  margin: .7rem 0 0;
  padding: .55rem .7rem;
  border-radius: 10px;
  background: var(--exc-bg-soft, rgba(128,128,128,.07));
  border-left: 3px solid var(--mom-local-marca, var(--exc-accent));
}

.mom-local-logo {
  width: 40px; height: 40px; flex: none;
  object-fit: contain;   /* contenido, no recortado: un logotipo apaisado
                            recortado pierde el nombre de la marca */
  background: #fff;      /* casi todos son PNG transparentes hechos para papel
                            blanco; sobre el modo noche son una mancha */
  border-radius: 8px; padding: 3px;
}

.mom-local-ini {
  width: 40px; height: 40px; flex: none;
  display: grid; place-items: center;
  border-radius: 8px;
  background: rgba(var(--exc-accent-rgb), .12);
  color: var(--exc-accent);
  font-weight: 700; font-size: .82rem;
}

.mom-local-txt { flex: 1; min-width: 0; }   /* o un nombre largo empuja el enlace
                                               fuera de la tarjeta */
.mom-local-nom {
  margin: 0; font-weight: 600; font-size: .92rem; line-height: 1.2;
  overflow-wrap: anywhere;
}
.mom-local-et  { margin: .1rem 0 0; font-size: .76rem; color: var(--exc-muted); }

.mom-local-ir {
  flex: none; font-size: .84rem; color: var(--exc-accent);
  text-decoration: none; white-space: nowrap;
  /* 44 px de alto de golpeo aunque la letra mida 13: se toca con el pulgar. */
  min-height: 44px; display: inline-flex; align-items: center; padding: 0 .2rem;
}
.mom-local-ir:hover { text-decoration: underline; }

/* ══ LA FICHA PÚBLICA, v2 ════════════════════════════════════════════════════
 *
 * Tres cambios sobre lo que había, y los tres salen de mirar la pantalla en un
 * teléfono:
 *
 *   1. Ciudad, horario y números iban en tres párrafos apilados — tres renglones
 *      para tres datos cortos, que empujaban los botones fuera de la primera
 *      pantalla. Ahora son UNA fila que envuelve.
 *   2. «Acerca de» era un `<dl>` de parejas rótulo/valor, así que la bio, el
 *      giro, los siete días y el mapa pesaban lo mismo. Ahora son tarjetas, y
 *      cada una contesta una de las tres preguntas que trae quien abre esto.
 *   3. El mapa, que es lo único que no se lee sino que se mira, baja al ancho
 *      entero en vez de competir arriba con lo que sí se lee.
 */

/* ── La fila de datos del encabezado ─────────────────────────────────────── */

.mom-pub-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  /* Ver arriba, donde vivía la raya: el hueco ancho ES el separador. */
  gap: .4rem 1.35rem;
  margin-top: .6rem;
}

/* Los hijos pierden el margen que traían de cuando cada uno era un párrafo: en
   una fila, ese margen los descuadra verticalmente entre sí. */
.mom-pub-meta > * { margin: 0; }

/* ── Las tarjetas de «Acerca de» ─────────────────────────────────────────── */

.mom-pub-acerca-rejilla {
  display: grid;
  gap: 1rem;
  margin-bottom: 1rem;
}

.mom-ac { display: grid; gap: .85rem; align-content: start; }

.mom-ac-t {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
}

.mom-ac-bio {
  margin: 0;
  color: var(--exc-text);
  line-height: 1.6;
  /* Una bio larga no puede desbordar la tarjeta, y `anywhere` parte palabras a
     la mitad —ya pasó con «Electrodomésticos»—, así que `break-word`. */
  overflow-wrap: break-word;
}

/* ── Los dos datos cortos, en fila y con su icono ────────────────────────── */

.mom-ac-datos {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  /* Separados del texto por una raya, no por aire: sin ella el dato y la bio se
     leen como un solo párrafo que cambia de tamaño a la mitad. */
  padding-top: .85rem;
  border-top: 1px solid var(--exc-border);
}
/* Sin bio no hay nada arriba de lo que separarse. */
.mom-ac-bio:first-child + .mom-ac-datos { border-top: 1px solid var(--exc-border); }
.mom-ac-t + .mom-ac-datos { border-top: 0; padding-top: 0; }

.mom-ac-datos > div { display: flex; align-items: center; gap: .55rem; }
.mom-ac-datos svg { flex: none; color: var(--exc-accent); --exc-ico-w: 1.6; }
.mom-ac-datos dt { color: var(--exc-muted); font-size: .78rem; }
.mom-ac-datos dd { margin: 0; font-weight: 600; font-size: .92rem; }

/* ── El horario ──────────────────────────────────────────────────────────── */

/* Lo primero es si está abierto AHORA: es la pregunta de nueve de cada diez
   visitas. Lleva el TEXTO escrito y no solo el punto de color — uno de cada
   doce hombres no distingue el verde del rojo. */
.mom-ac-estado {
  display: flex;
  align-items: center;
  gap: .45rem;
  margin: 0;
  font-weight: 600;
}
.mom-ac-punto {
  width: 9px; height: 9px;
  border-radius: 50%;
  flex: none;
  background: currentColor;
}
.mom-ac-estado.is-si { color: var(--exc-success); }
.mom-ac-estado.is-no { color: var(--exc-danger); }

.mom-ac-hoy {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  margin: -.4rem 0 0;
  font-size: .92rem;
}
.mom-ac-hoy span { color: var(--exc-muted); }
.mom-ac-hoy b { font-variant-numeric: tabular-nums; }

/* La semana en DOS columnas: siete renglones de dos palabras y una hora dejan
   media tarjeta vacía a la derecha, y encima estiran la caja hasta que el mapa
   de abajo queda fuera de la pantalla. */
.mom-ac-sem {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: .1rem .9rem;
  grid-template-columns: 1fr;
}

.mom-ac-sem li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .8rem;
  padding: .3rem .5rem;
  border-radius: 7px;
  font-size: .88rem;
}
.mom-ac-sem li > span { text-transform: capitalize; color: var(--exc-muted); }
.mom-ac-sem li > b { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* HOY, en una pastilla del acento. Es el renglón que se viene a buscar, y en
   una lista de siete iguales hay que encontrarlo contando. */
.mom-ac-sem li.es-hoy {
  background: color-mix(in srgb, var(--exc-accent) 14%, transparent);
  color: var(--exc-accent);
}
.mom-ac-sem li.es-hoy > span,
.mom-ac-sem li.es-hoy > b { color: var(--exc-accent); font-weight: 700; }

/* ── «Ver horario completo» ──────────────────────────────────────────────── */

.mom-ac-mas > summary {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  cursor: pointer;
  padding: .35rem .7rem;
  border: 1px solid var(--exc-border);
  border-radius: 999px;
  font-size: .82rem;
  color: var(--exc-muted);
  /* El triángulo del navegador no obedece al tema y en modo noche sale de un
     gris que no es ninguno de los nuestros. Se quita y manda el icono. */
  list-style: none;
}
.mom-ac-mas > summary::-webkit-details-marker { display: none; }
.mom-ac-mas > summary:hover { border-color: var(--exc-accent); color: var(--exc-accent); }
.mom-ac-mas[open] > summary svg { transform: rotate(180deg); }
.mom-ac-mas > summary svg { transition: transform .15s; --exc-ico-w: 1.8; }

.mom-ac-comidas {
  margin: .7rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: .25rem;
  font-size: .85rem;
}
.mom-ac-comidas li { display: flex; justify-content: space-between; gap: .8rem; }
.mom-ac-comidas span { text-transform: capitalize; color: var(--exc-muted); }
.mom-ac-comidas b { font-weight: 500; color: var(--exc-muted); }

/* ── «Encuéntranos» ──────────────────────────────────────────────────────── */

.mom-ac-donde-cuerpo { display: grid; gap: 1rem; }

.mom-ac-donde-txt { display: grid; gap: .9rem; align-content: start; }

.mom-ac-dir {
  display: flex;
  align-items: flex-start;
  gap: .55rem;
  margin: 0;
}
.mom-ac-dir svg { flex: none; color: var(--exc-accent); --exc-ico-w: 1.7; margin-top: .1rem; }
.mom-ac-dir > span { display: grid; gap: .1rem; min-width: 0; }
.mom-ac-dir b { font-weight: 600; }
.mom-ac-dir small { color: var(--exc-muted); font-size: .85rem; line-height: 1.45; }

.mom-ac-donde-btns { display: flex; flex-wrap: wrap; gap: .5rem; }

.mom-ac-mapa { margin: 0; }
.mom-ac-mapa img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--exc-radius-card);
  /* Un borde tenue lo despega del fondo: el mapa es claro y sobre una tarjeta
     clara sus bordes se pierden y parece que la imagen se sale de la caja. */
  border: 1px solid var(--exc-border);
}
/* La atribución no es opcional: los datos son de OpenStreetMap (ODbL) y el
   estilo de CARTO. Pequeña y debajo, pero nunca escondida. */
.mom-ac-mapa figcaption {
  margin-top: .3rem;
  font-size: .68rem;
  color: var(--exc-muted);
}

/* El mapa VIVO de megacitygo.io, para un canal con su padrón sincronizado.
   Alto fijo y no `aspect-ratio`: un mapa no se recorta como una foto, y en un
   teléfono estrecho una proporción 16:9 dejaría 200 px de alto. */
.mom-ac-vivo {
  display: block;
  width: 100%;
  height: 340px;
  border: 1px solid var(--exc-border);
  border-radius: var(--exc-radius-card);
  overflow: hidden;
  background: var(--exc-bg-soft, rgba(128, 128, 128, .08));
}

.mom-ac-solo-ciudad {
  display: flex;
  align-items: center;
  gap: .4rem;
  margin: 0;
  color: var(--exc-muted);
  --exc-ico-w: 1.7;
}
.mom-ac-solo-ciudad svg { color: var(--exc-accent); }

/* ── Y en pantalla ancha ─────────────────────────────────────────────────── */

@media (min-width: 720px) {
  /* Sobre y Horario, lado a lado. El horario pide menos ancho —son horas— así
     que la bio se queda con lo que sobra. */
  .mom-pub-acerca-rejilla { grid-template-columns: minmax(0, 1fr) minmax(0, .85fr); }

  /* La dirección a la izquierda y el mapa a la derecha, con el mapa en su
     tamaño natural: estirado a mil píxeles se ve borroso —lo compone el
     servidor a 640— y deja la dirección sola en un renglón larguísimo. */
  .mom-ac-donde-cuerpo {
    grid-template-columns: minmax(200px, 1fr) minmax(0, 640px);
    gap: 1.4rem;
    align-items: start;
  }

  .mom-ac-vivo { height: 420px; }
}

/* ══ daClic: la otra dirección del perfil ═══════════════════════════════════
 *
 * La que ya tienen impresa en un volante o pegada en el costado del camión.
 * Sale con la manita de la marca, que es lo que la hace reconocible de un
 * vistazo para quien ya la ha visto en otro sitio.
 *
 * Va en el ORO del sitio y no en el índigo de daClic: ver el porqué más
 * abajo, donde estaban sus variables. Lo que la identifica es la MANITA.
 */

/* ── La dirección de daClic en la ficha ─────────────────────────────────────
 *
 * Renglón propio bajo los números: es una DIRECCIÓN y no un dato de la cuenta,
 * y metida entre «3 Momentos» y «799 Seguidores» se lee como otra cifra más.
 *
 * En su índigo y con su manita, como el renglón del rail — la marca es de
 * ellos. `width: fit-content` para que el área que se toca sea el texto y no
 * toda la fila: un enlace que ocupa el ancho entero se pulsa sin querer al
 * intentar desplazar la página con el pulgar.
 */
.mom-pub-daclic {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  width: fit-content;
  max-width: 100%;
  margin-top: .45rem;
  /* El TEXTO con el tono legible; la manita, con el de la marca. */
  color: var(--exc-accent);
  font-size: .88rem;
  font-weight: 500;
  text-decoration: none;
}

.mom-pub-daclic:hover span { text-decoration: underline; }
/* La manita hereda el tono del texto. A 20 px un trazo se lee como una
   letra más, y con el índigo de marca quedaba visiblemente más apagada que
   su propia dirección — que es peor que no distinguirla. La marca se
   reconoce por la FORMA; el tono solo tiene que dejarla ver. */
.mom-pub-daclic svg { flex: none; font-size: 1.05em; }

/* La dirección se recorta antes que desbordar la ficha: partida en dos
   renglones deja de leerse como una dirección. */
.mom-pub-daclic span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── daClic va en el ORO del sitio, no en su índigo ─────────────────────────
 *
 * Estuvo en `#4f46e5` —su color de marca— y se cambió. Dos razones, y la
 * segunda es la que manda:
 *
 *   1. Se ve mejor. Un renglón índigo entre el oro del acento y el gris del
 *      texto es la única cosa de otro color en toda la ficha, y llama más
 *      atención de la que merece un enlace que lleva fuera.
 *
 *   2. El índigo NO se puede leer en modo noche: sobre la superficie oscura da
 *      **2.90:1** y el mínimo de un texto son 4.5:1. Aclarado a `#818cf8`
 *      cumple de noche (6.12) y se cae en claro (2.98), así que hacían falta
 *      dos tonos y un `[data-theme]` para un solo enlace. El oro del sitio ya
 *      está medido en los dos fondos — es el acento de todo lo demás.
 *
 * Lo que identifica a daClic aquí sigue siendo la MANITA: una marca se
 * reconoce por su forma, y el color de un icono monocromo en el pie de un
 * perfil no es lo que la hace suya.
 */


/* ── Y el campo de la hoja de editar ────────────────────────────────────────
 *
 * El prefijo `daclic.mx/` va PINTADO a la izquierda del campo y no dentro del
 * `placeholder`: así se ve que solo hace falta escribir el nombre, que es lo
 * único que quien llena esto recuerda. El servidor acepta igual la dirección
 * entera — el prefijo es una ayuda, no una regla. */
.mom-daclic-et {
  display: inline-grid;
  place-items: center;
  color: var(--exc-accent);
  font-size: 1.05em;
  vertical-align: -.15em;
  margin-right: .3rem;
}

.mom-daclic-campo {
  display: flex;
  align-items: stretch;
  border: var(--exc-border-width, 1px) solid var(--exc-border);
  border-radius: var(--exc-radius-sm, 10px);
  overflow: hidden;
  background: var(--exc-surface-2, var(--exc-surface));
}

.mom-daclic-campo:focus-within { border-color: var(--exc-accent); }

.mom-daclic-pre {
  display: grid;
  place-items: center;
  padding: 0 .1rem 0 .7rem;
  color: var(--exc-muted);
  font-size: .88rem;
  white-space: nowrap;
  user-select: none;
}

/* El input pierde su propia caja: la caja ahora es la del grupo, y con las dos
   se veía un recuadro dentro de otro. */
.mom-daclic-campo .exc-input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  border-radius: 0;
  padding-left: 0;
}

.mom-daclic-campo .exc-input:focus { outline: none; box-shadow: none; }

/* Los CÍRCULOS bajo la ficha, en la página pública.
 *
 * `.mom-circ` la comparten esta pantalla y el perfil de dentro del panel, así
 * que el aire se pone desde FUERA con el hermano adyacente en vez de tocar el
 * parcial: allá vive dentro de una tarjeta que ya tiene su relleno, y el mismo
 * margen le dejaría un hueco en medio.
 *
 * Pegados a la ficha se leían como parte de ella —una fila más de datos— y lo
 * que son es lo contrario: la respuesta corta a «¿y esta cuenta de qué va?».
 */
.mom-pub-ficha + .mom-circ {
  margin: 1rem 0 1.25rem;

  /* ── Centrados, y el `safe` no es adorno ─────────────────────────────────
   *
   * Aquí la columna mide más de mil píxeles y cinco círculos ocupan
   * cuatrocientos: pegados a la izquierda dejaban dos tercios de nada al lado
   * y se leían como una fila que se cortó. En el perfil de dentro del panel
   * no pasa —viven en una tarjeta estrecha— y por eso esto va en el hermano
   * adyacente y no en `.mom-circ`.
   *
   * `safe center` y NUNCA `center` a secas: esta fila se DESPLAZA a lo ancho,
   * y un flex centrado que desborda reparte el sobrante a los dos lados —
   * el trozo de la izquierda queda antes del origen del scroll y no hay forma
   * de llegar a él. Con quince intereses, los primeros serían inalcanzables.
   * `safe` vuelve a `flex-start` en cuanto no cabe.
   *
   * Y si un navegador no entiende la palabra, tira la declaración entera y se
   * queda alineado a la izquierda, que es exactamente como estaba. */
  justify-content: safe center;
}

/* ══ La pestaña «Acerca de» ═════════════════════════════════════════════════
 *
 * Su cabecera, igual que la de espacios: el antetítulo dice de qué va antes que
 * el titular, porque quien la abre no sabe si aquí hay horarios, dirección o la
 * historia del negocio — y las tres están.
 */
.mom-ac-h { margin-bottom: 1rem; }
.mom-ac-ojo {
  margin: 0 0 .3rem; color: var(--exc-accent);
  font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
}
.mom-ac-tit {
  margin: 0; font-family: var(--exc-font-display, inherit);
  font-size: clamp(1.4rem, 3.2vw, 1.95rem); line-height: 1.14;
}
.mom-ac-sub { margin: .35rem 0 0; color: var(--exc-muted); font-size: .92rem; }

/* La primera tarjeta lleva filete en el acento: es la que contesta «qué es
   esto» y con todas iguales no había por dónde empezar a leer. */
.mom-ac-sobre { border-left: 3px solid var(--exc-accent); }

/* La semana en DOS columnas, y quien lo decide es el ANCHO DE LA TARJETA.
 *
 * Estaba en `@media (min-width: 720px)` y eso mira el VIEWPORT: desde que esta
 * pantalla tiene rail, en un escritorio de 1400 px el panel mide 772 y la
 * tarjeta del horario 347 — dos columnas de 13rem no caben en 347, así que la
 * lista se salía 108 px de su tarjeta y «Viernes» y «Sábado» quedaban cortados
 * por el borde. La misma trampa anotada en `pronto.css`.
 *
 * `grid-auto-flow: column` con cuatro filas fijas, y no dos columnas a secas:
 * con el flujo normal los días se reparten POR FILAS —lunes y martes juntos,
 * miércoles y jueves debajo— y para leer la semana en orden hay que ir en
 * zigzag. Bajando por la columna, los días van seguidos. Cuatro filas porque
 * siete días entre dos columnas dan 4 y 3.
 *
 * El umbral son 32rem y no 26: el renglón más largo —«miércoles 9:00 am – 8:00
 * pm» con el relleno de la pastilla de hoy— pide 233 px, así que dos columnas y
 * su hueco necesitan 492. Con un umbral más flojo caben las dos columnas y se
 * sale el texto, que es el mismo fallo con otra cara.
 *
 * Donde no haya `@container` se queda en una columna: se lee igual, ocupa más.
 */
.mom-ac { container-type: inline-size; }

@container (min-width: 32rem) {
  .mom-ac-sem {
    grid-auto-flow: column;
    grid-template-rows: repeat(4, auto);
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

/* Y un renglón no puede estirar su columna: `1fr` es `minmax(auto, 1fr)` y su
   mínimo es el contenido, con la hora en `nowrap` detrás. */
.mom-ac-sem li { min-width: 0; }

/* El horario de hoy, en el rail. */
.mom-card-hoy .mom-ac-estado { margin: 0; }
.mom-card-horas {
  margin: .15rem 0 0; font-size: 1.15rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ── «Muy pronto»: el renglón que solo ve el dueño ───────────────────────────
 *
 * Por qué no están sus pestañas y dónde se apaga. Atenuado y con su icono de
 * ojo: es una nota de trabajo dentro de una portada pública, y tiene que
 * leerse como algo que no forma parte de ella.
 */
.mom-pronto-nota {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .45rem;
  margin: .9rem 0 0;
  padding: .7rem .9rem;
  border: 1px dashed var(--exc-border);
  border-radius: 10px;
  color: var(--exc-muted);
  font-size: .85rem;
  line-height: 1.45;
}
.mom-pronto-nota svg { flex: none; color: var(--exc-accent); }
.mom-pronto-nota span { min-width: 0; }

/* El encabezado del panel de rutas, cuando son varias. Solo se pinta ahí, así
   que no hereda del `h2` de las demás pestañas. */
.cr-h {
    margin: 0 0 .25rem;
    font-size: 1.15rem;
}

/* ── Lista o rejilla en el perfil PÚBLICO ──────────────────────────────────
 *
 * Los dos iconos, alineados a la derecha sobre las publicaciones. Reusa
 * `.mom-pf-v` —el mismo botón del perfil de dentro del panel— para que el
 * control se vea igual en las dos pantallas; lo único propio es dónde se
 * coloca.
 */
.mom-pub-vista {
    display: flex;
    justify-content: flex-end;
    gap: .25rem;
    margin: 0 0 .75rem;
}

/* `[hidden]` pierde ante un `display` declarado y aquí no hay regla global que
   lo arregle: cada caso pone la suya. Sin estas dos, lista y rejilla se
   pintarían una encima de otra. */
.mom-pub-lista[hidden],
.mom-pub-rejilla[hidden] {
    display: none;
}

/* ── La ficha de un canal con DISTINTIVO ───────────────────────────────────
 *
 * El color del canal deja de ser un detalle y pasa a ser la identidad de la
 * tarjeta. Todo sale de `--cal-c`, que pone la clase `exc-cal-<color>` en la
 * propia ficha — por eso la clase va ahí y no dentro: desde la ficha la heredan
 * sus hijos, y colgada de la pastilla no había forma de teñir a sus hermanos.
 *
 * Sin color elegido manda el acento del sitio, así que la ficha se ve igual de
 * intencionada el primer día.
 */
.mom-pub-ficha.is-sello,
.mom-pf-ficha.is-sello {
    /* El contenedor de la consulta de abajo. Sin esta línea `@container` no
       dispara NUNCA y la barra se queda en una sola fila en el teléfono. */
    container-type: inline-size;

    --sello-c:   var(--cal-c, var(--exc-accent));
    --sello-rgb: var(--cal-c-rgb, var(--exc-accent-rgb, 212, 175, 55));

    /* El BORDE sí lleva el color; el fondo NO.
     *
     * Estuvo teñido al 6 % y se veía peor: sobre el negro del sitio, un velo de
     * color convierte la tarjeta en un rectángulo marrón y le quita fuerza a lo
     * único que tiene que resaltar, que es el distintivo. Con el fondo negro,
     * el color queda donde dice algo —el borde, el aro del retrato, la barra,
     * la raya de la bio— y la foto de portada no compite con nada.
     *
     * Se deja heredar `var(--exc-surface)` de `.mom-pub-ficha` en vez de
     * repetirlo aquí: escrito dos veces, cambiar el fondo del sitio dejaría
     * estas tarjetas con el de antes.
     */
    border-color: rgba(var(--sello-rgb), .45);
}

/* El aro del retrato, del color del canal. */
.mom-pub-ficha.is-sello .mom-pub-foto,
.mom-pf-ficha.is-sello .mom-pub-foto {
    box-shadow: 0 0 0 3px rgba(var(--sello-rgb), .55);
}

/* La pastilla del giro, también. Es la que dice «Gobierno» al lado de «Canal»,
   y en un canal oficial esa palabra es la que se viene a leer. */
.mom-pub-ficha.is-sello .mom-pub-giro,
.mom-pf-ficha.is-sello .mom-pub-giro {
    color: var(--sello-c);
    border-color: rgba(var(--sello-rgb), .45);
    background: rgba(var(--sello-rgb), .12);
}

/* ── La barra oficial ──────────────────────────────────────────────────────
 *
 * A lo ancho y no una pastilla: es lo primero que hay que leer en la página de
 * un ayuntamiento. Es un `<button>` porque LLEVA a «Acerca de» — el aspecto de
 * barra pulsable sin destino enseña a no tocar las que sí llevan.
 */
.mom-pub-sello {
    display: flex;
    align-items: center;
    gap: .55rem;
    width: 100%;
    margin: .35rem 0 .1rem;
    padding: .5rem .85rem;
    border: 1px solid rgba(var(--sello-rgb), .45);
    border-radius: 10px;
    background: rgba(var(--sello-rgb), .10);
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.mom-pub-sello:hover { background: rgba(var(--sello-rgb), .16); }

.mom-pub-sello:focus-visible {
    outline: 2px solid var(--sello-c);
    outline-offset: 2px;
}

/* El icono en su propia caja: sin ella, con un trazo fino se pierde al lado de
   un texto en negrita. */
.mom-pub-sello-ico {
    display: grid;
    place-items: center;
    flex: none;
    width: 1.85rem;
    height: 1.85rem;
    border-radius: 7px;
    background: rgba(var(--sello-rgb), .18);
    color: var(--sello-c);
}

.mom-pub-sello b {
    flex: none;
    color: var(--sello-c);
    font-size: .95rem;
}

/* El separador es un pseudo-elemento y no un carácter: un «|» escrito lo lee un
   lector de pantalla y ahí no dice nada. Por eso además va `aria-hidden`. */
.mom-pub-sello i {
    flex: none;
    width: 1px;
    height: 1.1rem;
    background: rgba(var(--sello-rgb), .45);
}

.mom-pub-sello small {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--exc-text-2, #9aa0a6);
    font-size: .88rem;
}

.mom-pub-sello-mas {
    display: grid;
    place-items: center;
    flex: none;
    margin-left: auto;
    color: rgba(var(--sello-rgb), .75);
}

/* ── En un TELÉFONO, todo en un renglón ────────────────────────────────────
 *
 * Estaba al revés: la barra envolvía y la segunda línea bajaba al ancho
 * entero. Medido en uno de 390 px, eso eran **126 px de los 411** que medía la
 * ficha —tres renglones para un dato— y había que bajar 1 215 px para llegar a
 * las pestañas.
 *
 * Ahora no envuelve: la línea del canal se recorta con puntos suspensivos. Una
 * línea cortada se entiende; tres renglones ocupando media pantalla para decir
 * lo mismo, no. Lo que de verdad hay que leer —«Página oficial»— nunca se
 * recorta, porque va en `flex: none`.
 */
@container (max-width: 26rem) {
    .mom-pub-sello {
        flex-wrap: nowrap;
        gap: .45rem;
        padding: .4rem .6rem;
    }

    .mom-pub-sello-ico { width: 1.5rem; height: 1.5rem; }
    .mom-pub-sello b   { font-size: .88rem; }

    /* `min-width: 0` es lo que hace posible el recorte: un hijo de flex mide
       por defecto su contenido y no baja de ahí, así que sin esta línea el
       `ellipsis` no aparece nunca y lo que pasa es que la barra desborda. */
    .mom-pub-sello small {
        flex: 1 1 auto;
        min-width: 0;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        padding-left: 0;
    }

    /* La pastilla del giro sobra aquí: la barra de debajo ya dice —mejor— que
       esto es una página de gobierno, y en un teléfono se lleva un renglón
       entero para repetirlo. */
    .mom-pub-ficha.is-sello .mom-pub-giro,
    .mom-pf-ficha.is-sello  .mom-pub-giro { display: none; }
}

/* La bio, con la raya del color a la izquierda. Solo en una ficha con
   distintivo: en las demás sigue siendo un párrafo suelto. */
.mom-pub-ficha.is-sello .mom-pub-bio,
.mom-pf-ficha.is-sello .mom-pub-bio {
    padding-left: .65rem;
    border-left: 3px solid var(--sello-c);
}
/* ── Editar el distintivo (solo canales de gobierno) ───────────────────────── */
.mom-sello-ed {
    display: grid;
    /* `minmax(0, 1fr)` y no `1fr`: con `1fr` el mínimo es el contenido y una
       línea larga estira la hoja por encima de su padre. */
    grid-template-columns: minmax(0, 1fr);
    gap: .45rem;
}

/* La línea que pone Exclivia: es una MUESTRA, no un campo. Va con el fondo de
   una caja deshabilitada para que se lea como «esto no lo escribes tú». */
.mom-sello-fija {
    display: flex;
    align-items: center;
    gap: .45rem;
    margin: 0;
    padding: .45rem .7rem;
    border-radius: 8px;
    background: var(--exc-surface-2, rgba(255, 255, 255, .04));
    color: var(--exc-text-2, #9aa0a6);
    font-size: .9rem;
}

.mom-sello-sub {
    margin-top: .35rem;
}

.mom-sello-colores,
.mom-sello-iconos {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
}

/* El radio de verdad se esconde pero NO se quita: se mueve fuera de la vista
   con `position: absolute` para que siga recibiendo el foco del teclado. Con
   `display: none` deja de ser enfocable y el grupo no se puede recorrer. */
.mom-sello-c input,
.mom-sello-i input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    pointer-events: none;
}

.mom-sello-c {
    position: relative;
    cursor: pointer;
}

.mom-sello-c > span {
    display: block;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--cal-c, var(--exc-accent));
    border: 2px solid transparent;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .12) inset;
}

.mom-sello-c input:checked + span {
    border-color: var(--exc-text, #fff);
}

.mom-sello-c input:focus-visible + span {
    outline: 2px solid var(--exc-accent);
    outline-offset: 2px;
}

.mom-sello-i {
    position: relative;
    cursor: pointer;
}

.mom-sello-i > span {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border-radius: 8px;
    border: 1px solid var(--exc-border, rgba(255, 255, 255, .12));
    color: var(--exc-text-2, #9aa0a6);
}

.mom-sello-i input:checked + span {
    border-color: var(--exc-accent);
    color: var(--exc-accent);
    background: rgba(var(--exc-accent-rgb, 212, 175, 55), .10);
}

.mom-sello-i input:focus-visible + span {
    outline: 2px solid var(--exc-accent);
    outline-offset: 2px;
}

/* La barra dentro del panel no lleva a ningún sitio, así que no se anuncia
   como pulsable: ni cursor, ni fondo al pasar por encima. */
.mom-pub-sello.is-quieta {
    cursor: default;
}

.mom-pub-sello.is-quieta:hover {
    background: rgba(var(--sello-rgb), .10);
}

/* ── El retrato SOBRE la portada, solo en un teléfono ──────────────────────
 *
 * En escritorio el retrato va al lado y NO se monta: la portada de un negocio
 * suele llevar su nombre escrito en el centro y el avatar lo taparía. Esa
 * decisión se queda — ahí la portada mide 193 px y es una imagen que se mira.
 *
 * En un teléfono el cálculo es otro. La portada mide 90 px, el retrato se lleva
 * 70 de ancho al lado del nombre, y al nombre le quedan 260: medido, «Deportes
 * Villa de Pozos» ocupa 244 y su sello 18, así que el sello caía solo a un
 * renglón por SEIS píxeles. Eso no se arregla bajando la letra —el siguiente
 * nombre un poco más largo lo rompe igual—: se arregla dándole el ancho entero.
 *
 * ── Y se ancla a la FICHA, no a la portada ─────────────────────────────────
 *
 * El retrato vive dentro de `.mom-pub-ficha` y no dentro de `.mom-pub-portada`
 * —son hermanas—, así que un `top: 100%` buscando la portada no la encuentra:
 * sube hasta el primer ancestro posicionado, que no existe, y acaba anclado a
 * la página. Pasó: el avatar se fue a `y = 813`, media pantalla más abajo.
 *
 * Va relativo a la ficha y se TIRA hacia arriba con un `top` negativo, que es
 * lo que lo monta sobre la esquina de la portada — la esquina y no el centro,
 * que es lo que la decisión de arriba protege.
 */
@media (max-width: 30rem) {
    .mom-pub-ficha {
        position: relative;
        /* Sitio para la parte del retrato que asoma por arriba. */
        padding-top: 2.4rem;
    }

    .mom-pub-retrato {
        position: absolute;
        top: -1.7rem;
        left: .85rem;
        z-index: 2;
    }

    /* La portada deja de recortar para que el retrato pueda salirse. El radio
       lo conserva la imagen, que es lo que se ve. */
    .mom-pub-portada { overflow: visible; }
    .mom-pub-portada > img,
    .mom-pub-portada picture {
        border-radius: var(--exc-radius-card) var(--exc-radius-card) 0 0;
    }

    /* Sin columna para el retrato, el nombre se lleva el ancho entero. */
    .mom-pub-datos {
        flex: 1 1 100%;
        min-width: 0;
    }

    .mom-pub-foto {
        width: 3.9rem;
        height: 3.9rem;
        border-radius: 1rem;
    }
}
/* ── La columna de datos del panel, en un TELÉFONO ─────────────────────────
 *
 * Por debajo de 992 px la ficha es una COLUMNA, no una fila. Ahí un
 * `flex-basis` actúa sobre el ALTO y no sirve de nada para el ancho: la
 * columna se dimensiona por su contenido, y la barra oficial —que no envuelve—
 * pedía 414 px dentro de una ficha de 358. La página se iba de lado.
 *
 * Medido: el mismo panel SIN distintivo daba 340 de 358 y no desbordaba, así
 * que esto lo traía la barra.
 *
 * Lo que lo arregla es decirle que ocupe el ancho del padre y que pueda bajar
 * de su mínimo automático. Las dos cosas: `width` sola deja el `min-width:
 * auto` en pie, y `min-width` sola no la estira.
 */
@media (max-width: 991px) {
    .mom-pf-datos {
        width: 100%;
        min-width: 0;
    }
}


/* El total de reacciones en la vista pública (sin cuenta): se lee sin sumar los seis iconos. */
.mom-pie-total { margin-left: .35rem; align-self: center; font-size: .9rem; font-weight: 700; color: var(--exc-text); text-decoration: none; white-space: nowrap; }
.mom-pie-total:hover { color: var(--exc-accent); }
