From 0bc128ff3a8bd41ea27a2f5a67214419658d4433 Mon Sep 17 00:00:00 2001 From: Amruth Pillai Date: Tue, 29 Sep 2026 12:40:36 +0200 Subject: [PATCH] feat(web): give pressable surfaces a quick press response Buttons (every variant except link, skipped while loading), chips, tiles, nav items, rail and tab-bar icons now dip to 0.97 on press; document, template, application and suggestion cards dip to 0.98. Full-width settings and conversation rows darken to the press colour instead of shrinking. Joined button groups cancel the scale so their seams stay closed, and the switch thumb stretches toward its travel while held. Document and template cards transitioned transform, but Tailwind v4 lifts with the translate property, so their hover lift jumped; they now list translate and scale. A new document card keeps its accent ring while hovered, and letter template cards lift like resume template cards. --- .../applications/components/application-card.tsx | 2 +- .../src/features/assistant/assistant-panel.tsx | 9 ++++++--- apps/web/src/features/assistant/conversation.tsx | 2 +- .../web/src/features/documents/document-card.tsx | 5 +++-- .../src/features/documents/documents-page.tsx | 2 +- .../features/documents/new-document-dialog.tsx | 6 +++--- .../resume/editor/design/style-groups.tsx | 2 +- .../resume/editor/design/template-group.tsx | 2 +- apps/web/src/features/settings/preferences.tsx | 2 +- apps/web/src/features/settings/root.tsx | 5 +++-- .../builder/letter/-components/design-panel.tsx | 2 +- .../routes/dashboard/-components/app-shell.tsx | 16 ++++++++-------- packages/ui/src/components/button-group.tsx | 2 +- packages/ui/src/components/button.tsx | 8 ++++++-- packages/ui/src/components/switch.tsx | 2 +- 15 files changed, 38 insertions(+), 29 deletions(-) diff --git a/apps/web/src/features/applications/components/application-card.tsx b/apps/web/src/features/applications/components/application-card.tsx index faf23b958..1289e904f 100644 --- a/apps/web/src/features/applications/components/application-card.tsx +++ b/apps/web/src/features/applications/components/application-card.tsx @@ -21,7 +21,7 @@ export function ApplicationCard({ application, onClick, withMenu = false, draggi return (
diff --git a/apps/web/src/features/assistant/assistant-panel.tsx b/apps/web/src/features/assistant/assistant-panel.tsx index 85c2d143d..7cbef0636 100644 --- a/apps/web/src/features/assistant/assistant-panel.tsx +++ b/apps/web/src/features/assistant/assistant-panel.tsx @@ -358,7 +358,7 @@ function EmptyState({ document, disabled, onPick }: EmptyStateProps) { type="button" disabled={disabled} onClick={() => onPick(suggestion.label)} - className="flex min-h-11 w-full items-center gap-3 rounded-lg border border-line px-3 py-2 text-start transition-colors duration-quick hover:bg-hover disabled:opacity-60" + className="flex min-h-11 w-full items-center gap-3 rounded-lg border border-line px-3 py-2 text-start transition-[background-color,scale] duration-quick ease-enter hover:bg-hover enabled:active:scale-[0.98] disabled:opacity-60" > @@ -489,7 +489,10 @@ function ConversationRow({ thread, current, detail, onOpen, onDelete }: Conversa type="button" aria-current={current ? "true" : undefined} onClick={onOpen} - className={cn("grid min-w-0 flex-1 rounded-lg px-3 py-2 text-start", current && "bg-sunken")} + className={cn( + "grid min-w-0 flex-1 rounded-lg px-3 py-2 text-start transition-colors duration-quick ease-enter active:bg-press", + current && "bg-sunken", + )} > {thread.title} {detail} @@ -498,7 +501,7 @@ function ConversationRow({ thread, current, detail, onOpen, onDelete }: Conversa icon="close" label={t`Delete ${thread.title}`} size="icon-sm" - className="me-1 text-ink-3 opacity-0 transition-[opacity,background-color,border-color,color,filter] focus-visible:opacity-100 group-hover/row:opacity-100" + className="me-1 text-ink-3 opacity-0 transition-[opacity,background-color,border-color,color,filter,scale] focus-visible:opacity-100 group-hover/row:opacity-100" onClick={onDelete} /> diff --git a/apps/web/src/features/assistant/conversation.tsx b/apps/web/src/features/assistant/conversation.tsx index be17530b4..6539322f0 100644 --- a/apps/web/src/features/assistant/conversation.tsx +++ b/apps/web/src/features/assistant/conversation.tsx @@ -669,7 +669,7 @@ export function Composer(props: ComposerProps) { disabled={!streaming && (!hasText || disabled)} onClick={streaming ? props.onStop : submit} className={cn( - "grid size-[34px] shrink-0 place-items-center rounded-lg transition-colors duration-quick", + "grid size-[34px] shrink-0 place-items-center rounded-lg transition-[background-color,color,scale] duration-quick ease-enter enabled:active:scale-[0.97]", streaming ? "bg-ink text-bg" : hasText ? "bg-accent text-on-accent" : "bg-sunken text-ink-3", )} > diff --git a/apps/web/src/features/documents/document-card.tsx b/apps/web/src/features/documents/document-card.tsx index f57821501..06a028731 100644 --- a/apps/web/src/features/documents/document-card.tsx +++ b/apps/web/src/features/documents/document-card.tsx @@ -125,8 +125,9 @@ export function DocumentCard({ document, onTags, onLink }: DocumentItemProps) { document={document} label={document.name} className={cn( - "relative block aspect-page overflow-hidden rounded-[6px] shadow-[0_0_0_1px_var(--line),var(--shadow-1)] transition-[transform,box-shadow] duration-quick hover:-translate-y-0.5 hover:shadow-[0_0_0_1px_var(--line),var(--shadow-2)]", - isNew && "shadow-[0_0_0_2px_var(--accent),var(--shadow-1)]", + "relative block aspect-page overflow-hidden rounded-[6px] shadow-[0_0_0_1px_var(--line),var(--shadow-1)] transition-[translate,scale,box-shadow] duration-quick ease-enter hover:-translate-y-0.5 hover:shadow-[0_0_0_1px_var(--line),var(--shadow-2)] active:scale-[0.98]", + isNew && + "shadow-[0_0_0_2px_var(--accent),var(--shadow-1)] hover:shadow-[0_0_0_2px_var(--accent),var(--shadow-2)]", document.trashedAt && "pointer-events-none", )} > diff --git a/apps/web/src/features/documents/documents-page.tsx b/apps/web/src/features/documents/documents-page.tsx index f46ad48e5..8b939876f 100644 --- a/apps/web/src/features/documents/documents-page.tsx +++ b/apps/web/src/features/documents/documents-page.tsx @@ -160,7 +160,7 @@ export function DocumentsPage({ search, onSearchChange }: DocumentsPageProps) { }) } className={cn( - "h-7 rounded-full border px-3 text-[13px] transition-colors duration-quick", + "h-7 rounded-full border px-3 text-[13px] transition-[background-color,border-color,color,scale] duration-quick ease-enter active:scale-[0.97]", active ? "border-accent bg-accent-soft text-accent-text" : "border-line-2 text-ink-2 hover:bg-hover", diff --git a/apps/web/src/features/documents/new-document-dialog.tsx b/apps/web/src/features/documents/new-document-dialog.tsx index 2a02883cd..59beccfbb 100644 --- a/apps/web/src/features/documents/new-document-dialog.tsx +++ b/apps/web/src/features/documents/new-document-dialog.tsx @@ -282,7 +282,7 @@ export function NewDocumentDialog({ data }: { data?: NewDocumentDialogData | und const file = event.dataTransfer.files[0]; if (file) void importFile(file); }} - className="flex items-start gap-4 rounded-xl border-[1.5px] border-line-2 border-dashed p-5 text-start transition-colors duration-quick hover:border-accent hover:bg-accent-soft" + className="flex items-start gap-4 rounded-xl border-[1.5px] border-line-2 border-dashed p-5 text-start transition-[background-color,border-color,scale] duration-quick ease-enter hover:border-accent hover:bg-accent-soft active:scale-[0.98]" > @@ -420,7 +420,7 @@ function ChoiceTile({ icon, title, description, onClick, disabled }: ChoiceTileP type="button" disabled={disabled} onClick={onClick} - className="flex items-start gap-3 rounded-xl border border-line p-4 text-start transition-colors duration-quick hover:border-line-2 hover:bg-hover disabled:opacity-60" + className="flex items-start gap-3 rounded-xl border border-line p-4 text-start transition-[background-color,border-color,scale] duration-quick ease-enter hover:border-line-2 hover:bg-hover enabled:active:scale-[0.97] disabled:opacity-60" > @@ -578,7 +578,7 @@ function CopyForJob({ initialSourceId, initialJobId, onBack, onCreated }: CopyFo setName(null); }} className={cn( - "flex h-8 items-center gap-1.5 rounded-full border px-3 text-[13px] transition-colors duration-quick", + "flex h-8 items-center gap-1.5 rounded-full border px-3 text-[13px] transition-[background-color,border-color,color,scale] duration-quick ease-enter active:scale-[0.97]", jobId === option.id ? "border-accent bg-accent-soft text-accent-text" : "border-line-2 text-ink-2 hover:bg-hover", diff --git a/apps/web/src/features/resume/editor/design/style-groups.tsx b/apps/web/src/features/resume/editor/design/style-groups.tsx index b8405313c..a1390c86f 100644 --- a/apps/web/src/features/resume/editor/design/style-groups.tsx +++ b/apps/web/src/features/resume/editor/design/style-groups.tsx @@ -182,7 +182,7 @@ export function ColorGroup() { value={accent.hex} aria-label={accent.label} title={accent.label} - className="aspect-square cursor-pointer rounded-full transition-shadow duration-quick data-checked:shadow-[0_0_0_2px_var(--surface),0_0_0_4px_var(--swatch)]" + className="aspect-square cursor-pointer rounded-full transition-[box-shadow,scale] duration-quick ease-enter active:scale-[0.97] data-checked:shadow-[0_0_0_2px_var(--surface),0_0_0_4px_var(--swatch)]" style={{ backgroundColor: accent.hex, "--swatch": accent.hex } as CSSProperties} /> ))} diff --git a/apps/web/src/features/resume/editor/design/template-group.tsx b/apps/web/src/features/resume/editor/design/template-group.tsx index eeff46619..bccb4b077 100644 --- a/apps/web/src/features/resume/editor/design/template-group.tsx +++ b/apps/web/src/features/resume/editor/design/template-group.tsx @@ -190,7 +190,7 @@ function TemplateCard({ id, data, selected, onPreview }: TemplateCardProps) { > diff --git a/apps/web/src/features/settings/preferences.tsx b/apps/web/src/features/settings/preferences.tsx index 48eea77d6..fc205d8cf 100644 --- a/apps/web/src/features/settings/preferences.tsx +++ b/apps/web/src/features/settings/preferences.tsx @@ -73,7 +73,7 @@ function ThemeTiles() {