/* ============================================================================
   STARFALL TERMINAL — term-chat.css
   ----------------------------------------------------------------------------
   The community room: a launcher pill in the bottom-right corner and a glass
   panel whose feed, online count and back log all come from js/desk-core.js.
   The composer is a lock — posting is member-only — and the small print says
   so plainly. Motion respects prefers-reduced-motion.

   Layering note: .toasts already lives bottom-right, so the toast stack is
   nudged above the launcher here.
   ========================================================================== */

.toasts { bottom: 84px; }

.chat {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 135;
  font-family: var(--ui);
}

/* --- launcher --------------------------------------------------------- */
.chat__fab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 46px;
  padding: 0 16px 0 14px;
  border-radius: 999px;
  border: 1px solid var(--line-gold);
  background: linear-gradient(180deg, rgba(18, 24, 38, 0.94), rgba(8, 11, 19, 0.96));
  box-shadow: var(--shadow-1), 0 0 40px -22px rgba(var(--accent-rgb), 0.9);
  cursor: pointer;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s;
}
.chat__fab:hover {
  transform: translateY(-2px);
  border-color: rgba(var(--accent-rgb), 0.6);
  box-shadow: var(--shadow-2), 0 0 54px -20px rgba(var(--accent-rgb), 0.9);
}
.chat__fab i {
  position: relative;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  flex: none;
}
.chat__fab i::after {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1px solid rgba(var(--accent-rgb), 0.5);
  animation: animPingChat 2.6s var(--ease) infinite;
}
@keyframes animPingChat {
  0%   { transform: scale(0.8); opacity: 0.9; }
  80%  { transform: scale(1.5); opacity: 0; }
  100% { opacity: 0; }
}
.chat__fab b {
  font: 700 12px/1 var(--mono);
  letter-spacing: 0.1em;
  color: var(--ink);
}
.chat__fab span {
  font: 700 11px/1 var(--mono);
  color: var(--up);
}
.chat__fab em {
  font: 800 10px/1 var(--mono);
  font-style: normal;
  padding: 3px 6px;
  border-radius: 999px;
  background: var(--accent);
  color: #0a0d14;
  transform: scale(0);
  transition: transform 0.25s var(--ease);
}
.chat__fab em.is-on { transform: scale(1); }

/* --- panel ------------------------------------------------------------ */
.chat__panel {
  position: absolute;
  right: 0;
  bottom: 60px;
  width: 380px;
  max-width: calc(100vw - 40px);
  height: 560px;
  max-height: calc(100dvh - 140px);
  display: grid;
  /* head · stats · who-is-online · feed · typing · composer · footer */
  grid-template-rows: auto auto auto minmax(0, 1fr) auto auto auto;
  border-radius: var(--r-lg);
  border: 1px solid var(--line-2);
  background: linear-gradient(180deg, rgba(12, 17, 28, 0.96), rgba(6, 9, 16, 0.98));
  backdrop-filter: blur(16px) saturate(130%);
  -webkit-backdrop-filter: blur(16px) saturate(130%);
  box-shadow: var(--shadow-2), 0 0 90px -50px rgba(var(--accent-rgb), 0.9);
  overflow: hidden;
  transform-origin: bottom right;
  animation: chatIn 0.3s var(--ease) both;
}
.chat__panel[hidden] { display: none; }
@keyframes chatIn {
  from { opacity: 0; transform: translateY(14px) scale(0.97); }
}

.chat__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  background: rgba(0, 0, 0, 0.35);
}
.chat__head b {
  font: 700 12px/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
}
.chat__head span {
  font: 600 10.5px/1 var(--mono);
  letter-spacing: 0.1em;
  color: var(--muted);
}
.chat__live {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  font: 700 10.5px/1 var(--mono);
  letter-spacing: 0.1em;
  color: var(--up);
}
.chat__live i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--up);
  box-shadow: 0 0 10px var(--up);
  animation: animBreathe 2s var(--ease) infinite;
}
.chat__close {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.03);
  color: var(--muted);
  cursor: pointer;
}
.chat__close:hover { color: #fff; border-color: var(--line-2); }

/* --- online strip ----------------------------------------------------- */
.chat__stats {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--line);
  font: 600 10.5px/1 var(--mono);
  letter-spacing: 0.06em;
  color: var(--faint);
  background: rgba(255, 255, 255, 0.012);
}
.chat__stats b { color: var(--ink-2); }
.chat__stats .chat__dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--faint);
}
.chat__avatars { display: inline-flex; margin-left: auto; }
.chat__avatars span {
  width: 22px;
  height: 22px;
  margin-left: -7px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.16);
  display: grid;
  place-items: center;
  overflow: hidden;
  font: 800 8.5px/1 var(--mono);
  color: #0a0d14;
}
/* --- generated portraits -------------------------------------------------
   Every face in the room is an <img>: a person drawn from the seat's own code
   by js/sf-portrait.js. These rules only frame one, so the same picture works
   at 22px under the counter and at 28px on a line. */
.chat__ava img,
.chat__face img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  border-radius: inherit;
}
.chat__face { display: block; border-radius: inherit; overflow: hidden; }
.chat__ava { overflow: hidden; }

/* --- the online count -------------------------------------------------
   Just the number and the avatars: the room itself is the feed below.
   ---------------------------------------------------------------------- */
.chat__online {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
}
.chat__online b { color: var(--accent); }

/* --- feed ------------------------------------------------------------- */
.chat__feed {
  padding: 12px 14px 16px;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.chat__msg {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  gap: 10px;
  animation: chatMsg 0.4s var(--ease) both;
}
@keyframes chatMsg {
  from { opacity: 0; transform: translateY(8px); }
}

.chat__ava {
  width: 28px;
  height: 28px;
  border-radius: 9px;
  display: grid;
  place-items: center;
  font: 800 11px/1 var(--mono);
  color: #0a0d14;
}

.chat__body { min-width: 0; }
/* the seat the line is aimed at — a room with several conversations running at
   once needs them visible, otherwise it reads as noise */
.chat__to {
  display: block;
  margin-bottom: 2px;
  font: 600 9.5px/1.2 var(--mono);
  letter-spacing: 0.04em;
  color: var(--faint);
}
.chat__to::before { content: none; }
.chat__meta {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 3px;
}
.chat__meta b {
  font: 700 11.5px/1 var(--mono);
  color: var(--ink);
}
.chat__meta u {
  font: 600 9.5px/1 var(--mono);
  letter-spacing: 0.06em;
  text-decoration: none;
  color: var(--faint);
}
.chat__meta time {
  margin-left: auto;
  font: 600 9.5px/1 var(--mono);
  color: var(--faint);
}
.chat__text {
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-2);
  word-break: break-word;
}
.chat__text em { font-style: normal; color: var(--accent); }
.chat__text b { color: var(--ink); }

/* ---- a line written in another language --------------------------------
   The desk has seats in Osaka, Shenzhen, Seoul, Bangkok, Cairo and São Paulo,
   and a seat writes in the language of the country it trades from. Three things
   make that read as one room rather than as noise:

     · the script keeps its own `lang` and `dir`, so the browser shapes and
       breaks it correctly instead of treating Arabic as a Latin string;
     · the font stack names the CJK, Thai, Arabic and Devanagari faces that ship
       with Windows, macOS and Android, because the desk's own faces carry none
       of those glyphs and a browser left to guess sometimes guesses at boxes;
     · the English gloss sits under the line, quiet and italic — the room is only
       one conversation while everybody can follow it. */
.chat__lang {
  display: inline-block;
  margin-right: 6px;
  padding: 1px 5px;
  border: 1px solid var(--line);
  border-radius: 5px;
  font: 800 8.5px/1.45 var(--mono, ui-monospace, monospace);
  letter-spacing: 0.1em;
  vertical-align: 1px;
  color: var(--faint);
}
.chat__native {
  font-family: 'Rajdhani', 'Hiragino Sans', 'Hiragino Kaku Gothic ProN', 'Yu Gothic UI', 'Meiryo',
    'Noto Sans JP', 'Noto Sans SC', 'Microsoft YaHei', 'PingFang SC', 'Noto Sans KR', 'Malgun Gothic',
    'Apple SD Gothic Neo', 'Leelawadee UI', 'Noto Sans Thai', 'Geeza Pro', 'Noto Naskh Arabic',
    'Noto Sans Arabic', 'Nirmala UI', 'Noto Sans Devanagari', 'Kohinoor Devanagari', system-ui, sans-serif;
  color: var(--ink);
}
.chat__text .chat__gloss {
  display: block;
  margin-top: 3px;
  font-size: 12.2px;
  font-style: italic;
  line-height: 1.45;
  color: var(--muted);
}

.chat__msg.is-desk .chat__ava {
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
}
.chat__msg.is-desk .chat__meta b { color: var(--accent); }

.chat__sys {
  align-self: center;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.02);
  font: 600 10px/1 var(--mono);
  letter-spacing: 0.06em;
  color: var(--faint);
  animation: chatMsg 0.4s var(--ease) both;
}

.chat__react {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(var(--accent-rgb), 0.06);
  font: 700 10px/1 var(--mono);
  color: var(--ink-2);
}

/* --- reactions ----------------------------------------------------------
   One chip per emoji, added by js/term-chat.js as the core times them in. The
   row is empty — and therefore invisible — on a line nobody reacted to. */
.chat__reactions {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 7px;
}
.chat__reactions:empty { display: none; }
.chat__react b { color: var(--ink); font-weight: 700; }
.chat__react.is-new { animation: chatPop 0.55s var(--ease) both; }
@keyframes chatPop {
  0% { transform: scale(0.55); opacity: 0; }
  55% { transform: scale(1.14); }
  100% { transform: scale(1); opacity: 1; }
}

/* --- typing ----------------------------------------------------------- */
.chat__typing {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 14px;
  border-top: 1px solid var(--line);
  font: 600 10.5px/1 var(--mono);
  letter-spacing: 0.06em;
  color: var(--faint);
  min-height: 34px;
}
.chat__typing b { color: var(--ink-2); font-weight: 700; }
.chat__typing i {
  display: inline-block;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--accent);
  animation: chatDot 1.1s var(--ease) infinite;
}
.chat__typing i:nth-child(2) { animation-delay: 0.15s; }
.chat__typing i:nth-child(3) { animation-delay: 0.3s; }
@keyframes chatDot {
  0%, 100% { transform: translateY(0); opacity: 0.4; }
  50%      { transform: translateY(-3px); opacity: 1; }
}

/* --- the composer: a lock, not an input -------------------------------- */
.chat__post {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 12px;
  border-top: 1px solid var(--line);
  background: rgba(0, 0, 0, 0.22);
}
.chat__post input {
  flex: 1 1 auto;
  min-width: 0;
  height: 34px;
  padding: 0 12px;
  border-radius: 999px;
  border: 1px dashed rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.02);
  color: var(--faint);
  font: 600 11px/1 var(--mono);
  cursor: not-allowed;
}
.chat__lockico {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 9px;
  border: 1px solid var(--line-gold);
  background: rgba(var(--accent-rgb), 0.08);
  color: var(--accent);
}
.chat__lockico svg { width: 15px; height: 15px; }
.chat__send {
  flex: none;
  padding: 9px 12px;
  border-radius: 999px;
  border: 1px solid var(--line-gold);
  background: rgba(var(--accent-rgb), 0.1);
  color: var(--accent);
  font: 700 10px/1 var(--mono);
  letter-spacing: 0.12em;
  text-decoration: none;
  white-space: nowrap;
}
.chat__send:hover { background: rgba(var(--accent-rgb), 0.2); color: #fff; }
.chat__msg.is-mine .chat__ava { box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.6); }

/* --- footer ----------------------------------------------------------- */
.chat__foot {
  padding: 9px 14px 11px;
  border-top: 1px solid var(--line);
  background: rgba(0, 0, 0, 0.3);
  font: 600 9.5px/1.5 var(--mono);
  letter-spacing: 0.04em;
  color: var(--faint);
}
.chat__foot b { color: var(--muted); }

/* --- responsive ------------------------------------------------------- */
@media (max-width: 860px) {
  .chat { right: 12px; bottom: 12px; }
  .toasts { bottom: 76px; }
  .chat__panel {
    width: calc(100vw - 24px);
    height: 62dvh;
    max-height: 62dvh;
    bottom: 58px;
  }
  .chat__fab { height: 42px; padding: 0 13px; }
  .chat__fab b { display: none; }
}

@media (max-width: 560px) {
  .chat__feed { padding: 10px 11px 14px; gap: 10px; }
  .chat__text { font-size: 13px; }
  .chat__who-rows { max-height: 96px; }
}

@media (prefers-reduced-motion: reduce) {
  .chat__fab i::after,
  .chat__live i,
  .chat__typing i { animation: none !important; }
  .chat__msg,
  .chat__sys,
  .chat__react,
  .chat__panel { animation: none !important; }
  .chat__fab:hover { transform: none; }
}

@media print {
  .chat { display: none !important; }
}
