diff --git a/packages/chat-ui/src/chat-ui.css b/packages/chat-ui/src/chat-ui.css new file mode 100644 index 0000000..0398317 --- /dev/null +++ b/packages/chat-ui/src/chat-ui.css @@ -0,0 +1,100 @@ +/* @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.0); + } + + .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.0); + } + + .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; + } +}