I Built Six Animations to Emphasize the Focused Task, Then Deleted All of Them
A day of trying to make the focused task slot more visually prominent, building six different animations, deleting each one, and finally landing on an opt-in preference.
I Built Six Animations to Emphasize the Focused Task, Then Deleted All of Them
What Was Already There
When you focus a task in Fecit, it lifts out of the main list and into a dedicated pinned slot at the top. That slot already has a decent amount of visual hierarchy: a 1.5px PRIMARY300 border, a PRIMARY400 native iOS shadow halo, and a slightly different background tone from the rest of the list.
But today I had this thought: “Can I make it even more prominent?” A focused task should really shout, “This is what I should be working on right now.” It sounded simple.
It turned into a full day of building six animations and deleting every single one of them.
Attempt 1: Rotating Dashed Comet
The first idea was a comet effect — a dashed pattern traveling around the border. Reanimated + react-native-svg, AnimatedRect with an animated strokeDashoffset. The first prototype worked. “Oh, it’s spinning!” was the reaction.
Then came the endless dial-in: longer dashes, smaller gaps, fewer dashes, thinner stroke, different color, add glow, remove glow… After a while, the direction shifted to “make it feel like an outer halo.” I moved the dashes outside the item bounds, and suddenly they disappeared.
Two Hours Down a Rabbit Hole
The dashes weren’t showing up outside the item. Color issue? Stroke width? Was Reanimated itself broken? Even bright red 4px wasn’t visible. I started suspecting that animatedProps had a compatibility bug between react-native-svg 15.x and Reanimated 4.x, and switched to a requestAnimationFrame + setState JS-driven animation. Still nothing.
The culprit was overflow: "hidden" on LightSwipeable — or so I thought at first. The real culprit was one level higher: FocusedTaskWrapper, the wrapper around the focused task, also had overflow: "hidden". Even after I moved the SVG outside the list item, the upper wrapper was clipping everything outward. Worse, the “outer halo” that I’d been seeing the whole time? That was the existing native shadow of FocusedTaskWrapper, not my SVG. Two hours staring at a thing that was never rendering.
Lesson: before blaming your animation library, walk up the DOM tree and check what actually clips. And don’t mistake a preexisting effect for something you just added.
Once I restructured the components so the SVG lived outside the overflow-hidden wrapper, the rotation finally showed up.
Attempt 2: Each Dash Is a Soft Glow Dot
“Not like that — each dot should be a soft halo, shimmering.” Keep the dash pattern, but render each dash as a thick soft stroke, layered three times for diffusion. Slower rotation, ~1.8s per cycle.
“Too explicit, should blend more.” Adjust. “Clean inside, only spread outward.” Adjust. “The bottom is getting cut off.” The overflow: "hidden" legacy strikes again. Adjust.
Attempt 3: Lighthouse Beam
A single long soft arc sweeping around the border, like a lighthouse. Built it. Showed it.
“No, each individual dot should be the halo.”
I’d misread the request. Reverted.
Attempt 4: Breathing Shadow
“Let’s give up on the rotating dashes.” Switched approach: pulse the native shadow’s opacity and radius like breathing. 2s cycle, 0.3↔0.6 opacity, 8px↔14px radius. Quiet, calm breathing.
“I can tell it’s there but I have to really look.” Pushed the ranges to extremes: 0.15↔1.0 opacity, 3px↔25px radius. Faster cycle. Still too subtle. The slot’s overflow: "hidden" also clipped the shadow expansion downward, which didn’t help. Eventually: “nah, scrap this too.”
Attempt 5: Spotlight
Instead of adding to the focused task, dim everything else. Animated opacity 1 → 0.55 on the FlatList below whenever a focused task exists. The effect was clear — the focused task popped dramatically.
“Focus works, but this is gonna hurt when I’m actually managing items in the list.” Fair point. Reverted.
Attempt 6: Background Tint
Changed the focused slot’s background from NEUTRAL100 to PRIMARY50 (a faint blue wash). “Can’t see it.” PRIMARY100 (slightly stronger). “Still can’t.” Bright red as a sanity check. “Yeah, let’s not do this.”
The Realization
Six attempts taught me one thing: the focused slot was already sufficiently emphasized.
- Dedicated pinned position (physical separation from the list)
- 1.5px PRIMARY300 border
- Native shadow halo (already a subtle glow)
- Slightly different background from the list
Every visual effect I piled on top oscillated between “too subtle to notice” and “too busy to tolerate.” Moving elements, especially, don’t help concentration — they hurt it. Your eye keeps getting pulled back to the motion.
“A visual effect to help focus” might just be a contradiction. Focus is a quiet state. Static hierarchy either works or it doesn’t. Adding more is usually decoration.
Redirection: Visual → Functional
If visuals don’t solve the problem, try function. The focused task should show something useful for actually working on that task. Like elapsed time.
Except earlier the same morning, I’d actually removed elapsed time from the Live Activity because it felt pressuring. So this time, a different angle: opt-in preference.
- Default OFF (no pressure, minimal experience by default)
- Settings toggle “Show Elapsed Time” turns it on across list items + Live Activity
- If the task has a duration, count down remaining time (red + negative sign when overdue, like
-05:23) - If no duration, just show elapsed time
Fits Fecit’s “Minimal to Maximal” principle. Quiet by default. Optional depth when the user wants it.
Looking Back
After building and deleting six visual effects, the net output is one preference toggle. The code diff isn’t huge. But taking a full day to arrive at “don’t add signal — give the user a choice” felt like the right lesson, even if it was an expensive way to learn it.
A few other takeaways along the way:
- When something’s clipped, walk up the DOM tree. Check the
overflowproperty on every wrapper, one by one. Don’t stop at the obvious one. - If you see something working, verify that you are the one making it work. I spent two hours mistaking a preexisting native shadow for my own SVG glow.
- “I can’t see it” has many possible causes. Low contrast, wrong position, clipped by parent, not rendering at all — verify each one, don’t guess.
- Motion can be the opposite of focus. Focus isn’t loud. It’s quiet.
Tomorrow, something else.