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
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"
>
x

View File

@@ -182,7 +182,7 @@ export function InlineReplyBox({ event, name, rootEvent }: InlineReplyBoxProps)
)}
<button
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"
>
x

View File

@@ -65,7 +65,7 @@ export const NoteCard = memo(function NoteCard({ event, focused, onReplyInThread
<article
ref={cardRef}
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) => {
// Don't navigate if clicking on interactive elements
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"
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>

View File

@@ -16,7 +16,7 @@ export function ToastContainer() {
{toasts.map((toast) => (
<div
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="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;
}
/* 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 */
::-webkit-scrollbar {
width: 12px;