/* Los mensajes, en filas planas y no en burbujas.
 *
 * Avatar a la izquierda, nombre en negrita y hora en gris en la misma linea,
 * texto debajo a todo el ancho de la columna. Los mensajes propios van igual
 * que los ajenos: los distingue el nombre, no el lado. Una racha del mismo
 * autor esconde avatar y nombre y ensena la hora en el canal del avatar al
 * pasar por encima. Es la lectura de Slack, que es la que ya saben los ojos.
 *
 * Las clases que pone el formateador (message--me, --threaded, --first-of-day,
 * --mentioned, --formatted) y los ganchos de los controladores no cambian. */
.message-area {
  display: contents;

  &:has(.message) {
    .message-area--empty {
      display: none;
    }
  }

  &:not(:has(.message)) {
    --opacity: 0.2;

    block-size: 100%;
    display: grid;
    place-content: center stretch;
    place-items: center center;

    > * {
      grid-area: 1/1;
    }

    /* Un token y no un literal: la bienvenida (`welcome/show`) quiere el
       dibujo a pantalla completa, y el vacío de una conversación no. */
    .message-area--empty > figure img {
      inline-size: var(--empty-illustration-size, 30dvw);
    }
  }
}

/* El texto del vacío de una conversación. */
.room__empty {
  margin-inline: auto;
  max-inline-size: 40ch;
}

.room__empty-figure {
  --empty-illustration-size: min(8rem, 24dvw);
}

.room__empty-figure img {
  display: block;
  margin-inline: auto;
}

.message-area__return-to-latest {
  animation: pulsing-outline 2s infinite both;
  outline: 0 solid var(--color-selected-dark);
  inset-block-end: var(--footer-height);
  inset-inline-start: calc(50% - calc(var(--btn-size) / 2));
  position: absolute;
}

/* La bienvenida con el enlace de invitacion: la unica tarjeta de la lista. */
#system_welcome {
  --avatar-size: 5ch;

  display: block;
  margin-block-start: calc(var(--avatar-size) * 2);
  position: relative;
  z-index: 1;

  .avatar {
    margin-block-start: calc(var(--avatar-size) * -0.5);
  }

  .message__body {
    display: block;
    max-inline-size: unset;
  }

  .message__body-content {
    background-color: var(--color-message-bg);
    border-radius: 0.75em;
    overflow: unset;
    padding: var(--block-space) var(--inline-space-double);
  }

  .system-welcome--translation {
    inset-block-start: var(--block-space);
    inset-inline-start: var(--block-space);
    position: absolute;
  }

  .invite-label,
  .btn--regenerate {
    display: none;
  }
}

.messages {
  /* El canal del avatar y el hueco hasta el texto. Lo comparten la fila, la
     hora de la racha y la sangria de lo que cuelga del mensaje. */
  --message-gutter: 2.4rem;
  --message-column-gap: 0.7rem;
  --message-inline-pad: calc(var(--inline-space) + 1vw);
  /* Aire entre mensajes de autores distintos; dentro de una racha, casi nada. */
  --message-space: 0.5rem;
  --message-row-gap: 0;

  display: grid;
  flex: 1;
  grid-auto-rows: min-content;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-block: var(--block-space) var(--block-space-half);
  position: relative;
  row-gap: 0;
}

.message {
  column-gap: var(--message-column-gap);
  display: grid;
  grid-template-areas:
    "sep sep"
    "avatar body";
  grid-template-columns: var(--message-gutter) minmax(0, 1fr);
  grid-template-rows: min-content min-content;
  padding-block: 0.3rem;
  padding-inline: var(--message-inline-pad);
  position: relative;
  visibility: hidden;
  z-index: 0;

  .message__boost-inline {
    display: none;
  }

  &.message--formatted {
    visibility: visible;
  }

  /* La fila se enciende al pasar: dice donde estas y de paso da fondo a la
     barra de acciones que aparece a la derecha. */
  @media (hover: hover) {
    &:hover {
      background-color: var(--color-message-bg);
    }
  }

  &:has(.boost-item) {
    .message__boost-inline {
      display: inline-flex;
    }
  }

  /* Entre dos autores distintos, aire; dentro de la racha, nada. */
  + .message:not(.message--threaded) {
    margin-block-start: var(--message-space);
  }

  &.message--threaded {
    padding-block: 0.15rem;
  }

  &.message--failed {
    opacity: 0.5;

    .message__meta::after {
      content: "🚫";
      font-size: 1em;
      line-height: 1;
    }

    .message__body-content {
      animation: wiggle 0.4s both;
      outline: 1px dashed var(--color-negative);
      outline-offset: 0.3rem;
    }
  }
}

.message__day-separator {
  align-items: center;
  display: none;
  font-size: 0.75rem;
  font-weight: 700;
  grid-area: sep;
  grid-template-columns: 1fr auto 1fr;
  inline-size: 100%;
  margin-block: var(--block-space) var(--block-space-half);
  text-align: center;
  visibility: hidden;

  time,
  span {
    background-color: var(--color-bg);
    border: 1px solid var(--color-border-dark);
    border-radius: 3em;
    padding: 0.4em 1.2em;
  }

  &::after,
  &::before {
    border-top: 1px solid var(--color-border-dark);
    content: "";
  }

  .message--first-of-day & {
    display: grid;
    visibility: visible;
  }
}

.message__avatar {
  --avatar-border-size: 1px;
  --avatar-border-radius: 0.5rem;
  --avatar-size: var(--message-gutter);

  display: flex;
  grid-area: avatar;
  margin-block-start: 0.1rem;
  z-index: 2;
}

.message__meta {
  align-items: baseline;
  column-gap: 0.5rem;
  display: flex;
  justify-content: start;
  line-height: 1.4;
  margin: 0;
  min-inline-size: 0;

  /* En tactil la fila crece a 44 para que la hora, que es el enlace
     permanente del mensaje, tenga area de pulsacion. */
  @media (pointer: coarse) {
    min-block-size: 44px;
    align-items: center;
  }

  .message__room {
    display: none;
    visibility: hidden;
  }

  .message__heading {
    align-items: baseline;
    column-gap: 0.5rem;
    display: inline-flex;
    margin: 0;
    min-inline-size: 0;
  }
}

.message__author {
  font-size: 0.95rem;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.message__permalink {
  color: var(--color-text-subtle);
  font-size: 0.75rem;
  font-weight: 400;
  text-decoration: none;
  white-space: nowrap;

  &:hover {
    text-decoration: underline;
  }

  @media (pointer: coarse) {
    position: relative;

    &::after {
      block-size: 44px;
      content: "";
      inline-size: 44px;
      inset-block-start: 50%;
      inset-inline-start: 50%;
      position: absolute;
      translate: -50% -50%;
    }
  }
}

.message__body {
  display: block;
  grid-area: body;
  max-inline-size: 100%;
  min-inline-size: 0;
  position: relative;
}

.message__body-content {
  color: var(--message-color, var(--color-text));
  font-weight: 400;
  inline-size: auto;
  line-height: 1.46;
  max-inline-size: 100%;
  word-break: break-word;

  /* La edicion en sitio si se enmarca: es un formulario dentro de la lista y
     tiene que verse como tal. */
  &.message__body-content--editing {
    background-color: var(--color-message-bg);
    border-radius: 0.75em;
    padding: var(--block-space-half) var(--inline-space);
  }
}

/* La imagen de un mensaje: a la izquierda y con su proporcion, como en Slack.
 *
 * El marco trae el ancho y la proporcion originales en linea (ver
 * Messages::AttachmentPresentation); aqui solo se acota y se deja de centrar.
 * El `align-items` no sobra: sin el, el `display: flex` del marco estiraba la
 * imagen hasta el alto del marco mientras el ancho se topaba, y la dejaba
 * achatada. */
.message__attachment {
  block-size: auto;
  border: 1px solid var(--color-border-dark);
  border-radius: 0.5em;
  max-inline-size: 100%;
}

.message__attachment-frame {
  align-items: start;
  margin-block-start: 0.35rem;
  margin-inline: 0;
  max-inline-size: min(100%, 26rem);
}

.message__attachment-frame.flex > * {
  inline-size: 100%;
}

/* La imagen ocupa el ancho del marco y su alto sale de su propia proporcion.
   Atarla al alto del marco (100%) la deformaria en cuanto los metadatos no
   coincidieran con el fichero; la proporcion del marco esta para reservar el
   hueco mientras carga, no para recortar. */
.message__attachment-frame.flex .message__attachment {
  block-size: auto;
  inline-size: 100%;
}

img.message__attachment {
  cursor: zoom-in;
}

/* La barra de accesos rapidos: flota arriba a la derecha de la fila al pasar
   por encima, como en Slack. Reacciones de un clic, anadir otra, responder,
   copiar, marcar como no leido, editar y un "..." con el resto. */
.message__actions {
  inset: -1.1rem 0 auto auto;
  position: absolute;
  z-index: 3;
}

.message__toolbar {
  align-items: center;
  background-color: var(--color-bg);
  border: 1px solid var(--color-border-dark);
  border-radius: 0.6rem;
  box-shadow: 0 2px 8px oklch(var(--lch-always-black) / 0.14);
  display: flex;
  gap: 0.1rem;
  padding: 0.15rem;

  /* button_to y form_with envuelven el boton en un form: sin esto cada uno
     arrastraria su margen y la fila quedaria desigual. Va ANTES del bloque
     tactil de abajo a proposito: `> :not(details)` y `form` pesan lo mismo, y
     el plegado tiene que ganar por orden o los cuatro botones envueltos se
     quedarian pintados sobre cada mensaje. */
  form {
    display: contents;
    margin: 0;
  }

  /* Solo se ve al pasar o al tabular hasta ella. Con opacity y no
     display:none, para que el foco de teclado la revele. */
  opacity: 0;
  transition: opacity 120ms ease-in-out;

  .message:hover &,
  .message:focus-within & {
    opacity: 1;
  }

  /* Sin `hover` no hay forma de revelarla, y dejarla fija llenaba cada mensaje
     de iconos sueltos: ahi las acciones salen como hoja al mantener pulsado,
     que es lo que hace cualquier app del telefono. Ver
     message_sheet_controller y el final de esta hoja.

     La condicion es solo `hover: none` y no `(hover: none) and (pointer:
     coarse)`: un aparato que no casara ninguna de las dos -- pointer: none, o
     un tactil con trackpad -- se quedaba con la barra encendida sobre cada
     mensaje. */
  @media (hover: none) {
    display: none;
  }
}

.message__toolbar-sep {
  align-self: stretch;
  border-inline-start: 1px solid var(--color-border-dark);
  margin-block: 0.3rem;
  margin-inline: 0.15rem;
}

.message__action-btn {
  --btn-background: transparent;
  --btn-border-color: transparent;
  --btn-border-radius: 0.4rem;
  --btn-size: 1.9rem;
  --hover-size: 0;
  --outline-offset: 0;
  --width: 33%;

  flex-basis: var(--width);
  font-size: 0.8rem;

  @media (hover: hover) and (pointer: fine) {
    &:where(:not(:active):hover) {
      --btn-background: var(--color-message-bg);

      opacity: 1;
    }
  }

  &:where(:not(:active)):focus-visible {
    opacity: 1;
  }

  .message__toolbar > &,
  .message__toolbar > form > & {
    flex: none;
  }

  .boost-character {
    font-size: 1.05rem;
    line-height: 1;
  }
}

.message__edit-btn {
  display: none;

  .admin &,
  .message--me & {
    display: inline-flex;
  }
}

/* Mencionado: la fila entera se tine y lleva una banda al canto, como en
   Slack. Sin sacudida: la banda ya dice lo que hay que decir. */
.message--mentioned {
  background-color: oklch(var(--lch-orange) / 0.12);
  box-shadow: inset 3px 0 0 oklch(var(--lch-orange));

  @media (hover: hover) and (pointer: fine) {
    &:hover {
      background-color: oklch(var(--lch-orange) / 0.18);
    }
  }
}

/* La racha: el 2o y siguientes mensajes seguidos del mismo autor. Sin avatar
   ni nombre; la hora sale del flujo y se revela en el canal del avatar al
   pasar por encima. Con opacity y no display:none, para que el enlace siga
   siendo tabulable y el foco de teclado lo devuelva a la vista.

   Solo dentro de #message-area: en la busqueda el heading lleva ademas el
   nombre de la sala, que es el contexto del resultado. */
.message--threaded {
  .message__author,
  .message__avatar {
    display: none;
  }
}

#message-area .message--threaded {
  .message__heading {
    inline-size: var(--message-gutter);
    inset-block-start: 0.35em;
    inset-inline-end: calc(100% + var(--message-column-gap));
    justify-content: end;
    opacity: 0;
    overflow: hidden;
    position: absolute;
    transition: opacity 100ms ease;
  }

  .message__permalink {
    font-size: 0.65rem;
  }

  &:hover .message__heading,
  &:focus-within .message__heading {
    opacity: 1;
  }
}

.message__edit-btns div:only-of-type {
  margin-inline: auto;
}

.message--emoji:not(:has(.composer--edit)) {
  .message__body-content {
    .trix-content {
      font-size: 2.4em;
      line-height: 1.3;
    }
  }
}

/* El resultado de busqueda al que se llego: se enciende y se apaga. */
.message.search-highlight {
  animation: highlight-fade-out 1.5s 0.5s both;
  background-color: var(--color-selected);
}

/* Pending uploads */
.message__pending-upload {
  background-color: var(--color-message-bg);
  border-radius: 0.5em;
  margin-block-start: 0.35rem;
  overflow: hidden;
  padding: var(--block-space-half) var(--inline-space);
  position: relative;

  &::before {
    background-color: var(--color-border-dark);
    block-size: 100%;
    content: "";
    inline-size: 100%;
    inset-inline-start: var(--percentage);
    position: absolute;
    transform: translateX(-100%);
    z-index: 1;
  }

  > div {
    z-index: 2;
  }

  span {
    inline-size: 3rem;
    display: inline-block;
  }

  .composer__file-thumbnail {
    aspect-ratio: 1;
    background-size: contain;
    inline-size: 1.4em;
  }
}

/* La raya de "mensajes nuevos"
 *
 * Marca donde te quedaste al volver a una sala que marcaste como no leída. La
 * inserta unread_divider_controller: no puede venir del servidor porque los
 * mensajes se renderizan con cache compartida entre usuarios.
 */
.unread-divider {
  align-items: center;
  border-top: 1px solid var(--color-negative);
  display: flex;
  grid-column: 1 / -1;
  justify-content: end;
  margin-block: var(--block-space) var(--block-space-half);
  position: relative;
}

.unread-divider__label {
  background-color: var(--color-bg);
  color: var(--color-negative);
  font-size: 0.75rem;
  font-weight: 700;
  padding-inline: var(--inline-space-half);
  transform: translateY(-50%);
}

/* La hoja de acciones en tactil
 *
 * Es la MISMA barra de arriba, movida al borde inferior: no se clona nada, asi
 * que los formularios de reaccion y el boton de responder -- que cuelga del
 * controlador del mensaje -- siguen donde tienen que estar.
 *
 * Las reacciones van arriba en fila, como en Slack; el resto, en filas a lo
 * ancho con su nombre al lado. El nombre ya estaba en el marcado para los
 * lectores de pantalla: aqui simplemente se deja ver. */
.message-sheet-scrim {
  background-color: oklch(0% 0 0 / 0.45);
  inset: 0;
  position: fixed;
  z-index: 4;
}

body.has-message-sheet {
  overflow: hidden;
}

@media (hover: none) {
  /* El menu de copiar de iOS sale con la misma pulsacion larga y taparia la
     hoja. */
  .message__body-content {
    -webkit-touch-callout: none;
  }

  /* El mensaje sube por encima del velo, como el globo que se levanta en
     iMessage: sin esto la hoja se queda pintada debajo del composer. `.message`
     ya trae `z-index: 0`, o sea su propio contexto de apilamiento, asi que lo
     que hay dentro no puede subir por su cuenta. */
  .message--sheet {
    background-color: var(--color-bg);
    border-radius: 0.75rem;
    z-index: 6;
  }

  .message--sheet .message__actions {
    position: static;
  }

  .message--sheet .message__toolbar {
    background-color: var(--color-bg);
    border: 0;
    border-start-end-radius: 1rem;
    border-start-start-radius: 1rem;
    box-shadow: 0 -0.5rem 2rem oklch(0% 0 0 / 0.35);
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    inset: auto 0 0 0;
    padding: 0.7rem 0.75rem calc(0.7rem + var(--safe-bottom));
    position: fixed;
    z-index: 5;
  }

  /* El tirador, como el de cualquier hoja del sistema. */
  .message--sheet .message__toolbar::before {
    background-color: var(--color-border-darker);
    block-size: 0.25rem;
    border-radius: 1rem;
    content: "";
    flex-basis: 100%;
    inline-size: 2.5rem;
    margin: 0 auto 0.5rem;
  }

  /* Las reacciones: circulos grandes en la primera fila. */
  .message--sheet .message__quick-boost,
  .message--sheet .message__boost-btn {
    --btn-background: var(--color-message-bg);
    --btn-border-radius: 50%;
    --btn-size: 3.1rem;

    flex: 0 0 auto;
  }

  .message--sheet .message__quick-boost .boost-character {
    font-size: 1.6rem;
  }

  .message--sheet .message__toolbar-sep {
    border-block-start: 1px solid var(--color-border-dark);
    border-inline-start: 0;
    flex-basis: 100%;
    margin-block: 0.4rem;
    margin-inline: 0;
  }

  /* El resto, filas a lo ancho con su nombre. */
  .message--sheet .message__toolbar .btn:not(.message__quick-boost, .message__boost-btn) {
    --btn-padding: 0.6em 0.7em;

    aspect-ratio: auto;
    block-size: auto;
    display: flex;
    flex: 1 0 100%;
    font-size: 1rem;
    gap: 0.9rem;
    inline-size: auto;
    justify-content: start;
  }

  .message--sheet .message__toolbar .btn:not(.message__quick-boost, .message__boost-btn) > * {
    grid-area: auto;
  }

  .message--sheet .message__toolbar .btn:not(.message__quick-boost, .message__boost-btn) .for-screen-reader {
    block-size: auto;
    clip-path: none;
    inline-size: auto;
    overflow: visible;
    position: static;
    white-space: normal;
  }
}
