*, *::before, *::after { box-sizing: border-box; }

:root {
  --bg:        #0b0b0f;
  --bg-row:    #131318;
  --line:      #22222c;
  --text:      #e9e9f0;
  --dim:       #8b8b9c;

  --twitch:    #a970ff;
  --tiktok:    #25f4ee;
  --youtube:   #ff3d47;

  --bits:      #c9a3ff;
  --sub:       #a970ff;
  --prime:     #4d9bff;
  --gift:      #ff6ec7;
  --gift-tiktok:#25f4ee;
  --donation:  #ffc93c;
  --member:    #2fd57e;
  --raid:      #ff9d3c;
  --follow:    #6f6f82;
  --announce:  #8b8b9c;

  --row-pad:   4px 12px;
  --fs:        16px;
}

html, body {
  height: 100%; margin: 0;
  background: var(--bg); color: var(--text);
  font: var(--fs)/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, sans-serif;
  overflow: hidden;
}
body { display: flex; flex-direction: column; }
header { flex: none; }

/* Flex + min-height:0 rather than calc() on the header height, so the panel and
   the feed both scroll independently and nothing depends on a magic number. */
#stage {
  flex: 1; min-height: 0;
  display: grid; grid-template-columns: 1fr 330px;
}
body.nodons #stage { grid-template-columns: 1fr; }
body.nodons #dons { display: none; }

/* ------------------------------------------------------------- header --- */

header {
  display: flex; align-items: center; gap: 14px;
  padding: 9px 14px;
  background: #0e0e13;
  border-bottom: 1px solid var(--line);
  user-select: none;
}

.brand {
  font-weight: 800; font-size: 15px; letter-spacing: .1em;
  color: var(--text);
}
.brand span { color: var(--dim); margin-left: 3px; }

.filters { display: flex; gap: 7px; margin-left: auto; }

.pill {
  display: flex; align-items: center; gap: 7px;
  padding: 5px 11px;
  font: 600 13px/1 inherit; color: var(--dim);
  background: #17171e; border: 1px solid var(--line); border-radius: 999px;
  cursor: pointer; transition: background .12s, color .12s, border-color .12s, opacity .12s;
}
.pill:hover { background: #1e1e27; }
.pill .ic { width: 14px; height: 14px; fill: currentColor; flex: none; }

/* Off = drained of colour and pushed back, so "hidden" reads at a glance. */
.pill:not(.on) { opacity: .4; }
.pill:not(.on) .lbl { text-decoration: line-through; }

.pill.on[data-toggle="twitch"]  { color: var(--twitch);  border-color: #3a2a5c; background: #1b1428; }
.pill.on[data-toggle="tiktok"]  { color: var(--tiktok);  border-color: #14484a; background: #0d2224; }
.pill.on[data-toggle="youtube"] { color: var(--youtube); border-color: #5c2229; background: #261114; }

.dot { width: 7px; height: 7px; border-radius: 50%; background: #444; flex: none; }
.dot.connected   { background: #2fd57e; box-shadow: 0 0 7px #2fd57e88; }
.dot.reconnecting{ background: #ffc93c; animation: blink 1s infinite; }
.dot.offline, .dot.off { background: #4a4a58; }
/* A setup problem must not look like "he just isn't streaming there". */
.dot.nokey, .dot.error { background: var(--youtube); box-shadow: 0 0 7px #ff3d4788; }
@keyframes blink { 50% { opacity: .25; } }

.ct {
  min-width: 26px; text-align: center;
  font-variant-numeric: tabular-nums; font-size: 11px;
  color: var(--dim); background: #00000055; border-radius: 999px; padding: 2px 5px;
}

.evonly.on { color: #14141a; background: var(--donation); border-color: var(--donation); }

/* --------------------------------------------------------------- feed --- */

#feed {
  min-height: 0;
  overflow-y: auto; overscroll-behavior: contain;
  padding: 6px 0 14px;
  scrollbar-width: thin; scrollbar-color: #2c2c38 transparent;
}
#feed::-webkit-scrollbar, #dons::-webkit-scrollbar { width: 9px; }
#feed::-webkit-scrollbar-thumb, #dons::-webkit-scrollbar-thumb { background: #2c2c38; border-radius: 9px; }

/* ---------------------------------------------------- donations panel --- */
/* The whole point: a donation scrolls out of chat in seconds. Here it stays. */

#dons {
  min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  background: #0e0e13; border-left: 1px solid var(--line);
  scrollbar-width: thin; scrollbar-color: #2c2c38 transparent;
}

.dhead {
  position: sticky; top: 0; z-index: 2;
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  padding: 10px 13px 9px;
  background: #0e0e13; border-bottom: 1px solid var(--line);
}
.dtitle { font: 800 11px/1 inherit; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); }
.dtot { text-align: right; }
.dtot b { display: block; font-size: 19px; font-weight: 800; color: var(--donation); font-variant-numeric: tabular-nums; }
.dtot i { font: 400 9px/1.3 inherit; font-style: normal; color: #6a6a7c; }

.dempty { padding: 26px 16px; text-align: center; color: #55556a; font-size: 13px; }
.dempty small { color: #3f3f52; font-size: 11px; line-height: 1.6; display: inline-block; margin-top: 7px; }

.don {
  --c: var(--donation);
  display: grid; grid-template-columns: 30px 1fr; gap: 9px;
  padding: 10px 13px;
  border-bottom: 1px solid #ffffff08;
  border-left: 3px solid var(--c);
  background: linear-gradient(90deg, color-mix(in srgb, var(--c) 13%, transparent), transparent 75%);
  animation: land .45s cubic-bezier(.2,.9,.3,1.2);
}
@keyframes land {
  from { opacity: 0; transform: translateY(-10px); }
  60%  { background-color: color-mix(in srgb, var(--c) 35%, transparent); }
}
.don[data-tier="bits"]        { --c: var(--bits); }
.don[data-tier="sub"]         { --c: var(--sub); }
.don[data-tier="gift"]        { --c: var(--gift); }
.don[data-tier="gift-tiktok"] { --c: var(--gift-tiktok); }
.don[data-tier="donation"]    { --c: var(--donation); }
.don[data-tier="member"]      { --c: var(--member); }

.don .pfp { width: 30px; height: 30px; font-size: 12px; }
.dbody { min-width: 0; }

.damt {
  display: flex; align-items: center; gap: 6px;
  font: 800 19px/1.15 inherit; color: var(--c);
  font-variant-numeric: tabular-nums;
  word-break: break-word;
}
.damt svg { width: 13px; height: 13px; flex: none; }
.don[data-p="twitch"]  .damt svg { fill: var(--twitch); }
.don[data-p="tiktok"]  .damt svg { fill: var(--tiktok); }
.don[data-p="youtube"] .damt svg { fill: var(--youtube); }
.damt img { height: 22px; width: 22px; object-fit: contain; }

.dwho { font-weight: 700; font-size: 14px; color: #cfcfe0; margin-top: 2px;
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dmsg { font-size: 13px; color: #9d9db0; margin-top: 3px; word-wrap: break-word; overflow-wrap: anywhere; }
.dago { font-size: 10px; color: #5c5c70; margin-top: 4px; font-variant-numeric: tabular-nums; }

#sound.on { color: #14141a; background: var(--member); border-color: var(--member); }
#showdons.on { color: #14141a; background: #cfcfe0; border-color: #cfcfe0; }

@media (max-width: 1100px) { #stage { grid-template-columns: 1fr 260px; } }
@media (max-width: 860px)  { #stage { grid-template-columns: 1fr; } #dons { display: none; } }

.row {
  display: grid;
  grid-template-columns: 16px 26px 1fr;
  align-items: start; gap: 8px;
  padding: var(--row-pad);
  animation: in .16s ease-out;
}
@keyframes in { from { opacity: 0; transform: translateY(5px); } }

/* No row separators. Chat reads as a river; the icon column does the sorting. */
.row:hover { background: #ffffff08; }

/* The left rail: one icon, brand-coloured, always in the same column. */
.rail { display: flex; justify-content: center; padding-top: 5px; }
.rail svg { width: 14px; height: 14px; }
.row[data-p="twitch"]  .rail svg { fill: var(--twitch); }
.row[data-p="tiktok"]  .rail svg { fill: var(--tiktok); }
.row[data-p="youtube"] .rail svg { fill: var(--youtube); }

.pfp {
  width: 26px; height: 26px; border-radius: 50%;
  object-fit: cover; background: #23232e; flex: none;
  display: grid; place-items: center;
  font: 700 11px/1 inherit; color: #b9b9cc;
}
.pfp.ph { display: grid; }

.body { min-width: 0; padding-top: 1px; }

.badges { display: inline-flex; gap: 3px; vertical-align: -3px; margin-right: 4px; }
.badges img { width: 16px; height: 16px; border-radius: 3px; }
.badges .txt {
  font: 700 9px/1.5 inherit; letter-spacing: .03em; text-transform: uppercase;
  padding: 0 4px; border-radius: 3px; background: #2e2e3c; color: #b6b6c8;
  vertical-align: 1px;
}

.name { font-weight: 700; color: #cfcfe0; }
.name::after { content: ":"; color: var(--dim); font-weight: 400; }
.ev .name::after { content: ""; }

.msg { color: var(--text); word-wrap: break-word; overflow-wrap: anywhere; }
.msg img.em { height: 22px; vertical-align: -6px; margin: 0 1px; }

.sys { color: var(--dim); font-size: 14px; }

/* ------------------------------------------------------------- events --- */

.row.ev {
  --c: var(--announce);
  background:
    linear-gradient(90deg, color-mix(in srgb, var(--c) 22%, transparent), color-mix(in srgb, var(--c) 4%, transparent) 65%, transparent);
  border-left: 4px solid var(--c);
  padding: 7px 12px 7px 8px;
  margin: 4px 0;
}
.row.ev[data-tier="bits"]        { --c: var(--bits); }
.row.ev[data-tier="sub"]         { --c: var(--sub); }
.row.ev[data-tier="sub"].prime   { --c: var(--prime); }
.row.ev[data-tier="gift"]        { --c: var(--gift); }
.row.ev[data-tier="gift-tiktok"] { --c: var(--gift-tiktok); }
.row.ev[data-tier="donation"]    { --c: var(--donation); }
.row.ev[data-tier="member"]      { --c: var(--member); }
.row.ev[data-tier="raid"]        { --c: var(--raid); }
.row.ev[data-tier="announce"]    { --c: var(--announce); }

/* Follows fire constantly on TikTok - legible, but never competing with money. */
.row.ev[data-tier="follow"] {
  --c: var(--follow);
  background: none; border-left-color: transparent;
  opacity: .5; font-size: 14px; margin: 0; padding: var(--row-pad); padding-left: 12px;
}
.row.ev[data-tier="follow"] .chip { background: none; color: var(--dim); padding: 0; }

.ehead { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }

.chip {
  font: 800 10px/1 inherit; letter-spacing: .07em; text-transform: uppercase;
  padding: 4px 7px; border-radius: 5px;
  color: #0c0c11; background: var(--c);
}

.amt {
  font-weight: 800; font-size: 17px; color: var(--c);
  font-variant-numeric: tabular-nums;
}

/* The big ones should be visible from across the room. */
.row.ev.big { padding-top: 10px; padding-bottom: 10px; }
.row.ev.big .amt { font-size: 22px; }
.row.ev.big .chip { font-size: 11px; padding: 5px 9px; }
.row.ev.big .art { height: 34px; width: 34px; }

.art { height: 26px; width: 26px; object-fit: contain; }

/* Hiding is CSS, not a re-render - toggling a platform is instant. */
body.hide-twitch  .row[data-p="twitch"]  { display: none; }
body.hide-tiktok  .row[data-p="tiktok"]  { display: none; }
body.hide-youtube .row[data-p="youtube"] { display: none; }
body.evonly .row:not(.ev) { display: none; }

#jump {
  position: fixed; left: 50%; bottom: 16px; transform: translateX(-50%);
  padding: 8px 16px; border: 0; border-radius: 999px;
  font: 700 13px/1 inherit; color: #0c0c11; background: var(--text);
  cursor: pointer; box-shadow: 0 6px 20px #000a;
}

@media (max-width: 720px) {
  .pill .lbl, .pill .ct { display: none; }
  .brand span { display: none; }
}
