.directory-layout {
  grid-template-columns: 1fr 320px;
}

@media (max-width: 900px) {
  .directory-layout {
    grid-template-columns: 1fr;
  }
  .chat-sidebar {
    order: 2;
  }
}

/* --- Chat global: parte normal del documento (position:static) — scrollea
   junto con el resto de la página, no queda flotando pegado a la
   pantalla. Es una columna más del grid de .directory-layout, como
   .sidebar en el resto de las páginas del sitio. */
.chat-sidebar {
  align-self: start;
}

.chat-panel {
  display: flex;
  flex-direction: column;
  height: 620px;
  box-sizing: border-box;
}

.chat-panel h2 {
  flex-shrink: 0;
}

.chat-panel .section-hint {
  flex-shrink: 0;
}

.chat-messages {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--sp-1) var(--sp-1) var(--sp-1) 0;
  margin: var(--sp-3) 0;
}

.chat-message {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-1) var(--sp-1);
  margin: 0 calc(var(--sp-1) * -1);
  border-radius: var(--r-sm);
  transition: background 0.1s ease;
}

@media (hover: hover) and (pointer: fine) {
  .chat-message:hover {
    background: rgba(var(--surface-tint), 0.05);
  }
}

/* Barrita flotante estilo Discord (reaccionar/responder) — oculta por
   default, solo aparece con el cursor encima del mensaje. En touch no
   hay hover real para revelarla, así que ahí queda siempre visible. */
.chat-message__toolbar {
  position: absolute;
  top: -12px;
  right: 6px;
  display: flex;
  gap: 2px;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: var(--r-sm);
  padding: 2px;
  box-shadow: var(--sh-sm);
}

@media (hover: hover) and (pointer: fine) {
  .chat-message__toolbar {
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.1s ease;
  }
  .chat-message:hover .chat-message__toolbar {
    opacity: 1;
    pointer-events: auto;
  }
}

.chat-message__toolbar-btn {
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: none;
  border-radius: var(--r-xs);
  font-size: var(--fs-sm);
  line-height: 1;
  color: var(--text-dim);
  cursor: pointer;
}

.chat-message__toolbar-btn:hover {
  background: rgba(var(--surface-tint), 0.1);
  color: var(--text);
}

.chat-message__avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--void);
  border: 1px solid var(--panel-line);
}

.chat-message__avatar--fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--teal);
  color: var(--void);
  font-weight: 800;
  font-size: var(--fs-caption);
}

.chat-message__body {
  min-width: 0;
  flex: 1;
}

.chat-message__meta {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
}

.chat-message__name {
  color: var(--gold-bright);
  font-weight: 700;
  font-size: var(--fs-sm);
}

.chat-message__time {
  color: var(--text-dim);
  font-size: var(--fs-micro);
}

.chat-message__text {
  font-size: var(--fs-sm);
  color: var(--text);
  word-break: break-word;
  white-space: pre-wrap;
}

.chat-message--deleted {
  opacity: 0.65;
}

.chat-message__text--deleted {
  font-style: italic;
  color: var(--text-dim);
}

.chat-message__reply-quote {
  font-size: var(--fs-micro);
  color: var(--text-dim);
  border-left: 2px solid var(--panel-line);
  padding-left: var(--sp-2);
  margin-bottom: var(--sp-1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-message__reactions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  margin-top: var(--sp-1);
}

.chat-message__reaction {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  border: 1px solid var(--panel-line);
  background: rgba(var(--surface-tint), 0.06);
  border-radius: var(--r-pill);
  padding: 1px var(--sp-2);
  font-size: var(--fs-micro);
  color: var(--text-dim);
  cursor: pointer;
}

.chat-message__reaction.is-mine {
  border-color: var(--teal);
  color: var(--text);
}

/* --- Panel de emojis (compartido: componer mensaje y reaccionar) --- */
.chat-form__emoji-btn {
  font-size: var(--fs-md);
  padding: var(--sp-2) var(--sp-3);
}

.chat-emoji-panel {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  width: 220px;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--sp-1);
  background: var(--panel);
  border: 0;
  border-radius: var(--r-md);
  padding: var(--sp-2);
  box-shadow: var(--sh-lg), var(--sh-hairline);
  z-index: 20;
  transform-origin: bottom left;
  transition: opacity 160ms var(--ease-out), transform 160ms var(--ease-out), visibility 160ms;
}

/* [hidden] ya NO cae a display:none (a propósito, ver comentario abajo en
   .chat-gif-panel[hidden] — mismo criterio en los dos paneles) para poder
   animar el cierre en vez de que desaparezca de golpe. */
.chat-emoji-panel[hidden] {
  display: grid;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: scale(0.92) translateY(4px);
}

@media (prefers-reduced-motion: reduce) {
  .chat-emoji-panel { transition: opacity 120ms ease; }
  .chat-emoji-panel[hidden] { transform: none; }
}

.chat-emoji-panel--inline {
  position: static;
  width: auto;
  margin-top: var(--sp-1);
}

.chat-emoji-panel__btn {
  border: none;
  background: none;
  font-size: var(--fs-md);
  padding: var(--sp-1);
  border-radius: var(--r-xs);
  cursor: pointer;
}

.chat-emoji-panel__btn:hover {
  background: rgba(var(--surface-tint), 0.1);
}

/* --- Preview de "respondiendo a" arriba del input --- */
.chat-reply-preview {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  background: rgba(var(--surface-tint), 0.06);
  border: 1px solid var(--panel-line);
  border-left: 2px solid var(--teal);
  border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-3);
  margin-bottom: var(--sp-2);
  flex-shrink: 0;
}

.chat-reply-preview[hidden] {
  display: none;
}

.chat-reply-preview__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: 1px;
}

.chat-reply-preview__label {
  font-size: var(--fs-micro);
  color: var(--text-dim);
}

.chat-reply-preview__label strong {
  color: var(--gold-bright);
}

.chat-reply-preview__text {
  font-size: var(--fs-caption);
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-reply-preview__cancel {
  flex-shrink: 0;
  border: none;
  background: none;
  color: var(--text-dim);
  font-size: var(--fs-md);
  cursor: pointer;
  padding: 0 var(--sp-1);
}

.chat-reply-preview__cancel:hover {
  color: var(--danger);
}

.chat-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  flex-shrink: 0;
}

.chat-form__gif-wrap {
  position: relative;
  flex-shrink: 0;
}

.chat-form__gif-btn {
  font-weight: 800;
  font-size: var(--fs-caption);
  padding: var(--sp-2) var(--sp-3);
}

.chat-gif-panel {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  width: 260px;
  max-height: 300px;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: var(--r-md);
  padding: var(--sp-3);
  box-shadow: var(--sh-lg);
  z-index: 20;
  transform-origin: bottom left;
  transition: opacity 160ms var(--ease-out), transform 160ms var(--ease-out), visibility 160ms;
}

/* [hidden] ya NO cae a display:none — así el cierre se puede animar
   (opacity+scale) en vez de cortar de golpe. El panel es position:absolute,
   así que dejarlo con display real incluso "cerrado" no mueve nada del
   layout de alrededor. */
.chat-gif-panel[hidden] {
  display: flex;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: scale(0.92) translateY(4px);
}

@media (prefers-reduced-motion: reduce) {
  .chat-gif-panel { transition: opacity 120ms ease; }
  .chat-gif-panel[hidden] { transform: none; }
}

.chat-gif-panel__search {
  flex-shrink: 0;
  background: var(--void);
  border: 1px solid var(--panel-line);
  border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-3);
  color: var(--text);
  font-family: "Barlow", sans-serif;
  font-size: var(--fs-sm);
}

.chat-gif-panel__search:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 1px;
}

.chat-gif-results {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-2);
  margin-top: var(--sp-2);
  overflow-y: auto;
}

.chat-gif-results img {
  width: 100%;
  height: 80px;
  object-fit: cover;
  border-radius: var(--r-xs);
  cursor: pointer;
  transition: transform 0.1s var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .chat-gif-results img:hover {
    transform: scale(1.04);
  }
}

.chat-gif-results__status {
  grid-column: 1 / -1;
  padding: var(--sp-3) 0;
}

.chat-form button[type="submit"] {
  flex: 1;
  justify-content: center;
}

.chat-message__gif {
  display: block;
  max-width: 100%;
  max-height: 160px;
  border-radius: var(--r-sm);
  margin-top: var(--sp-1);
}

/* Mismo bug de especificidad de siempre: sin esto, [hidden] pierde
   contra el display:flex de arriba y el form queda visible aunque no
   haya sesión iniciada. */
.chat-form[hidden] {
  display: none;
}

.chat-form__input {
  flex: 1 1 100%;
  min-width: 0;
  background: var(--void);
  border: 1px solid var(--panel-line);
  border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-3);
  color: var(--text);
  font-family: "Barlow", sans-serif;
  font-size: var(--fs-sm);
}

.chat-form__input:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 1px;
}

.chat-login-hint {
  margin: var(--sp-1) 0 0;
}

.chat-login-hint a {
  color: var(--teal);
}

.chat-error {
  margin: var(--sp-2) 0 0;
  color: var(--danger);
  font-size: var(--fs-sm);
}

.directory-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--sp-4);
}

/* Mismo bug de especificidad que create-lobby-form: sin esto, [hidden]
   pierde contra el display:grid de arriba y la grilla vacía se ve un
   instante antes de que JS la llene. */
.directory-grid[hidden] {
  display: none;
}

.lobby-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-5);
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: var(--r-lg);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease, transform 0.15s var(--ease-out), box-shadow 0.15s ease;
  opacity: 0;
  animation: row-enter 320ms var(--ease-out) both;
  animation-delay: calc(var(--stagger-index, 0) * 40ms);
}

@media (prefers-reduced-motion: reduce) {
  .lobby-card { animation: none; opacity: 1; }
}

@media (hover: hover) and (pointer: fine) {
  .lobby-card:hover {
    border-color: var(--teal);
    transform: translateY(-2px);
    box-shadow: var(--sh-lg);
  }
}

.lobby-card:active {
  transform: scale(0.98);
}

.lobby-card__header {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}

.lobby-card__icon {
  flex-shrink: 0;
  display: block;
  width: 36px;
  height: 36px;
}

.lobby-card__icon-img {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--void);
  border: 1px solid var(--panel-line);
}

.lobby-card__icon-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  color: var(--void);
  font-family: "Barlow", sans-serif;
  font-weight: 800;
  font-size: var(--fs-md);
}

.lobby-card__name {
  font-size: var(--fs-lg);
  color: var(--gold-bright);
  margin: 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Oculto a propósito, mismo criterio que .last-updated en style.css —
   se retoma más adelante. */
.lobby-card__updated {
  display: none;
}

.lobby-card__meta {
  display: flex;
  justify-content: space-between;
  font-size: var(--fs-caption);
  color: var(--text-dim);
  /* Empuja esto siempre al fondo de la tarjeta, sin importar cuántos
     jugadores se muestren arriba (0 a 3) — las tarjetas ya quedan de
     igual alto entre sí (grid stretch por default), así que esto alinea
     el texto en la misma posición Y en toda la fila. */
  margin-top: auto;
  padding-top: var(--sp-2);
}

/* --- Skeleton de carga: mismo tamaño/forma que .lobby-card real (misma
   grilla .directory-grid), para que no haya un salto de layout cuando el
   contenido real la reemplaza. Reemplaza al viejo "Cargando lobbys…" de
   texto plano — se siente más premium y deja ver de entrada la forma que
   va a tener el contenido. */
.lobby-card-skeleton {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-5);
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: var(--r-lg);
}

.lobby-card-skeleton__header {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}

.skeleton-block {
  display: block;
  border-radius: var(--r-xs);
  background: linear-gradient(
    100deg,
    rgba(var(--surface-tint), 0.08) 30%,
    rgba(var(--surface-tint), 0.18) 50%,
    rgba(var(--surface-tint), 0.08) 70%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.6s ease-in-out infinite;
}

.skeleton-block--circle {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
}

.skeleton-block--name {
  width: 60%;
  height: 20px;
}

.skeleton-block--row {
  width: 100%;
  height: 28px;
  border-radius: var(--r-sm);
}

.skeleton-block--meta {
  width: 45%;
  height: 14px;
  margin-top: var(--sp-1);
}

@keyframes skeleton-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .skeleton-block { animation: none; }
}

.lobby-card__top-players {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

/* Grid de 2 columnas (ícono, texto) x 2 filas (nombre, rango) — así el
   ícono de invocador y el de rango arrancan en la misma columna (se
   "alinean" entre sí) y el nick y el texto de rango también, aunque los
   dos íconos midan distinto. Los hijos se acomodan solos en orden de
   documento: medalla+ícono+nombre ocupan la fila 1, spacer+ícono+rango
   la fila 2 (grid-auto-flow: row, 3 por fila). */
.lobby-card__top-player {
  display: grid;
  grid-template-columns: 18px 26px 1fr;
  align-items: center;
  column-gap: var(--sp-2);
  row-gap: 2px;
  font-size: var(--fs-caption);
  padding-bottom: 2px;
}

.lobby-card__top-player-medal-spacer {
  width: 18px;
}

.lobby-card__top-player .rank-icon--summoner,
.lobby-card__top-player .rank-icon-wrap {
  justify-self: start;
}

.lobby-card__top-player-medal {
  font-size: var(--fs-caption);
  width: 18px;
  flex-shrink: 0;
  text-align: center;
}

.lobby-card__top-player-name {
  color: var(--gold-bright);
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.lobby-card__top-player-rank {
  color: var(--text-dim);
  font-size: var(--fs-micro);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Íconos compartidos: de invocador (circular) y de rango (emblema) --- */
.rank-icon--summoner {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--void);
  border: 1px solid var(--panel-line);
}

.rank-icon--empty {
  display: inline-block;
}

/* Cajita con overflow:hidden + zoom con transform:scale en el <img> de
   adentro: el PNG de CommunityDragon trae mucho aire transparente, y
   márgenes negativos "a ojo" para compensarlo (lo que había antes)
   dejaban el glifo visible desalineado del ícono de invocador de al
   lado — con esta cajita, el BORDE de la cajita es el borde visual real
   del ícono, así que alinea perfecto con justify-self/align-items como
   cualquier otro elemento normal. */
.rank-icon-wrap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  overflow: hidden;
  flex-shrink: 0;
}

.rank-icon-wrap .rank-icon--tier {
  width: 100%;
  height: 100%;
  object-fit: contain;
  transform: scale(1.7);
}

.global-rank-row__meta .rank-icon-wrap {
  width: 52px;
  height: 52px;
  vertical-align: middle;
}

/* --- Rankings globales (arriba del directorio) --- */
.global-leaderboards-title {
  text-align: center;
  font-size: clamp(22px, 3vw, 30px);
  margin: 0 0 var(--sp-4);
}

.global-leaderboards-title[hidden] {
  display: none;
}

.global-leaderboards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-5);
  margin-bottom: var(--sp-8);
}

/* Grid ya estira ambos .panel a la misma altura (el más alto, "Mejores
   jugadores", marca el piso) — con esto el panel pasa a columna flex, y
   el footnote se ancla siempre abajo del todo con margin-top:auto, sin
   importar cuántos lobbys/jugadores tenga la lista arriba. */
.global-leaderboards .panel {
  display: flex;
  flex-direction: column;
}

.global-leaderboards__footnote {
  margin-top: auto;
  padding-top: var(--sp-3);
  font-size: var(--fs-micro);
  color: var(--text-dim);
  line-height: var(--lh-snug);
}

.global-leaderboards[hidden] {
  display: none;
}

.directory-grid-title {
  font-size: clamp(20px, 2.6vw, 26px);
  margin: 0;
}

@media (max-width: 800px) {
  .global-leaderboards {
    grid-template-columns: 1fr;
  }
}

.global-rank-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.global-rank-row {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  align-items: center;
  gap: var(--sp-3);
  padding: 0 var(--sp-3);
  border-radius: var(--r-md);
  background: rgba(var(--surface-tint), 0.06);
  border: 1px solid var(--panel-line);
}

/* Ancho FIJO para el nombre (no 1fr): cada <li> es su propio grid
   independiente (no hay una sola grilla compartiendo columnas entre
   filas), así que con 1fr el ancho de esta columna se recalculaba en
   cada fila según cuánto ocupara el meta AL LADO en esa fila puntual —
   con nombres/textos de largo distinto, el meta terminaba arrancando en
   una X distinta por fila. Con un ancho fijo acá, el meta (1fr, se lleva
   lo que sobra) arranca siempre en el mismo punto en todas las filas. */
.global-rank-row--player {
  grid-template-columns: 24px 28px 180px 1fr;
}

.global-rank-row--player .rank-icon--summoner {
  width: 28px;
  height: 28px;
}

/* En pantallas angostas, la columna del nombre (1fr) tiene min-width
   efectivo 0 (el navegador lo permite porque tiene overflow:hidden) —
   con poco espacio se aplasta a casi nada para dejarle lugar al texto
   del meta (que no puede achicarse, tiene white-space:nowrap), y el
   resultado es que el meta queda "flotando" descentrado en vez de
   arrancar del borde real de la fila. Solución: en mobile, el meta pasa
   a ocupar su propia línea completa abajo, alineado a la izquierda de
   verdad, sin competir por espacio con la medalla/ícono/nombre de arriba. */
@media (max-width: 560px) {
  .global-rank-row--player {
    grid-template-columns: 24px 28px 1fr;
    grid-template-areas:
      "pos icon name"
      "meta meta meta";
    row-gap: var(--sp-1);
    padding: var(--sp-2) var(--sp-3);
  }

  .global-rank-row--player .global-rank-row__position {
    grid-area: pos;
  }

  .global-rank-row--player .rank-icon--summoner {
    grid-area: icon;
  }

  .global-rank-row--player .global-rank-row__main {
    grid-area: name;
  }

  .global-rank-row--player .global-rank-row__meta {
    grid-area: meta;
    justify-content: flex-start;
  }
}

.global-rank-row__position {
  font-family: "Rajdhani", "Barlow", sans-serif;
  font-weight: 800;
  font-size: var(--fs-md);
  text-align: center;
}

.global-rank-row__main {
  color: var(--gold-bright);
  font-weight: 700;
  font-size: var(--fs-sm);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.global-rank-row__main:hover {
  text-decoration: underline;
}

.global-rank-row__meta {
  display: flex;
  align-items: center;
  /* space-between: el texto arranca pegado a la izquierda de esta
     columna (misma X en las 5 filas, gracias al ancho fijo de la
     columna del nombre) y el ícono de rango queda siempre pegado al
     borde derecho de la fila (también misma X en las 5 filas) — los dos
     extremos alineados, cada uno a su lado. */
  justify-content: space-between;
  font-size: var(--fs-micro);
  color: var(--text-dim);
  white-space: nowrap;
}
