AddThisFeature

Countdown Timer

A live countdown to a deadline that ends cleanly instead of running negative.

simple UI & Polish

What it adds

A countdown component driven by a server-provided deadline, with a defined finished state.

What your agent is told to do

5
  1. 1

    Send the deadline and the server's current time together, compute the offset between server and device once, and count against the corrected value. The device clock cannot be trusted to be right.

  2. 2

    Recompute the remaining time from the corrected clock on every tick rather than decrementing a stored number, so a suspended tab does not resume showing a value minutes behind reality.

  3. 3

    Define the finished state explicitly: what the component shows at zero, whether it reveals something, disables a control, or triggers a refetch. Reuse the app's existing Progress Indicator System styling rather than introducing new type and colour for the digits.

  4. 4

    Reserve the widest layout the digits will ever occupy so the surrounding content does not shift as the count crosses from two digits to one, or drops the hours segment.

  5. 5

    Do not treat the client countdown as enforcement. Whatever the deadline gates must be checked again on the server, because anyone can change their clock or edit the displayed value.

Edge cases it handles

8
  • A backgrounded or sleeping tab stops receiving ticks. On becoming visible again, recompute from the corrected clock and render the true remaining time rather than continuing from where the timer paused.
  • The device clock may be wrong by hours or set deliberately. Anchor to a server timestamp delivered with the page and treat the device only as a source of elapsed time since that anchor.
  • A countdown that reaches zero must switch to its finished state, not continue into negative numbers. Decide what happens at zero before building the counting.
  • Announcing every second to a screen reader is unusable. Give the timer an accessible label with the remaining time and announce only at meaningful intervals, such as at the last few minutes and at zero.
  • Stop the tick when the component is offscreen or the tab is hidden, and under prefers-reduced-motion render a static remaining time updated infrequently instead of a live ticking display.
  • A deadline already in the past when the page loads must render finished immediately, with no flash of a large positive number.
  • The unit labels and number formatting must follow the viewer's locale, and the largest unit should drop away as it empties rather than showing a leading zero for days.
  • Multiple countdowns on one page should share a single tick rather than each running their own interval.

Definition of done

9
  • The countdown is anchored to a server timestamp and is unaffected by a wrong device clock.
  • Returning to a backgrounded tab shows the correct remaining time immediately.
  • Reaching zero switches to a defined finished state and never displays negative time.
  • A deadline already past renders finished on first paint with no flash.
  • Ticking stops when the component is hidden and is suppressed under prefers-reduced-motion.
  • Remaining time is available to screen readers without per-second announcements.
  • The digits occupy reserved space and the layout does not shift as units change.
  • The feature matches the existing design system.
  • No existing functionality is broken.

Related features

How it works

  1. 1

    Copy the link

    Grab the Markdown instruction URL for this feature.

  2. 2

    Give it to your AI

    Paste it into Claude Code, Cursor, v0, Lovable — whatever you build with.

  3. 3

    It inspects, then implements

    Your agent reads your existing app first, then adds the feature to fit it.

Works with your stack

These instructions are written to adapt. They tell the agent to detect your framework, match your existing design system, and reuse what you already have — rather than assuming a particular stack.

Need it tighter than that? Customize the feature and tell it exactly what you're running.