Polish: reduced motion, toast animation, token consistency

- Add prefers-reduced-motion media query for accessibility
- Add slide-in animation for toast notifications
- Standardize transition durations across note cards
- Replace remaining hard-coded text-white with theme tokens
This commit is contained in:
Jure
2026-04-02 18:30:10 +02:00
parent ae5b9a444c
commit ba3ef9e2c8
6 changed files with 24 additions and 5 deletions

View File

@@ -259,7 +259,7 @@ export function ComposeBox({ onPublished, onNoteInjected }: { onPublished?: () =
)} )}
<button <button
onClick={() => removeAttachment(i)} onClick={() => removeAttachment(i)}
className="absolute -top-1.5 -right-1.5 w-4 h-4 bg-danger text-white text-[10px] rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity" className="absolute -top-1.5 -right-1.5 w-4 h-4 bg-danger text-accent-text text-[10px] rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity"
title="Remove" title="Remove"
> >
x x

View File

@@ -182,7 +182,7 @@ export function InlineReplyBox({ event, name, rootEvent }: InlineReplyBoxProps)
)} )}
<button <button
onClick={() => removeAttachment(i)} onClick={() => removeAttachment(i)}
className="absolute -top-1.5 -right-1.5 w-4 h-4 bg-danger text-white text-[10px] rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity" className="absolute -top-1.5 -right-1.5 w-4 h-4 bg-danger text-accent-text text-[10px] rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity"
title="Remove" title="Remove"
> >
x x

View File

@@ -65,7 +65,7 @@ export const NoteCard = memo(function NoteCard({ event, focused, onReplyInThread
<article <article
ref={cardRef} ref={cardRef}
data-note-id={event.id} data-note-id={event.id}
className={`border-b border-border px-4 py-3 hover:bg-bg-hover transition-colors duration-100 cursor-pointer group/card${focused ? " bg-accent/10 border-l-2 border-l-accent" : ""}`} className={`border-b border-border px-4 py-3 hover:bg-bg-hover transition-colors cursor-pointer group/card${focused ? " bg-accent/10 border-l-2 border-l-accent" : ""}`}
onClick={(e) => { onClick={(e) => {
// Don't navigate if clicking on interactive elements // Don't navigate if clicking on interactive elements
const target = e.target as HTMLElement; const target = e.target as HTMLElement;

View File

@@ -101,7 +101,7 @@ function ImageGrid({ images, onImageClick }: { images: string[]; onImageClick: (
className="absolute inset-0 bg-black/50 flex items-center justify-center rounded-sm cursor-zoom-in" className="absolute inset-0 bg-black/50 flex items-center justify-center rounded-sm cursor-zoom-in"
onClick={(e) => { e.stopPropagation(); onImageClick(idx); }} onClick={(e) => { e.stopPropagation(); onImageClick(idx); }}
> >
<span className="text-white text-lg font-semibold">+{extraCount}</span> <span className="text-[#ffffff] text-lg font-semibold">+{extraCount}</span>
</div> </div>
)} )}
</div> </div>

View File

@@ -16,7 +16,7 @@ export function ToastContainer() {
{toasts.map((toast) => ( {toasts.map((toast) => (
<div <div
key={toast.id} key={toast.id}
className="flex items-stretch min-w-[240px] max-w-[360px] bg-bg-raised border border-border shadow-lg" className="flex items-stretch min-w-[240px] max-w-[360px] bg-bg-raised border border-border shadow-lg toast-enter"
> >
<div className={`w-1 shrink-0 ${accentColor[toast.type]}`} /> <div className={`w-1 shrink-0 ${accentColor[toast.type]}`} />
<div className="flex items-center justify-between gap-2 px-3 py-2 flex-1"> <div className="flex items-center justify-between gap-2 px-3 py-2 flex-1">

View File

@@ -99,6 +99,25 @@ body {
animation: fade-in 150ms ease-out; animation: fade-in 150ms ease-out;
} }
/* Toast slide-in */
@keyframes toast-in {
from { opacity: 0; transform: translateX(16px); }
to { opacity: 1; transform: translateX(0); }
}
.toast-enter {
animation: toast-in 200ms ease-out;
}
/* Reduced motion: collapse all animations/transitions */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
/* Scrollbar */ /* Scrollbar */
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 12px; width: 12px;