/* ==========================================================================
   SnippetLab — community chatroom

   Built on the app's existing design system: near-black surfaces defined by
   1px borders, depth from background steps rather than shadows, radii bimodal
   (a pill or a card, nothing between), colour only in small details.

   The bubble and composer shapes follow the IzzXd Code reference the owner
   sent over: a soft rounded bubble with a small square-ish avatar, a pill
   composer with inline action buttons, and tiny uppercase letterspaced labels
   for anything that is a heading rather than content.
   ========================================================================== */


/* ------------------------------------------------------------------ shell

   The dialog is a flex column: header and composer pinned, the message list
   taking the space between. Height is a fixed fraction of the viewport so the
   modal does not resize as messages arrive.
   ------------------------------------------------------------------ */

/* Above every other dialog: the chatroom can be opened from inside the
   snippet detail view, and it must not render underneath it. */
.chatroom-modal{z-index:70}

.chatroom-dialog{
  display:flex;
  flex-direction:column;
  width:min(680px,100%);
  height:min(78vh,660px);
  max-height:78dvh;
  padding:0;
  overflow:hidden;
}

/* The dialog head keeps the app's default padding but loses the bottom rule,
   because the status strip below it draws its own. */
.chatroom-dialog .dialog-head{
  padding:16px 18px;
  border-bottom:1px solid var(--border-subtle);
  flex-shrink:0;
}

.chatroom-dialog .dialog-head h3{font-size:15px}
.chatroom-dialog .dialog-head p{font-size:11px;color:var(--text-faint)}


/* ------------------------------------------------------------------ status

   One thin strip under the header: a live dot and the connection state. It is
   deliberately quiet — it is not content, and it should not compete with the
   messages for attention.
   ------------------------------------------------------------------ */

.chatroom-status{
  display:flex;
  align-items:center;
  gap:7px;
  padding:7px 18px;
  font-size:10.5px;
  color:var(--text-dim);
  border-bottom:1px solid var(--border-subtle);
  background:var(--code-bg);
  flex-shrink:0;
}

.chat-live-dot{
  width:5px;
  height:5px;
  border-radius:50%;
  background:var(--green);
  flex-shrink:0;
  box-shadow:0 0 0 2px rgba(34,197,94,.14);
}

@keyframes chat-pulse{
  0%,100%{opacity:1}
  50%{opacity:.35}
}
.chat-live-dot{animation:chat-pulse 2.4s ease-in-out infinite}

/* A failed or reconnecting state recolours the dot rather than adding a
   separate error icon — one signal, not two. */
.chatroom-status.is-error{color:var(--red)}
.chatroom-status.is-error .chat-live-dot{
  background:var(--red);
  box-shadow:0 0 0 2px rgba(239,68,68,.14);
  animation:none;
}


/* ---------------------------------------------------------------- messages

   A scrollable column. Bubbles are capped at 82% so the eye can always tell
   an incoming message from an outgoing one by which side it sits on.
   ------------------------------------------------------------------ */

.chat-messages{
  flex:1;
  min-height:0;
  overflow-y:auto;
  overscroll-behavior:contain;
  padding:16px 18px;
  display:flex;
  flex-direction:column;
  gap:10px;
  scrollbar-width:thin;
  scrollbar-color:var(--border-hover) transparent;
}

.chat-messages::-webkit-scrollbar{width:8px}
.chat-messages::-webkit-scrollbar-thumb{
  background:var(--border);
  border-radius:var(--r-pill);
}
.chat-messages::-webkit-scrollbar-thumb:hover{background:var(--border-hover)}
.chat-messages::-webkit-scrollbar-track{background:transparent}

/* Empty state — shown by the client when there is nothing to render, so a
   brand new room does not read as a broken one. */
.chat-empty{
  margin:auto;
  text-align:center;
  color:var(--text-dim);
  font-size:11.5px;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:8px;
}
.chat-empty .icon{width:22px;height:22px;color:var(--text-dim)}


/* ----------------------------------------------------------------- bubble */

.chat-message{
  display:flex;
  gap:9px;
  align-items:flex-end;
  max-width:82%;
  animation:chat-in .18s ease both;
}

@keyframes chat-in{
  from{opacity:0;transform:translateY(4px)}
  to{opacity:1;transform:none}
}

.chat-message.is-mine{
  align-self:flex-end;
  flex-direction:row-reverse;
}

/* Quoted-reply jump target flashes once so the eye finds it. */
@keyframes chat-flash{
  0%,100%{background:transparent}
  30%{background:rgba(250,250,250,.06)}
}
.chat-message.is-flash .chat-message-main{animation:chat-flash 1.1s ease}

.chat-avatar{
  flex-shrink:0;
  width:26px;
  height:26px;
  border-radius:9px;
  background:var(--chip-2);
  border:1px solid var(--border);
  color:var(--text-muted);
  display:flex;
  align-items:center;
  justify-content:center;
  font:600 10.5px/1 var(--font-sans);
  overflow:hidden;
  user-select:none;
}

.chat-avatar img{width:100%;height:100%;object-fit:cover}

.chat-message-main{
  position:relative;
  min-width:0;
  background:var(--surface-2);
  border:1px solid var(--border);
  border-radius:14px 14px 14px 4px;
  padding:8px 11px;
}

.chat-message.is-mine .chat-message-main{
  background:var(--chip-2);
  border-color:var(--border-hover);
  border-radius:14px 14px 4px 14px;
}

.chat-message.is-deleted .chat-message-main{
  background:transparent;
  border-style:dashed;
}

/* meta line */
.chat-message-meta{
  display:flex;
  align-items:baseline;
  gap:6px;
  margin-bottom:3px;
}

.chat-message-meta strong{
  font:600 11px/1.3 var(--font-sans);
  color:var(--text);
}

.chat-message.is-mine .chat-message-meta strong{color:var(--text-muted)}

.chat-message-meta time{
  font-size:9.5px;
  color:var(--text-dim);
  font-variant-numeric:tabular-nums;
}

.chat-edited{
  font-size:9px;
  color:var(--text-dim);
  font-style:italic;
}

.chat-message-main p{
  font-size:12.5px;
  line-height:1.55;
  color:var(--text-muted);
  word-break:break-word;
  white-space:pre-wrap;
}

.chat-message.is-mine .chat-message-main p{color:var(--text)}

.chat-tombstone{
  font-size:11px !important;
  color:var(--text-dim) !important;
  font-style:italic;
}


/* ------------------------------------------------------------ reply quote */

.chat-quote{
  display:block;
  width:100%;
  text-align:left;
  background:var(--code-bg);
  border:0;
  border-left:2px solid var(--border-hover);
  border-radius:0 6px 6px 0;
  padding:5px 8px;
  margin-bottom:6px;
  cursor:pointer;
  transition:background var(--ease);
}

.chat-quote:hover{background:var(--chip)}

.chat-quote strong{
  display:block;
  font:600 9px/1.4 var(--font-sans);
  text-transform:uppercase;
  letter-spacing:.06em;
  color:var(--text-faint);
  margin-bottom:1px;
}

.chat-quote span{
  display:block;
  font-size:10.5px;
  color:var(--text-dim);
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}

.chat-message.is-mine .chat-quote{border-left-color:var(--text-faint)}


/* ------------------------------------------------------------ reply banner */

.chat-reply-bar{
  display:flex;
  align-items:center;
  gap:8px;
  padding:8px 18px;
  background:var(--chip);
  border-top:1px solid var(--border);
  flex-shrink:0;
}

.chat-reply-bar.hidden{display:none}

.chat-reply-text{
  flex:1;
  min-width:0;
  display:flex;
  flex-direction:column;
  gap:1px;
  border-left:2px solid var(--text-faint);
  padding-left:8px;
}

.chat-reply-text strong{
  font:600 9px/1.4 var(--font-sans);
  text-transform:uppercase;
  letter-spacing:.06em;
  color:var(--text-faint);
}

.chat-reply-text span{
  font-size:11px;
  color:var(--text-muted);
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}

#chatCancelReply{
  flex-shrink:0;
  width:22px;
  height:22px;
  border-radius:var(--r-sm);
  color:var(--text-faint);
  display:flex;
  align-items:center;
  justify-content:center;
  font-size:13px;
  transition:background var(--ease),color var(--ease);
}

#chatCancelReply:hover{background:var(--surface-3);color:var(--text)}


/* --------------------------------------------------------------- reactions */

.chat-reactions{
  display:flex;
  flex-wrap:wrap;
  gap:3px;
  margin-top:5px;
}

.chat-reaction{
  display:inline-flex;
  align-items:center;
  gap:3px;
  padding:2px 7px;
  border:1px solid var(--border);
  border-radius:var(--r-pill);
  background:var(--code-bg);
  font-size:10.5px;
  line-height:1.5;
  color:var(--text-muted);
  cursor:pointer;
  transition:border-color var(--ease),background var(--ease);
}

.chat-reaction:hover{border-color:var(--border-hover);background:var(--chip)}

/* Yours reads as selected through the border, keeping the palette compressed
   rather than introducing a fill colour for state. */
.chat-reaction.is-mine{
  border-color:var(--text-faint);
  color:var(--text);
  background:var(--chip-2);
}

.chat-reaction-picker{
  position:fixed;
  z-index:1200;
  display:flex;
  flex-wrap:wrap;
  gap:2px;
  width:max-content;
  max-width:232px;
  padding:6px;
  background:var(--surface-3);
  border:1px solid var(--border);
  border-radius:var(--r-panel);
  box-shadow:var(--shadow-pop);
}

.chat-reaction-picker button{
  width:30px;
  height:30px;
  border-radius:var(--r-sm);
  font-size:16px;
  line-height:1;
  display:flex;
  align-items:center;
  justify-content:center;
  transition:background var(--ease);
}

.chat-reaction-picker button:hover{background:var(--chip-2)}


/* ----------------------------------------------------------- message tools

   Reply / React / Delete. Revealed on hover on a pointer device, and always
   visible on touch, where there is no hover to reveal them with.
   ------------------------------------------------------------------ */

.chat-actions{
  display:flex;
  gap:3px;
  margin-top:5px;
  opacity:0;
  transition:opacity var(--ease);
}

.chat-message:hover .chat-actions,
.chat-message:focus-within .chat-actions{opacity:1}

@media (hover:none){
  .chat-actions{opacity:1}
}

.chat-act{
  padding:2px 7px;
  border:1px solid transparent;
  border-radius:var(--r-sm);
  font-size:9.5px;
  font-weight:500;
  letter-spacing:.02em;
  color:var(--text-dim);
  transition:background var(--ease),color var(--ease),border-color var(--ease);
}

.chat-act:hover{
  background:var(--chip-2);
  border-color:var(--border);
  color:var(--text);
}

.chat-act-danger:hover{
  border-color:rgba(239,68,68,.35);
  color:var(--red);
  background:rgba(239,68,68,.08);
}


/* -------------------------------------------------------------- voice note */

.chat-voice{
  display:flex;
  align-items:center;
  gap:8px;
  min-width:190px;
  padding:2px 0;
}

.chat-voice audio{
  flex:1;
  height:30px;
  min-width:0;
  /* The native control ships light on some platforms; the filter pulls it
     toward the dark palette without repainting the whole element. */
  filter:invert(.92) hue-rotate(180deg) saturate(.6);
}

.chat-voice-len{
  font-size:9.5px;
  color:var(--text-dim);
  font-variant-numeric:tabular-nums;
  flex-shrink:0;
}

.chat-image{
  display:block;
  max-width:100%;
  max-height:220px;
  border-radius:var(--r-sm);
  border:1px solid var(--border);
  transition:border-color var(--ease);
}

a:hover > .chat-image{border-color:var(--border-hover)}


/* ---------------------------------------------------------------- composer */

.chat-form{
  display:flex;
  flex-direction:column;
  gap:8px;
  padding:12px 18px;
  border-top:1px solid var(--border);
  flex-shrink:0;
}

.chat-form.hidden{display:none}

.chat-form .textarea{
  min-height:0;
  height:40px;
  max-height:120px;
  padding:10px 12px;
  font-family:var(--font-sans);
  font-size:12.5px;
  line-height:1.4;
  border-radius:var(--r-input);
  resize:none;
  overflow-y:auto;
}

.chat-form-actions{
  display:flex;
  align-items:center;
  gap:6px;
}

/* Record button — a square icon button matching the composer's height. */
.chat-voice-btn{
  flex-shrink:0;
  width:34px;
  height:34px;
  border:1px solid var(--border-input);
  border-radius:var(--r-sm);
  background:var(--chip);
  color:var(--text-faint);
  display:flex;
  align-items:center;
  justify-content:center;
  transition:background var(--ease),color var(--ease),border-color var(--ease);
}

.chat-voice-btn .icon{width:15px;height:15px}
.chat-voice-btn:hover{
  background:var(--chip-2);
  border-color:var(--border-hover);
  color:var(--text);
}

.chat-voice-btn.is-recording{
  background:var(--red);
  border-color:var(--red);
  color:#fff;
  animation:chat-pulse 1.2s ease-in-out infinite;
}

.chat-rec-time{
  font-size:10.5px;
  color:var(--red);
  font-variant-numeric:tabular-nums;
  flex-shrink:0;
}

.chat-rec-time.hidden{display:none}

.chat-send{
  margin-left:auto;
  flex-shrink:0;
}

.chat-send:disabled{opacity:.5;cursor:not-allowed}


/* ------------------------------------------------------------- sign-in gate */

.chat-signin{
  flex:1;
  min-height:0;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:9px;
  padding:32px 24px;
  text-align:center;
}

.chat-signin.hidden{display:none}

.chat-signin .icon{
  width:24px;
  height:24px;
  color:var(--text-dim);
}

.chat-signin strong{
  font:600 13.5px/1.3 var(--font-sans);
  color:var(--text);
}

.chat-signin p{
  font-size:11.5px;
  color:var(--text-faint);
  max-width:280px;
  line-height:1.6;
}

.chat-signin .btn{margin-top:4px}


/* ------------------------------------------------------------------- note */

.chatroom-note{
  padding:0 18px 12px;
  font-size:10px;
  color:var(--text-dim);
  text-align:center;
  flex-shrink:0;
}


/* -------------------------------------------------------------- responsive

   Below 560px the chatroom takes the whole viewport. A 78vh modal with a
   keyboard open leaves almost no room for messages, which is the point at
   which a phone chat stops being usable.
   ------------------------------------------------------------------ */

@media (max-width:560px){
  .chatroom-dialog{
    width:100%;
    height:100dvh;
    max-height:100dvh;
    border-radius:0;
    border:0;
  }

  .chatroom-dialog .dialog-head{padding:14px 16px}
  .chat-messages{padding:14px 16px}
  .chat-message{max-width:88%}
  .chat-form{padding:10px 16px}
  .chat-reply-bar{padding:8px 16px}
  .chat-signin{padding:24px 20px}
}


/* ------------------------------------------------------------- guest sizing

   A signed-out visitor has one paragraph and one button. A dialog sized for a
   conversation is mostly empty at that point, which reads as a page that
   failed to load rather than a gate. Collapse to the content; the full height
   comes back the moment there is a list to fill.
   ------------------------------------------------------------------------ */

.chatroom-dialog.is-guest{
  height:auto;
  max-height:min(70vh,520px);
}

.chatroom-dialog.is-guest .chat-signin{
  flex:0 0 auto;
  padding:28px 24px;
}


/* ------------------------------------------------------------- avatars

   A real picture when the member has one, their initial when they do not.
   Both states are the same size and shape so a row of messages does not
   jitter depending on who has uploaded what.
   ---------------------------------------------------------------------- */

.chat-avatar{
  padding:0;
  border:1px solid var(--border);
  background:var(--chip-2);
  color:var(--text-muted);
  font:600 10.5px/1 var(--font-sans);
}

.chat-avatar img{
  width:100%;
  height:100%;
  object-fit:cover;
  border-radius:inherit;
  display:block;
}

/* Clickable avatar and name. The affordance is a subtle border lift on hover
   rather than an underline, which at 11px reads as a link inside a sentence. */
.chat-avatar.is-link{
  cursor:pointer;
  transition:border-color var(--ease),transform var(--ease);
}

.chat-avatar.is-link:hover{
  border-color:var(--border-hover);
  transform:translateY(-1px);
}

.chat-avatar.is-link:active{transform:none}

.chat-author.is-link{
  cursor:pointer;
  padding:0;
  border:0;
  background:none;
  font:600 11px/1.3 var(--font-sans);
  color:var(--text);
  text-align:left;
  transition:color var(--ease);
}

.chat-author.is-link:hover{
  color:var(--text);
  text-decoration:underline;
  text-underline-offset:2px;
}

.chat-message.is-mine .chat-author.is-link{color:var(--text-muted)}
