Arc
ComponentsBlocksDocsPricingTry the demo
Get Pro
Introduction
Installation
Theming
Motion
AI and MCP
Changelog
Metrics dashboardPro
KPI drilldownPro
Metric explorerPro
Revenue explorerPro
MRR waterfallPro
Cohort retentionPro
Usage forecastPro
Journey flowPro
Uptime statusNewPro
Choropleth explorerPro
Connected scatterPro
Horizon chartPro
Account healthNewPro
Market terminalPro
Budget variancePro
Small multiplesPro
Line replayPro
AI chatPro
AI composerPro
AI answerPro
Model pickerPro
Model arenaPro
Prompt studioPro
Document extractionPro
Agent memoryPro
AI side panelPro
Research runPro
AI insight cardNewPro
Catch upNewPro
AI feature launchNewPro
AI search barNewPro
AI setup wizardNewPro
Call insightsNewPro
Lead scoringNewPro
Agent runPro
Agent tasksPro
Agent approvalsPro
Agent routinesPro
Agent orchestratorPro
MCP serversPro
Knowledge basePro
Eval suitePro
Agent builderNewPro
Agent galleryNewPro
SidebarPro4
Page header
Command palette
Notification center
Selection toolbarPro
Empty states
Search resultsPro
Login and sign up5, free and Pro variants
Onboarding illustrationPro
OTP input
Multi-step formPro
Two-factor setupNewPro
Magic linkNewPro
Settings pagePro
Settings commandPro
Security settingsPro
Billing overviewPro
Usage billingPro
Cancel flowPro
Onboarding surveyNewPro
Spend alertNewPro
Team membersPro
Invite peoplePro
Team directoryPro
Roles and permissionsPro
Profile pageNewPro
API keysPro
WebhooksPro
IntegrationsPro
Environment variablesPro
Domain verifyNewPro
Webhook testerNewPro
Plan comparison
Pricing calculatorPro
Usage pricingPro
Cart drawerPro
Checkout summaryPro
Live checkoutPro
Seat managerNewPro
Credit top-upNewPro
Invoice studioPro
Wallet cardPro
Delivery trackerPro
Product listingPro
Product detailPro
Activity feedNewPro
Inbox triagePro
Support conversationPro
Support widgetPro
Help centerPro
Feature votingNewPro
File upload
Media playerPro
Week calendarPro
Availability pickerPro
Project boardPro
Release readinessPro
Kanban boardPro
Smart schedulerNewPro
Task breakdownNewPro
Goal trackerNewPro
Hero section
Hero signupPro
Scroll storyPro
Spotlight gridPro
Feature bentoPro
Comparison table
Logo marquee
Studio perspectivesPro
Stats band
Changelog feed
FAQ section
Contact section
Team showcasePro
Blog grid
Site header
Site footer
CTA section
Newsletter signup
Activity terrainPro
Revenue globePro
Customer galaxyPro
Semantic zoomPro
Layout morphPro
Exploded viewPro
What’s new74 new
BlocksCatch up

Catch up

Pro

A catch me up digest for when you return, where one button reads Slack, Linear, GitHub and Gmail for the range you pick and streams back a short ranked summary: Needs you, Decisions made, Shipped and FYI. Each item is one sentence with its source mark, people and a jump link, and marking items as read clears them with a smooth collapse.

Live block · sample data

When to use

  • A home or inbox screen that summarizes what happened across connected tools while the user was away.
  • An AI assistant feature that turns hundreds of notifications into a short ranked list with jump links.
  • A weekly or daily digest preview inside a product's notification settings.

When not to use

  • A live notification feed where every event matters; use a plain activity list instead.
  • A long-form report or meeting summary with paragraphs; use a document view or ai-chat.
  • Approving agent actions; use agent-approvals.

Installation

Pro source and install commands unlock with a Pro plan.

Usage

Drop it on a home or inbox screen for the moment someone comes back. Pass `generate(range, signal)` returning `CatchUpItem[]` (id, section, source, one-sentence text, context, when, people, href) and abort when the signal fires. Pass `counts` keyed by range for the per-source totals shown before it runs, plus `onOpen` and `onMarkRead` to wire jump links and read state. `ranges`, `range`/`onRangeChange`, `model` and `title` are optional. With no props it plays a simulated three-day digest once it scrolls into view.

example.tsx
1import { CatchUp } from "@/components/arc/blocks/catch-up/catch-up";2 3export function ReturnDigest() {4  return (5    <CatchUp6      generate={async (range, signal) => {7        const response = await fetch(`/api/digest?range=${range}`, { signal });8        if (!response.ok) throw new Error("Gmail did not respond. Try again in a minute.");9        return response.json();10      }}11      counts={{ "1d": { slack: 31, linear: 9 }, "3d": { slack: 86, linear: 31 }, "1w": { slack: 214, linear: 77 } }}12      onOpen={item => window.open(item.href, "_blank")}13      onMarkRead={ids => fetch("/api/digest/read", { method: "POST", body: JSON.stringify({ ids }) })}14    />15  );16}
Built fromButtonSegmentedControlTextShimmerTooltip

API reference

2 parts. The first is the root.

CatchUp

A catch me up digest card. One button reads Slack, Linear, GitHub and Gmail for a time range and streams back a prioritized summary in four sections: Needs you, Decisions made, Shipped and FYI. With no props it plays a simulated three day digest.

PropTypeDefaultDescription
generate(range: string, signal: AbortSignal) => Promise<CatchUpItem[]>–Builds the digest for a range. Abort the request when the signal fires (Stop, a new range, unmount). Leave it out to play the built in sample digest, which reads nothing.
rangesCatchUpRange[]1 day, 3 days, 1 weekOptions in the time range selector: { value, label, since }. The label also fills the button ("Catch up on 3 days") and since fills the summary line.
rangestring–Controlled range value. Pair with onRangeChange.
defaultRangestringsecond rangeStarting range when uncontrolled.
onRangeChange(range: string) => void–Called when the range changes. A digest that is already showing rebuilds for the new range.
countsRecord<string, Partial<Record<CatchUpSource, number>>>sample countsUnread updates per source, keyed by range value. Shown before the digest runs and summed in the summary line.
onOpen(item: CatchUpItem) => void–Jump to an item in its app. Without it, items with an href open in a new tab, and items without one show a simulated notice.
onMarkRead(ids: string[]) => void–Called with the ids marked as read, one item at a time or all at once from Mark all as read.
model{ name: string; mark?: ReactNode }Claude Haiku 5.5The model that writes the digest, shown in the footer.
titlestring"Welcome back"Card title.
autoStartbooleantrue without generateRuns the digest once when the card first scrolls into view.
classNamestring–Extra class on the root card.

CatchUpItem

One digest line.

PropTypeDefaultDescription
idRequiredstring–Stable id, passed back to onMarkRead.
sectionRequired"needs-you" | "decisions" | "shipped" | "fyi"–Which section the item belongs to. Sections show in this order and hide when empty.
sourceRequired"slack" | "linear" | "github" | "gmail"–Source app, drawn with its real mark.
textRequiredstring–One sentence. It streams in a few words at a time.
contextstring–Where it happened: a channel, issue, pull request or thread.
whenstring–Short time label, such as "Sun 13:10".
people{ name: string; avatar?: string }[]–People involved. Up to three faces show, with the first name and a count.
hrefstring–Jump link to the item in its app.

Keyboard interactions

Tab
Moves through the range selector, each item's open and mark as read buttons, then the footer action.
Arrow keys
Move between time ranges in the selector.
EnterorSpace
Runs the digest, stops it, opens an item, or marks it as read.

Accessibility

  • A polite live region announces each phase: reading, digest ready with the item count, marked as read with the count left, and all caught up. The sample adds that it is simulated and nothing was read.
  • Sections are labelled regions with a heading that includes the count, and each sentence starts with its source name for screen readers.
  • Rows that have not streamed in yet are hidden from assistive tech and their buttons are out of the tab order.
  • After marking an item as read, focus moves to the next item's mark as read button, or to the footer action when the list is clear.
  • Status is never color alone: sections pair an icon with a label, and the reading state uses a spinner then a check per source.

Motion

  • The digest streams four words every 34ms; each chunk only fades in. Rows reserve their full height up front behind quiet skeleton bars, so nothing shifts while text streams.
  • Switching between sources, digest and outcome is one crossfade (100ms out, 160ms in) while the card height springs to the new size with no bounce.
  • Mark as read collapses the row's height and opacity in 200ms; an emptied section collapses the same way. The card follows the collapse frame by frame instead of chasing it with a second spring.
  • Labels, counts and the summary line swap with a single crossfade and a 2px rise. The button keeps a fixed minimum width across labels.
  • Reduced motion shows the finished digest at once, keeps crossfades as plain fades, and stops the spinner.

Responsive behavior

  • The card fills its container up to 600px. Below 440px container width the padding tightens, the range selector wraps under the title, and meta lines truncate with an ellipsis.
  • Item actions are always visible, so touch users do not depend on hover.
  • Holds at 360px and 390px viewports without horizontal scroll.

Performance

  • Streaming re-renders one small list on a 34ms timer only while text is streaming; it stops at ready.
  • Word fades run on CSS opacity transitions, not per-word motion components.
  • The sample starts once via IntersectionObserver; the spinner animates only during reading.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Use for a return or Monday morning moment: a manager or engineer comes back after time away and needs what changed, ranked by whether it needs them.
  • Keep items to one sentence written as an outcome ("API v2.14 is live with 38% faster search"), not a raw message. Put the person, channel and time in people, context and when.
  • Order is fixed by section: Needs you first. Only put items in Needs you when the reader has to act.
  • Pass generate for real data; it receives an AbortSignal that fires on Stop, a range change or unmount.
  • Sources are Slack, Linear, GitHub and Gmail. To add another, extend CatchUpSource and the marks file.
/components/blocks/catch-up/markdown

The full library index for assistants is at /llms.txt.

Related

Agent statusProComponentA compact live status pill for a running AI agent: the agent's mark in a live ring, the current activity and an elapsed timer, opening into the steps so far.Tool callProComponentA tool call row for agent transcripts: the tool's mark and the call in plain words, a live state while it runs, and the input and output a click away, with approval and retry when needed.Agent approvalsProBlockOne approval card for agents: the waiting tool call reads like a permission prompt with the tool's mark, the agent's reason and its arguments, and you approve, deny or allow it from now on.AI chatProBlockA full-screen AI chat where answers stream in as markdown with folding reasoning, tool chips and cited sources. People can switch chats and models, edit or retry a message into versions, rate replies and stop a reply mid-stream.
PreviousAI insight cardNextAgent gallery
Arc · 129 block pagesllms.txt

On this page

  • Preview
  • When to use
  • When not to use
  • Installation
  • Usage
  • API reference
  • Keyboard
  • Accessibility
  • Motion
  • Responsive behavior
  • Performance
  • Notes for AI
  • Related
View as Markdown

Welcome back

142 updates since Fri 24 Oct
  • Slack86 messages
  • Linear31 issues
  • GitHub18 PRs
  • Gmail7 threads
Claude Haiku 5.5