/* ==========================================================================
   css/components/nameplates.css
   Split from app.html (build 2026.10.08.9-beta), original lines 2150-2405.
   Rules are in their ORIGINAL order; load order is defined in index.html.
   ========================================================================== */
/* -- Animated nameplates ------------------------------------------
   Only background-position animates (GPU-cheap), so the name + avatar stay crisp
   and it works on any number of rows. Applied via [data-plate] on member/voice rows
   and the shop preview. */
/* Full-bleed symmetric gradients (dark→bright→dark) that gently drift back and forth
   (alternate = no scroll-off / no loop jump), so the band never cuts off. */
[data-plate] { background-repeat: no-repeat; background-size: 200% 100%; animation: plate-flow 7s ease-in-out infinite alternate; }
@keyframes plate-flow { from { background-position: 0% 0; } to { background-position: 100% 0; } }
/* When the window is unfocused/hidden, freeze EVERY decorative loop - not just plates.
   On the software-OSR render path each running animation forces a full-window repaint
   ~60x/s, so 40+ spinning/hue/pulse SVG decos kept churning the whole desktop while you
   worked in another app. Pausing them all here reclaims that for free (no visible change
   while focused). Mirrors the perf-mode freeze set. */
body.win-blur,                 /* the body-level animated gradient theme (set inline) */
body.win-blur [data-plate],
body.win-blur [data-cplate],
body.win-blur [data-nsfx],
body.win-blur [data-plate]::before,
body.win-blur [data-cplate]::before,
body.win-blur .member-item.plate-anim[data-cplate]::before,
body.win-blur .dspin, body.win-blur .dspin2, body.win-blur .dspinR,
body.win-blur .dpulse, body.win-blur .dflick, body.win-blur .dhue,
body.win-blur .ddash, body.win-blur .ddash2, body.win-blur .ddashR {
  animation-play-state: paused !important;
}
/* Also freeze the decorative loops while in a voice/video call: the call view is the focus,
   not the background decos churning ~60x/s, so pausing them reclaims CPU with no visible
   cost during a call. rv-in-voice is toggled on the body whenever you're in voice. */
body.rv-in-voice,
body.rv-in-voice [data-plate],
body.rv-in-voice [data-cplate],
body.rv-in-voice [data-nsfx],
body.rv-in-voice [data-plate]::before,
body.rv-in-voice [data-cplate]::before,
body.rv-in-voice .member-item.plate-anim[data-cplate]::before,
body.rv-in-voice .dspin, body.rv-in-voice .dspin2, body.rv-in-voice .dspinR,
body.rv-in-voice .dpulse, body.rv-in-voice .dflick, body.rv-in-voice .dhue,
body.rv-in-voice .ddash, body.rv-in-voice .ddash2, body.rv-in-voice .ddashR {
  animation-play-state: paused !important;
}
[data-plate="crimson"] { background-image: linear-gradient(100deg, #7f1d1d77 0%, #ef444466 30%, #f871859e 52%, #ef444466 74%, #7f1d1d77 100%); }
[data-plate="ocean"]   { background-image: linear-gradient(100deg, #0c4a6e77 0%, #0284c766 30%, #38bdf89e 52%, #0284c766 74%, #0c4a6e77 100%); }
[data-plate="sunset"]  { background-image: linear-gradient(100deg, #7c2d1277 0%, #ea580c66 30%, #fb923c9e 52%, #ea580c66 74%, #7c2d1277 100%); }
[data-plate="forest"]  { background-image: linear-gradient(100deg, #14532d77 0%, #16a34a66 30%, #4ade809e 52%, #16a34a66 74%, #14532d77 100%); }
[data-plate="violet"]  { background-image: linear-gradient(100deg, #4c1d9577 0%, #7c3aed66 30%, #a78bfa9e 52%, #7c3aed66 74%, #4c1d9577 100%); }
[data-plate="mint"]    { background-image: linear-gradient(100deg, #065f4677 0%, #0d9488 30%, #6ee7b79e 52%, #0d948866 74%, #065f4677 100%); }
[data-plate="rose"]    { background-image: linear-gradient(100deg, #83184377 0%, #e11d4866 30%, #fb71859e 52%, #e11d4866 74%, #83184377 100%); }
[data-plate="cyan"]    { background-image: linear-gradient(100deg, #155e7577 0%, #0891b266 30%, #22d3ee9e 52%, #0891b266 74%, #155e7577 100%); }
[data-plate="aurora"]  { background-image: linear-gradient(100deg, #134e4a88 0%, #22d3ee88 26%, #a78bfa88 50%, #f472b688 74%, #134e4a88 100%); background-size: 220% 100%; animation-duration: 9s; }
[data-plate="prism"]   { background-image: linear-gradient(100deg, #ff004c88 0%, #ffb00088 22%, #28ff0088 44%, #00e5ff88 66%, #c800ff88 88%, #ff004c88 100%); background-size: 240% 100%; animation-duration: 8s; }
[data-plate="ember"]   { background-image: linear-gradient(100deg, #7c2d1288 0%, #ef444477 32%, #f59e0b9e 52%, #ef444477 72%, #7c2d1288 100%); animation-duration: 5.5s; }
[data-plate="galaxy"]  { background-image: radial-gradient(circle at 74% 42%, #c4b5fd88, transparent 46%), linear-gradient(100deg, #1e1b4b99 0%, #4c1d9577 34%, #7c3aed99 55%, #312e8177 76%, #1e1b4b99 100%); background-size: 200% 100%, 200% 100%; }
[data-plate="gold"]    { background-image: linear-gradient(100deg, #78350f99 0%, #b4791099 30%, #fff4c0dd 50%, #b4791099 70%, #78350f99 100%); animation: plate-flow 5s ease-in-out infinite alternate; }
[data-plate="mono"]    { background-image: linear-gradient(100deg, #37415199 0%, #6b728099 30%, #e5e7ebdd 50%, #6b728099 70%, #37415199 100%); animation: plate-flow 5.5s ease-in-out infinite alternate; }
[data-plate="winter"]  { background-image: linear-gradient(100deg, #1e3a8a77 0%, #3b82f666 30%, #dbeafedd 52%, #3b82f666 74%, #1e3a8a77 100%); animation-duration: 8s; }
[data-plate="autumn"]  { background-image: linear-gradient(100deg, #7c2d1288 0%, #ea580c77 32%, #f59e0b9e 52%, #b91c1c77 72%, #7c2d1288 100%); }
[data-plate="sakura"]  { background-image: linear-gradient(100deg, #9d174d66 0%, #ec489966 30%, #fbcfe8e0 52%, #ec489966 74%, #9d174d66 100%); }
[data-plate="toxic"]   { background-image: linear-gradient(100deg, #3f620877 0%, #65a30d77 30%, #a3e6359e 52%, #65a30d77 74%, #3f620877 100%); animation-duration: 6s; }
[data-plate="northlight"] { background-image: linear-gradient(100deg, #0b3d2e88 0%, #10b98188 24%, #22d3ee88 44%, #4ade8088 60%, #8b5cf688 80%, #0b3d2e88 100%); background-size: 250% 100%; animation-duration: 10s; }
[data-plate="lava"]    { background-image: linear-gradient(100deg, #1c091099 0%, #7f1d1d99 26%, #ef444488 48%, #f59e0baa 62%, #7f1d1d99 80%, #1c091099 100%); background-size: 220% 100%; animation-duration: 5s; }
[data-plate="midnight"]{ background-image: linear-gradient(100deg, #0f172a99 0%, #1e3a8a88 32%, #6366f188 52%, #312e8188 72%, #0f172a99 100%); animation-duration: 9s; }
/* Voice list: keep the plate off the left (connector + avatar) so the tree lines stay
   visible - it only colours the name area on the right. Per-plate accent via --pv. */
[data-plate="crimson"]{--pv:#f8718599}[data-plate="ocean"]{--pv:#38bdf899}[data-plate="sunset"]{--pv:#fb923c99}[data-plate="forest"]{--pv:#4ade8099}[data-plate="violet"]{--pv:#a78bfa99}[data-plate="mint"]{--pv:#6ee7b799}[data-plate="rose"]{--pv:#fb718599}[data-plate="cyan"]{--pv:#22d3ee99}[data-plate="winter"]{--pv:#93c5fdaa}[data-plate="autumn"]{--pv:#f59e0baa}[data-plate="sakura"]{--pv:#f9a8d4cc}[data-plate="toxic"]{--pv:#a3e635aa}[data-plate="aurora"]{--pv:#a78bfa99}[data-plate="northlight"]{--pv:#4ade80aa}[data-plate="prism"]{--pv:#00e5ff99}[data-plate="ember"]{--pv:#f59e0baa}[data-plate="lava"]{--pv:#f59e0baa}[data-plate="midnight"]{--pv:#6366f1aa}[data-plate="galaxy"]{--pv:#7c3aedaa}[data-plate="gold"]{--pv:#fbbf24aa}[data-plate="mono"]{--pv:#9ca3afaa}
.voice-sidebar-member[data-plate] { background-image: linear-gradient(90deg, transparent 0, transparent 42px, var(--pv, #88888899) 92px, var(--pv, #88888899) 100%); background-size: 100% 100%; background-position: left center; animation: none; }
/* Member list: fade the animated plate out over the avatar so it doesn't slab across
   the pfp (NONONONONO-style). The plate is the row's own background, so we can't mask the
   row (that would fade the avatar too) - instead an overlay re-paints the row's resting
   colour on the left, fading to transparent so the plate only shows past the avatar. */
.member-item { position: relative; }
/* Animated preset plates ([data-plate]): the plate is the ROW background, so an overlay
   repaints the row's resting colour on the LEFT (fading to transparent) so the plate only
   shows past the avatar. */
.member-item[data-plate]::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 0;
  background: linear-gradient(90deg, var(--bg-chat) 0%, var(--bg-chat) 34px, transparent 96px);
}
/* Custom/scene plates ([data-cplate]): the plate lives on this ::before layer and is MASKED
   to fade out on the left. A mask makes those pixels truly transparent (the real row bg
   shows through), so it works under custom themes where an opaque overlay couldn't. */
.member-item[data-cplate]::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 0;
  background: var(--plate-bg, #8888) var(--plate-pos, center) / var(--plate-size, cover) no-repeat;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, transparent 30px, #000 92px);
          mask-image: linear-gradient(90deg, transparent 0, transparent 30px, #000 92px);
}
.member-item.plate-anim[data-cplate]::before { animation: plate-flow 7s ease-in-out infinite alternate; }
.member-item[data-plate] > *,
.member-item[data-cplate] > * { position: relative; z-index: 1; }
/* Legibility: name + status text can sit over any plate colour/scene, so on a plated row
   force high-contrast white with a shadow instead of the dim muted grey (which vanished
   against bright/photo nameplates). */
.member-item[data-plate] .member-name,
.member-item[data-cplate] .member-name { color: #fff;}
.member-item[data-plate] .member-activity,
.member-item[data-cplate] .member-activity { color: rgba(255,255,255,0.9);}

.msg-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display, 'Space Grotesk', sans-serif);
  font-weight: 700;
  font-size: 14px;
  color: #fff;
  margin-top: 2px;
  cursor: pointer;
  overflow: hidden;
}

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

.msg-body { flex: 1; min-width: 0; }

.msg-header {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 2px;
}

.msg-author {
  /* The SAME size as the message body, which is what the reference does - its username and body
     are both 16px and only the weight differs (500 vs 400). This was pinned at 14px while the
     body reads var(--a11y-msg-size), so the two agreed only at the default and drifted apart as
     soon as the Text Size setting moved: at 16 the body was BIGGER than the name above it.
     Same variable for both means they track each other at every setting. */
  font-size: var(--a11y-msg-size, 14px);
  font-weight: 500;
  color: var(--text-primary);
  cursor: pointer;
}
.msg-author:hover { text-decoration: underline; }
.msg-author.mod { color: #faa61a; }
.msg-author.admin { color: var(--red); }
.msg-author.bot { color: var(--blue); }

.msg-bot-badge {
  background: var(--blue);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  padding: 1px 4px;
  border-radius: 3px;
  text-transform: uppercase;
}

.msg-timestamp { font-size: 11px; color: var(--text-muted); }

.msg-timestamp-inline {
  position: absolute;
  left: 16px;
  top: 6px;
  font-size: 10px;
  color: var(--text-muted);
  opacity: 0;
  transition: opacity 0.1s;
  width: 40px;
  text-align: center;
  white-space: nowrap;
}

.msg-content {
  font-size: var(--a11y-msg-size, 14px);
  /* Message body is 400, not 500. At 500 every message in the app rendered in Rift Sans
     MEDIUM - body text one step heavy, which is the single biggest reason the type read wrong
     against the reference, because it is the text there is most of. The reference's body is
     `text-md/normal` = 400. Rift Sans ships a real 400 cut, so nothing is synthesised.
     Colour still nudged brighter than the dim --text-secondary so it reads crisply. */
  font-weight: 400;
  color: color-mix(in srgb, var(--text-secondary) 55%, var(--text-primary));
  line-height: 1.6;
  word-break: break-word;
  /* Preserve the line breaks people type with Shift+Enter (and runs of spaces).
     Without this the container collapses every newline to a single space. */
  white-space: pre-wrap;
}

.msg-content code {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 0 4px;
  font-family: monospace;
  font-size: 12px;
  color: var(--text-primary);
}

.msg-content a { color: var(--accent-bright); }
/* Automod blocked-message card (ephemeral, shown only to the sender) */
.msg-automod-card {
  display: flex; align-items: flex-start; gap: 12px; margin: 8px 16px;
  padding: 12px 14px; border-radius: 10px; background: var(--bg-surface);
  border: 1px solid color-mix(in srgb, #ed4245 40%, var(--border-strong));
  box-shadow: 0 4px 16px rgba(0,0,0,.25); animation: toast-in .18s ease;
}
.msg-automod-icon {
  width: 30px; height: 30px; border-radius: 8px; flex-shrink: 0; display: flex;
  align-items: center; justify-content: center; color: #ed4245; background: rgba(237,66,69,.14);
}
.msg-automod-text { flex: 1; min-width: 0; }
.msg-automod-title { font-size: 13px; font-weight: 700; color: var(--text-primary); }
.msg-automod-reason { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.msg-automod-preview {
  font-size: 13px; color: var(--text-secondary); margin-top: 6px; padding: 6px 9px;
  background: var(--bg-void); border-radius: 6px; word-break: break-word;
  max-height: 76px; overflow: hidden;
}
.msg-automod-dismiss {
  flex-shrink: 0; font-size: 18px; line-height: 1; color: var(--text-muted);
  background: none; border: none; cursor: pointer; padding: 2px 6px; border-radius: 4px;
}
.msg-automod-dismiss:hover { background: var(--bg-hover); color: var(--text-primary); }
.msg-content a:hover { text-decoration: underline; }

.msg-reactions {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
}

/* Reaction pill (reference-matched): a rounded-rectangle chip with a subtle
   translucent fill + thin border, accent-tinted once you've reacted. */
.reaction {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 2px 6px;
  min-height: 24px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;         /* rounded rectangle, not a full pill */
  font-size: 16px;            /* unicode emoji size (~18px glyph) */
  line-height: 1;
  cursor: pointer;
  transition: background 0.1s, border-color 0.1s, transform 0.12s var(--ease-spring, ease);
}
.reaction:hover { background: rgba(255, 255, 255, 0.10); border-color: rgba(255, 255, 255, 0.16); transform: translateY(-1px); }
.reaction:active { transform: scale(0.94); }
.reaction.mine { background: var(--accent-dim); border-color: var(--accent); }
.reaction > span:first-child { font-size: 16px; }
.reaction img { width: 18px; height: 18px; object-fit: contain; vertical-align: middle; }
.reaction .count { font-size: 13px; color: var(--text-secondary); font-weight: 600; }
.reaction.mine .count { color: var(--text-primary); }
/* Inline add-reaction chip at the END of the row - only rendered on message hover
   (display:none, not opacity:0, so it never takes space or pushes the reactions apart). */
.reaction-add {
  display: none; align-items: center; justify-content: center;
  min-height: 24px; padding: 0 7px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.1s, color 0.1s;
}
.message-group:hover .reaction-add { display: flex; }
.reaction-add:hover { background: rgba(255, 255, 255, 0.10); color: var(--text-secondary); }

