feat(frontend): content micro-animations — stagger, button press, toast polish
- animate-stagger utility + staggerDelay() helper; lists now rise in sequence (recordings grid, moderation rows, message list, media queue, dashboard tiles). - Button gets a subtle active:scale-[0.97] press feedback. - Toaster: toast-in slide-up, tone-accent border, rounded hover-close target. - All motion is reduced-motion aware (killed under prefers-reduced-motion).
This commit is contained in:
@@ -40,7 +40,7 @@ export const Button = ({
|
||||
return (
|
||||
<Comp
|
||||
className={cn(
|
||||
"inline-flex items-center justify-center whitespace-nowrap transition-all duration-150 select-none",
|
||||
"inline-flex items-center justify-center whitespace-nowrap transition-all duration-150 select-none active:scale-[0.97]",
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-signal/60 disabled:opacity-40 disabled:pointer-events-none",
|
||||
variants[variant],
|
||||
sizes[size],
|
||||
|
||||
@@ -74,8 +74,11 @@ export function Toaster({ position = "bottom-right" }: { position?: string }) {
|
||||
return (
|
||||
<div
|
||||
key={t.id}
|
||||
className="glass pointer-events-auto flex items-start gap-3 p-3.5"
|
||||
style={{ animation: "fade-up 0.18s ease" }}
|
||||
className={cn(
|
||||
"glass animate-toast-in pointer-events-auto flex items-start gap-3 p-3.5 transition-colors",
|
||||
t.tone === "signal" && "border-signal/30",
|
||||
t.tone === "vermilion" && "border-vermilion/30",
|
||||
)}
|
||||
>
|
||||
<Icon
|
||||
className={cn(
|
||||
@@ -95,11 +98,12 @@ export function Toaster({ position = "bottom-right" }: { position?: string }) {
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Dismiss"
|
||||
onClick={() => {
|
||||
store = store.filter((x) => x.id !== t.id);
|
||||
emit();
|
||||
}}
|
||||
className="text-ink-faint hover:text-ink"
|
||||
className="rounded-md p-1 text-ink-faint transition-colors hover:bg-white/8 hover:text-ink"
|
||||
>
|
||||
<X className="size-3.5" />
|
||||
</button>
|
||||
|
||||
@@ -37,6 +37,7 @@ export function MetricTile({
|
||||
spark,
|
||||
icon,
|
||||
className,
|
||||
style,
|
||||
}: {
|
||||
label: string;
|
||||
value: React.ReactNode;
|
||||
@@ -45,6 +46,7 @@ export function MetricTile({
|
||||
spark?: number[];
|
||||
icon?: React.ReactNode;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
}) {
|
||||
const toneColor =
|
||||
tone === "vermilion"
|
||||
@@ -60,6 +62,7 @@ export function MetricTile({
|
||||
"glass p-4 ring-focus transition-transform duration-200 hover:-translate-y-0.5",
|
||||
className,
|
||||
)}
|
||||
style={style}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="eyebrow">{label}</div>
|
||||
|
||||
Reference in New Issue
Block a user