Field notes10 min read

Why our notes hide at the screen edge

How the edge stash in Stickies by Coduo got its sizes and springs: a browser sketch, a native motion study, and the values that shipped.

By Published Updated

Stickies by Coduo, our sticky notes app for the Mac, gives every sticky two places to live. Pinned, it floats on the desktop as its own window. Unpinned, it goes to the right edge of the screen and shows only a thin strip of its colour. This post is how that edge got its numbers: which ones we tuned, which ones a design board fixed, and one behaviour we built, liked and did not ship. The app is not released yet; everything below is from the code on main.

Why put sticky notes at the screen edge at all?

Because the two placements are the whole model. The project's vocabulary file defines a sticky as existing "in exactly one of two placements, pinned or stashed", and a stashed sticky as one that "rests at the right screen edge, showing only its sliver". The sliver is meant to carry enough colour to tell one note from another and no content at all.

So a note you are not using costs you 12 points of screen width, not a window. Hover a sliver and that one card peeks out far enough to read its title and first lines while its neighbours stay slivers. Click it and it opens. Move away and it goes back.

What did the first sketch get wrong?

The first sketch got most of the numbers right and could not vouch for the motion. It was a single HTML file, committed at 22:13 on 5 September 2026 as docs/prototypes/stash-motion.html, with the right layout and most of the right numbers: 264 pt wide notes, a 12 pt visible sliver, 84 pt sliver height, 4 pt gaps, a 30 pt reveal threshold, a 100 ms hover dwell and a 200 ms leave grace.

What it could not tell us was how the stash would feel on a Mac. It ran its own spring: a hand-written integrator that steps position and velocity in 6 ms slices from an angular frequency of 2π divided by the response. The panel under the sliders says so in as many words: the browser study translates the board's spring into a physical one and "does not run SwiftUI". A spring that looks right in a browser tab is a claim about the browser.

Nine minutes later, at 22:22, the same study landed as native SwiftUI (App/PrototypeModel.swift, App/PrototypeInspector.swift, App/PrototypeView.swift). The browser sketch was retired as a design tool. It came back nineteen days later in a different role, which is further down.

What does a native motion study let you tune that a design board can't?

A native study lets you tune motion while it is moving, under your own hand. A board can annotate "spring(0.32, 0.82)" beside a dashed line, but it cannot let you grab a note halfway through that spring and feel whether the handoff is smooth. The native study's inspector opens with the instruction "Try grabbing a moving note", and every note's position is two spring axes, each holding a value and a velocity. A drag starts from wherever the spring had got to, and a retarget continues with the velocity the note already had.

The study exposes 18 values in PrototypeTuning:

GroupValueDefaultSlider range
SpringResponse0.32 s0.18 to 0.8
SpringDamping0.820.5 to 1.2
SpringPlayback speed1.0×0.2 to 1.5
Edge stashNote width264 pt200 to 340
Edge stashNote height300 pt180 to 360
Edge stashVisible sliver12 pt6 to 36
Edge stashSliver height84 pt42 to 100
Edge stashStack gap4 pt2 to 24
Edge stashMagnetic reach140 pt40 to 260
Edge stashAttraction10 pt0 to 28
Edge stashReveal threshold30 pt12 to 90
Edge stashHover intent0.1 s0 to 0.3
Edge stashLeave grace0.2 s0 to 0.4
Window fanItem spacing10 pt2 to 26
Window fanHover scale1.045×1 to 1.12
Window fanNeighbour displacement9 pt0 to 22
Window fanFan spread18 pt0 to 36
Window fanStagger0.035 s0 to 0.07

Four spring presets sit above the sliders: Board default (0.32, 0.82), Calm (0.38, 1.0), Playful (0.38, 0.65) and "Spring.swift original" (0.7, 0.7), the house values from Meng To's Spring library. Playback speed scales the simulation clock, so you can run a reveal at 0.2× and watch where it overshoots.

Two of the values are about intent, not motion. Magnetic reach and attraction make a resting sliver lean up to 10 pt toward the pointer once it comes within 140 pt of the edge, scaled by how close the pointer is horizontally and vertically. Hover intent and leave grace stop a peek from firing when the pointer only passes through the edge, and stop it from vanishing when the pointer overshoots the card by a few points.

One detail we liked: the study never stores a separate retract spring. It derives it from the reveal, with 0.875 times the response and damping raised by 0.08, capped at 1.2. At the board default of 0.32 and 0.82 that gives 0.28 and 0.90, exactly the retract spring the board specifies.

Which numbers shipped, and why those?

The board's numbers shipped. On 6 September at 09:04, a commit titled "pin board-defined motion tokens" replaced the provisional values in Sources/StickiesKit/Motion.swift, the one file every animation in the app has to go through. The provisional values had been read off the Spring library the evening before, marked as placeholders until the boards' motion specs landed:

TokenProvisional, 5 SeptPinned, 6 SeptWhere the pinned value comes from
Peek reveal0.35 s, 0.700.32 s, 0.82Board 02
Peek retract0.28 s, 1.000.28 s, 0.90Board 02
Pin pop0.40 s, 0.550.45 s, 0.88Board 03
Standard0.50 s, 0.700.70 s, 0.70Spring library house values

The reason for each value is the board. Nothing in the repo records why the designer picked 0.82 over 0.8, and we are not going to invent one. What the repo does record is how the values stay put: tests in MotionTests.swift assert the reveal, retract and pin-pop values, and the commit's evidence shows the check failing when the reveal response was changed from 0.32 to 0.33, before being restored.

The edge geometry shipped as the board drew it too, in DeckGeometry.swift: a 12 by 84 pt sliver (42 pt when the body is empty), 4 pt gaps, a 264 by 176 pt peek card, a hot zone 20 pt deep with 4 pt of vertical slop, a 100 ms enter debounce and a 200 ms retract delay. Past 7 stashed stickies the stash scrolls. Every one of those matches a value annotated on Board 01 or Board 02.

Where the study and the board differ, the shipped value is the board's. The study wakes a sliver within 30 pt of the edge and reveals the whole 300 pt note; the shipped hot zone is the board's 20 pt, and the peek is the board's 264 by 176 pt card. On 7 September the project wrote the split down as a ruling: the boards govern geometry, tints, stacking, ordering, copy and window level, and the native study "supersedes the boards for all animation and physics".

What didn't ship, and why?

Three things. The first is still planned; the second is undecided; the third is out of the product.

The physics. The shipped deck does not yet move the way the study does. In the build on main, the peek card appears in place: its offset is fixed at the screen's right edge minus 264 pt, the panel under it resizes without animation, and the reveal spring drives the card's opacity. Board 02 asks for 252 pt of travel with the height growing from 84 to 176 pt; the card does not travel yet. The per-frame spring advance that gives the study its interruptible feel has one caller today, the study itself. Porting it into the live deck, along with the magnetic lean, is an open task. The owner's word for the gap in the task file is "bland and brittle".

Fling-to-stash. In the study you can throw a note at the right edge and it stashes itself. On release, endDrag clamps the drag velocity to ±1,600 pt/s and projects where the note would coast using a 0.99 decay: current position plus velocity per millisecond times 0.99 / (1 − 0.99), which is 99 times the per-millisecond velocity. At the clamp that is 158.4 pt of coast. If the projected note would end with more than 45% of its width past the screen edge, it stashes; otherwise it settles 0.05 s of velocity further along.

None of that can run on a real sticky. The pinned sticky window sets isMovableByWindowBackground = true, so AppKit owns the drag and the app never sees a release velocity. A review on 8 September put it plainly: the setting "makes the prototype's tuned release momentum … unreachable", and the choice between owning the drag and dropping the momentum was being "decided by accident". It is still open. Today a pinned sticky drags like any other Mac window, and you stash it with its pin control.

The window fan. The study's fan, a staggered list of every note with a hover scale and neighbour displacement, has no counterpart in the app. Five of the 18 values tune something that does not exist in the product.

The fling did find a home. On 24 September the browser sketch was ported into the landing page's hero, where you can write on a sticky, drag it by its title bar and throw it at the right edge to stash it, with the same ±1,600 pt/s clamp and the same 0.99 projection. The website can have the throw because its playground keeps its own pointer history and computes the release velocity from it. The Mac app hands the sticky window's drag to AppKit and gets no velocity back.

Whose work did we build on?

Two open-source projects, both MIT-licensed and vendored into docs/reference/code/ with their licences.

The stash itself is adapted from Noty by aimen08. Its deck of notes resting at a screen edge, waking on pointer approach and opening on click is the interaction we started from. Its rest state became our stashed slivers, its per-note reveal became our peek, and its floating note became our pinned sticky. It also documented the traps we would otherwise have found the slow way: a non-activating panel that will not take typing until it is made key, a first click swallowed by an inactive app, full-screen Spaces needing the right window level, and multi-display decks that have to rebuild around display IDs rather than indices.

The spring vocabulary came from Spring by Meng To. We took only its numbers: it is UIKit-era code that does not build on macOS, and the rule in the repo is "Numbers cross; code does not." Its 0.7 and 0.7 house values are still in Motion.swift as the fallback for anything no board annotates.

Frequently asked questions

Where do stashed notes go in Stickies by Coduo?

To the right edge of the screen. A stashed sticky shows only a 12 pt wide, 84 pt tall colour sliver, stacked with 4 pt gaps and centred vertically. Stickies by Coduo stashes on the right edge only.

How long do you have to hover before a stashed sticky peeks?

100 ms inside a hot zone 20 pt deep from the screen edge, the sliver's height plus 4 pt of slop above and below. The peek retracts 200 ms after the pointer leaves both the hot zone and the peek card.

What spring does Stickies by Coduo use for the peek?

The reveal uses a SwiftUI spring with a 0.32 s response and a 0.82 damping fraction, and the retract uses 0.28 s at 0.90. Both values come from the design board for hover peek and are pinned by tests in the app's Motion.swift.

Can you throw a note at the screen edge to stash it in Stickies by Coduo?

Not in the Mac app. The motion study had fling-to-stash, but a pinned sticky's window is dragged by AppKit, which reports no release velocity, so the momentum projection has nothing to read. The throw does work in the playground at the top of the website.

Is Stickies by Coduo available yet?

No. Stickies by Coduo is not released yet. The values in this post are from the code on the main branch as of 25 September 2026.

Sticky notes in your menu bar

Stickies is not out yet. Email us and we will tell you when the download is ready.