137 lines
3.5 KiB
CSS
137 lines
3.5 KiB
CSS
/* @xtablo/chat-ui — Animations and utility classes */
|
|
|
|
/* ─── Message entry ─────────────────────────────────────────────── */
|
|
@keyframes chat-message-enter {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(8px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
/* ─── Toolbar entrance ──────────────────────────────────────────── */
|
|
@keyframes chat-toolbar-enter {
|
|
from {
|
|
opacity: 0;
|
|
transform: scale(0.95) translateY(4px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: scale(1) translateY(0);
|
|
}
|
|
}
|
|
|
|
/* ─── Reaction pop ──────────────────────────────────────────────── */
|
|
@keyframes chat-reaction-pop {
|
|
0% {
|
|
transform: scale(0);
|
|
opacity: 0;
|
|
}
|
|
70% {
|
|
transform: scale(1.1);
|
|
}
|
|
100% {
|
|
transform: scale(1);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
/* ─── Typing indicator dots ─────────────────────────────────────── */
|
|
@keyframes chat-typing-pulse {
|
|
0%,
|
|
60%,
|
|
100% {
|
|
opacity: 0.3;
|
|
transform: translateY(0);
|
|
}
|
|
30% {
|
|
opacity: 1;
|
|
transform: translateY(-4px);
|
|
}
|
|
}
|
|
|
|
/* ─── Cursor blink (streaming) ──────────────────────────────────── */
|
|
@keyframes chat-cursor-blink {
|
|
0%,
|
|
100% {
|
|
opacity: 1;
|
|
}
|
|
50% {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
/* ─── Read receipt status color transition ───────────────────────── */
|
|
@keyframes chat-status-read-in {
|
|
from {
|
|
color: var(--color-muted-foreground);
|
|
}
|
|
to {
|
|
color: var(--color-primary);
|
|
}
|
|
}
|
|
|
|
/* ─── Utility classes ───────────────────────────────────────────── */
|
|
@layer base {
|
|
.chat-message {
|
|
animation: chat-message-enter 250ms cubic-bezier(0.25, 0.1, 0.25, 1);
|
|
}
|
|
|
|
.chat-typing-dot {
|
|
animation: chat-typing-pulse 1.4s ease-in-out infinite;
|
|
}
|
|
|
|
.chat-toolbar-enter {
|
|
transform-origin: bottom center;
|
|
}
|
|
|
|
.group\/message:hover .chat-toolbar-enter {
|
|
animation: chat-toolbar-enter 150ms ease-out;
|
|
}
|
|
|
|
.chat-reaction-pop {
|
|
animation: chat-reaction-pop 200ms cubic-bezier(0.25, 0.1, 0.25, 1);
|
|
}
|
|
|
|
.chat-status-read {
|
|
animation: chat-status-read-in 400ms ease-out;
|
|
}
|
|
|
|
.chat-streaming-cursor {
|
|
animation: chat-cursor-blink 1s step-end infinite;
|
|
}
|
|
|
|
.chat-content-card {
|
|
background: var(--color-card);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 12px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.chat-drop-overlay {
|
|
position: absolute;
|
|
inset: 0;
|
|
z-index: 50;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: color-mix(in oklch, var(--color-background) 80%, transparent);
|
|
border: 2px dashed var(--color-primary);
|
|
border-radius: 12px;
|
|
backdrop-filter: blur(4px);
|
|
}
|
|
}
|
|
|
|
/* ─── Reduced motion ────────────────────────────────────────────── */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.chat-message,
|
|
.chat-typing-dot,
|
|
.chat-toolbar-enter,
|
|
.chat-reaction-pop,
|
|
.chat-status-read {
|
|
animation: none;
|
|
}
|
|
}
|