Two mechanisms from the sections below, running on one curve — a fill and a label, an edge and a mark. The pairing is the study: read the parts on their own first.
119Swell
Card 15's roll against a plate that grows under it. They do not fuse into one movement because they are on different axes — the label translates on Y while the plate scales — and the grow is capped at 1.03: at 1.06 the plate wins and the roll becomes something you notice afterwards.
CSSCode in FramerSubtle
123Crest
The one sequenced pairing here: card 10's sheen is delayed by exactly the duration of card 49's lift, so the light crosses the face only once the face has arrived. Played together they read as two effects on one button; played in order they read as one material catching a light it just moved into. Elevation stays lightness — bg-2 to bg-3, no shadow.
CSSCode in FramerSubtle
121Tide
Card 09's fill rising under card 20's letters, and the 26ms stagger is not decoration: it is the fill's own arrival time, sampled per letter, so each character flips just after the front has passed it. The roll is shorter than the fill, so the last letter still lands before the plate is full.
CSSCode in FramerBold
138Counter-rolling pair
Card 15's roll, run twice with opposite sign: the label lifts to its duplicate while the mark drops to its own, both across the same distance on the same curve. Every other pairing here takes two different mechanisms; this takes one and turns half of it around, which is the cheapest way to get the tension 124 names — two channels leaving the same way would be the same word said twice, and the only thing separating repetition from a pair is that one of them goes against. The plate carries the shared curve underneath, so there is one arrival and two readings of it.
CSSCode in FramerSubtle
120Lands first
The same two ingredients as 119, argued from card 52 instead: one curve, DIFFERENT rungs. The label is light and lands at 200ms; the plate is heavy and is still settling at 450ms, darkening a step as it goes. The compound is the gap between the two arrivals, and nothing rotates.
CSSCode in FramerSubtle
122Leading edge
Card 07 sweeping under card 11's arrow, with one change to the sweep: the front is an ellipse pinned to the left edge rather than a scaled rectangle, because a scaleX front is a flat vertical line and that is the one shape a wave never has. The arrow leaves by the edge the front is heading for, so the pair reads as a single movement.
CSSCode in FramerBold
124Closing marks
Card 13's marks close IN while the label grows. Marks out and label open would be two channels saying the same word twice; a frame tightening against type expanding is a tension, and that is what makes it read as one gesture. The label grows on a transform and not on tracking, because tracking changes the label's width and a hug-content button is as wide as its label.
CSSCode in FramerSubtle
Plate
The whole surface answers at once: it scales, lifts, leans, or argues with the pointer about its own weight.
41Inset fill
The plate sits an even four pixels inside its own measure and grows out to the hairline on hover, deepening a shade as it lands — on two concentric capsules a uniform inset is the only band that is provably even at every point.
CSSCode in FramerBold
126Squash and stretch
The plate is a soft mass and the area it covers is conserved — six per cent of width costs 5.6 of height, so the two multiply back to within a thousandth of where they started, which is the whole difference between this and a scale. The word takes the exact inverse and holds its size, because a 999px radius leaves no corner to watch and the gap at the end caps is the only landmark a deformation has here — without something rigid inside it, a soft mass that grows with everything in it is just a scale again. The settle overshoots through rest and squashes briefly the other way, the part a spring does and an ease-out cannot; 119 grows a plate under a label, and this is the only study here that deforms the plate itself.
CSSCode in FramerBold
43Keycap
The plate stands on a hard bottom edge like a keycap and collapses under the press.
CSSVariant in FramerSubtle
49Elevation step
The plate lights first and rises a beat later, and the label rolls over one character at a time across exactly that beat — the last letter lands on the frame the plate does.
CSSVariant in FramerSubtle
82Riser
Two legs grow from the bottom edge, the plate rises by exactly their height, and a face comes up over the top. The trailing leg lands a frame late so the button steps rather than levitates, and the line it was resting on gets drawn behind it. The only study here with an anatomy.
CSSCode in FramerBold
117Fixed shadow
Gumroad's checkout button. The plate slides up-left four pixels while the shadow grows down-right by the same four, so the shadow never moves: it is the seat the plate left. Feed the Accent swatch #ff90e8 to reassemble the shape — the seat arrives in that pink's own dark, because a seat is read against the card on one side and the plate on the other, and a grey one measured 1.17:1 against this plate.
CSSCode in FramerBold
140Answers back
Two faces on one hinge inside a single perspective: the front turns 85° away and up out of it while the back comes from −90° to flat. 34 and 104 are called flips and neither moves — they swap a light source on press — so this is the only study here where the plate has a back at all. What is written on that back is the study: it does not repeat the front, it answers it, and the objection the label raises is gone by the time the turn finishes.
CSSCode in FramerBold
116Stack fan
The plate lifts and three more fan out beneath it. They are plates and not shadow — three steps of one tone, drawn by one property at the plate's own radius, so depth is still stated as lightness. The tone follows the picked colour and lands where the grey did.
CSSCode in FramerSubtle
147Turns over
A closed prism, not a flip: two faces 45px apart and a floor hinged at the bottom edge, turning a half circle. Every face carries the same word, so nothing is revealed — an object simply tumbles. It has no roof, which is the point: mid-turn you are looking down into an open container. Recreated from Item-Box on tiny-mighty-buttons.webflow.io, whose geometry and easing this keeps.
CSSCode in FramerBold
148Counts its turns
147 always comes back. This one adds a roof, puts a different word on each of the four faces, and advances exactly a quarter turn per hover without returning — so the button holds its state in its geometry rather than in a class. The square profile is what makes it legal: at 45px deep against a 45px face, a quarter turn presents a face the same size as the one it replaced.
CSS + JSCode in FramerBold
149Stops halfway
147 passes through 90° in about 200ms and never lets you see it. This stops there: hover holds the box open with the floor face square to you, and press finishes the turn. One move split across two states, so hover and press stop competing for the same rotation — the same split 129 makes between a park and a landing.
CSSCode in FramerBold
150Rounds a corner
Half a turn on X and a whole one on Y, on nested elements finishing 90ms apart, so the box goes round a corner instead of spinning on a spit. The depth is in the asynchrony. Two axes means two elements — one element cannot carry two transforms on two clocks — and only X keeps the overshoot, because two bouncing axes read as a wobble.
CSSCode in FramerBold
50Magnetic
The button is drawn toward the pointer on a critically damped spring; the label follows with extra parallax.
JSCode in FramerBold
130Loose label
50 draws the whole button toward the pointer and lets the label parallax a little further. Turned inside out: the plate is nailed down and only the word drifts, capped at five pixels across, which stops the button being the thing attracted and makes it a frame the label is loose inside — a different feeling, not a smaller one.
CSS + JSCode in FramerSubtle
52Two masses
The arrow and the label leave at the same instant and travel the same distance at different rates, so the light one arrives first and the pair closes up by two pixels before the heavier label lands and restores the gap.
CSSCode in FramerSubtle
131Two targets
The plate answers which half of itself you are on, and it reads that from structure rather than from coordinates: :has() asks which child is hovered. 09, 75 and 111 all measure where the pointer is and hand CSS the number; this needs no number and no script at all, because the question is not where but which of these two.
CSSCode in FramerBold
136Grows its word
Card 128 opens the plate for a mark that arrives; this opens it for a word that was there all along, clipped to no width. It is the second study allowed to re-measure, and for the same reason: the silhouette change is the subject, so nothing here can be faked with a transform. The radius resolves against the live height, so the button is a true pill at both widths instead of changing shape family on the way out.
CSSCode in FramerBold
143Tightens
136 grows a plate until it fits a word. This closes one down onto it: the surface turns a corner toward you, gives up its radius from a pill to 6px, and draws in symmetrically until it is the label plus one step — 20px of padding to 8px — so the close has a destination it can reach rather than a distance it was told to travel. The label rides the tilt, because it is printed on the surface, but it does not follow it home: it hops out through the top and back in from the bottom while the plate is still moving, and the two things are on different clocks on purpose. Take the pointer away and the word hops the other way — out through the bottom, back in from the top — because the swap is two copies on transitions rather than one node on a keyframe, and a keyframe that only exists on hover has no way out at all.
CSSCode in FramerSubtle
146Only the ends are pixels
137 rasterises the whole plate; here the raster is confined to the two end-caps, so what changes is the SILHOUETTE. The plate withdraws to its label 11px at a time, the box holding its size and the label its place, and the cells ghost rather than switch off, so the shape given up stays readable behind the one kept. 143 tightens by re-measuring its padding; this tightens with nothing moving at all.
CSSCode in FramerBold
86Hairline only
One property moves and nothing travels — the least a button can do and still answer, with the house press doing the rest. The floor of the set, and of the page. Not in the library: it is here as the reference the other studies are measured against rather than as a button to drop into a page, so it hands over CSS and nothing else.
CSSVariant in FramerSubtle
Fill
A fill arrives or leaves. What differs is where it comes from and whether you can see it travel.
07One-way sweep
The fill enters from the left and leaves to the right — it never reverses the way it came. One fixed direction, and that is the point: card 75 is the one that reads which edge the pointer crossed.
CSSCode in FramerBold
75Directional fill
The fill enters from whichever of the four edges the pointer actually crossed, and leaves by the opposite one.
CSS + JSCode in FramerBold
129Takes turns
The fill enters from a different edge on each pass, cycling left, top, right and bottom, and leaves by the opposite one. 75 reads the edge the pointer actually crossed; this reads nothing — the order is authored, which is 25's argument moved from letters to edges, and it gives the button a rhythm of its own instead of a reflection of how you came at it.
CSS + JSCode in FramerBold
08Shutter
The fill comes down from the top edge and rolls back up to it. The anchor is the whole card: 07 sweeps across on one axis and this drops on the other, and a shutter that opened from its own middle would be a curtain.
CSSVariant in FramerBold
09Ink fill
The fill grows from the exact point where the pointer entered — and retreats to where it left. The radius is measured to the farthest point of the plate from that point, so the ink lands exactly as the transition ends rather than nearly: a guessed radius overshoots by a different amount on every plate width, and spends the slow tail of the ease off-screen. The plate is a stadium, so the measurement is to its outline and not to the corners of its box.
CSS + JSCode in FramerBold
111Press fill
The plate shrinks two per cent and drops half an elevation step as the pointer arrives, so the press has an approach rather than a start; the flood then runs from the point you pressed — the one study here you can call off: drag off the plate and it retracts, release outside and nothing happened. Card 74 times the press; this one places it.
CSS + JSCode in FramerBold
135The plus is the source
Every other fill on the page starts at the pointer or at an edge. This one starts at the mark: the bloom opens from the centre of the plus and spreads outward, so it arrives the same way whichever side you come in on, and the origin is derived from the padding and the mark rather than typed as a number. The polarity follows the front, which is why the plus turns first and the label a beat later.
CSSCode in FramerBold
91Stepped fill
Six columns rise on a stagger, so the fill arrives with a jagged leading edge and resolves flat. It does not retract: on the way out it collapses toward the ceiling, last column first. Blocks arriving, not a front moving.
CSSCode in FramerBold
139The wash outlives the fill
Two tilted panels sweep up under the label 64ms apart, so the fill arrives as one gesture in two stages: the first is only the wash that announces it, the second is the one that stays. 91 steps a fill in visible units along the same edge; this splits it across two panels that never share an edge. The exit is where it argues — the delay is stated in BOTH rules, so leaving, the fill goes first and the wash it arrived under is the last thing off the plate. A Framer gesture variant has no way to say that: its exit is always its entrance played backwards.
CSSCode in FramerBold
137Pixel dissolve
The plate is a raster and the fill arrives cell by cell rather than as a front: twenty-four cells, eight by three, each waiting its own turn. The order is authored, not random — cell i goes at rank (i × 7) mod 24, and because 7 is coprime with 24 no two neighbours hold neighbouring delays. That is card 25's argument moved from letters to a grid, and 91 is the nearest fill: it arrives in visible units too, but in six columns that still read as a front. The leave is the same order compressed to a fraction of its spread, so the plate dissolves out the way it came instead of clearing in one frame. The label rolls a third of that spread behind the raster, and it is blended rather than timed: 91 reveals a twin in the fill’s colour in the same six steps its fill arrives in, but a twin has to be clipped against a front and a raster has none, so at every moment the word covers cells on both sides of the flip. Difference resolves that per cell.
CSSCode in FramerBold
Edge
The outline does the work and the plate holds still: an underline, a rule, a drawn border, a corner that changes shape.
14Directional underline
In from the left, out to the right — the line never snaps back.
CSSCode in FramerSubtle
39Centre underline
The rule grows from the centre of the word and retreats to it. Card 14 flips its origin so the underline arrives from one side and leaves by the other; with no direction to read, this underlines the label.
CSSVariant in FramerSubtle
57Real underline
The browser's own underline thickens and rises toward the baseline, so skip-ink keeps clean gaps around the descenders the whole way through.
CSSCode in FramerSubtle
55Rule bend
The rule under the label deflects four pixels, like a beam under load, and comes back straight — the path itself is interpolated rather than a bent shape being scaled.
CSSCode in FramerBold
13Crop marks
Register marks land in the corners, as on a press sheet.
CSSVariant in FramerSubtle
42Edge light
A streak of the primary circles the hairline for as long as the pointer stays, and holds its place when it goes. It travels the outline, not an angle: a conic gradient crosses the caps 11.6 times faster than the flanks.
CSSCode in FramerSubtle
28Chamfered corner
The chamfered corners unfold and the rectangle becomes whole.
CSSCode in FramerSubtle
98Cell chamfer
Card 28 unfolds a chamfer along a straight diagonal; at bitmap resolution the same corner can only leave as whole cells, two of them, in two steps. The one card here the toolbar's radius cannot reach.
CSSCode in FramerSubtle
Label
The word performs: as one piece, so the button can change what it says without changing size — then split, so the characters can move apart.
15Label roll
The label rolls up and its duplicate takes its place from below — and the plate opens a slot for an arrow that arrives one delay behind it, so the room is made before anything is in it. Cards 20 and 23 do the same roll per character and per word; neither can open a slot, because ten characters have nowhere to open one between them. That is what this card is for.
CSSCode in FramerSubtle
127Arc swap
The swap travels an arc rather than a rail: both copies pivot ten line-heights below the baseline, so one rotation of five degrees carries the sideways drift and the tilt as consequences instead of as two more properties timed to agree with it. 15 is this gesture on a straight line and 70 pivots the mark; this pivots the word, and the ground draws back three pixels behind it while the border stays where it is.
CSSCode in FramerBold
19Overflow only
The label moves only if it is actually too long for the plate; if it fits, nothing happens at all.
CSS + JSCode in FramerBold
30Counter
The counter wakes and steps up to today's number.
CSSCode in FramerBold
20Letter roll
Card 15's gesture resolved per character: each letter leaves through the top of its own box while its duplicate arrives from the bottom, 26ms apart. An identical label replaces the one that left.
CSSCode in FramerBold
23Word roll
The same roll with the unit changed, and the answer to who would actually ship this. Four words reading themselves out is a CTA; twenty-one characters is a wave passing over a button. Only the granularity moved.
CSSCode in FramerSubtle
21Letter lift
The same stagger with nothing masked and nothing duplicated: each character lifts 3px and returns. Here as the argument that card 20 is usually the wrong choice — a roll needs a mask, a duplicate and a deep enough box.
CSSCode in FramerSubtle
24Middle out
The same lift ordered by distance from the label's centre rather than by reading order. Both ends move last, so the word breathes from the middle as one object instead of reading as a queue being served.
CSSCode in FramerSubtle
141Bursts from the middle
20 rolls each character through its own box on a straight line. Here the pair gets a diagonal, and the diagonal is not shared: every character's direction and rotation are derived from where it sits in the word, so the label bursts outward from its own centre rather than sliding one way as a block. The stagger runs middle-out with it — 24's order, thrown — and the arrival overshoots, so the replacement lands like something dropped into a hand. It fires on pointerenter and finishes even if you leave; that one-shot is the character of it, and a hover-driven animation would snap back mid-flight.
CSS + JSCode in FramerBold
25Random stagger
The same lift with the order taken away: a fixed permutation chosen so no two neighbouring characters hold neighbouring delays. CSS has no randomness, so the disorder is authored — a surface disturbed, not a sequence played.
CSSCode in FramerSubtle
26Weight wave
The weight rises in the characters nearest the pointer and ebbs once it has passed — the typography answers, nothing moves.
CSS + JSCode in FramerSubtle
85Nervous type
Every letter tilts on its own timing, so the word never settles. Card 26 also works letter by letter, but it moves weight and only where the pointer is; this moves geometry everywhere at once, and reads as hand-drawn.
CSSCode in FramerBold
142Each letter keeps its area
126 conserves the area of the plate; this conserves the area of a glyph. Each character compresses to .72 of its height and is charged 1.389 of width for it, so the two multiply back to within a ten-thousandth of where they started and the letter fattens as it flattens — the difference between a squash and a scale, at the one scale small enough that you read it as the type moving rather than the button. 26 and 85 change the characters in place too, but neither pays for what it takes. A tone pulse rides the same 700ms clock rather than one of its own, so the colour is part of the squash and not a second event happening near it.
CSS + JSCode in FramerBold
144Hinged at the first letter
Every swap here pivots on something the whole word shares: 15 rails it, 20 rails it per character, and 127 pivots ten line-heights below the baseline so the word tilts as one rigid object. This hinges on the word’s OWN LEFT EDGE, so travel is proportional to each character’s distance from the start — the C barely moves and the k at the end swings through nearly fifteen pixels. The word that arrives is the same word, so there is nothing to read but the motion, and rotation is the only channel: no lift, no drift, no tracking. Sixteen degrees is the angle at which the filled version still holds it — measured on the plate, the outgoing copy stays inside by seven pixels.
CSSCode in FramerSubtle
80Resolve
The label churns and locks in left to right, drawing only on its own characters, so the button never shows a glyph that does not belong to it.
CSS + JSCode in FramerBold
Mark
A small mark beside the label carries the gesture: an arrow travels, an icon redraws itself, a caret points.
11Arrow relay
The arrow leaves to the right and its twin takes over from the left, and the plate grows four per cent and shades down behind them. The growth is on the background alone — scaling the button would take both arrows with it, and the arrows are the study.
CSSVariant in FramerSubtle
12Dot to arrow
The dot that marks rest gives way to the arrow that marks action — in the same fixed slot, so nothing in the layout jumps.
CSSVariant in FramerSubtle
145One dot, five times
12’s dot marks rest and gives way to the arrow in a fixed slot. This one does not give way. There are five dots in that 3px box at rest, stacked exactly, and one length pulls them apart: each dot’s place is its index times THE SAME NUMBER, signed for the vertical and folded for the horizontal. So the chevron is not a second glyph, it is the dot at a different value, and the mark travels BETWEEN shapes rather than being swapped for one. Tiny Mighty’s arrow-dots computes its head the same way and then draws it once; the number is what is animated here, which is also why one control in Framer can hold the whole set.
CSSCode in FramerSubtle
69Clipped relay
One capsule with two windows, and only their contents move: the arrow exits the right edge and the next enters from the left, while the label rolls up out of the top and its next copy arrives from below. Each window advances its content the way that content reads. Neither comes back — every pass advances the cycle, the one study with no exit.
CSS + JSCode in FramerBold
59Exit velocity
The mark's way home is handed the pointer's exit velocity, so a quick sweep away carries it about two and a half pixels past rest before it settles and a slow drift simply eases home. It rests as a ring and fills as it goes, so it reports its state as well as its travel.
JSCode in FramerSubtle
78Corner exit
Card 09's fill, taken off the pointer and pinned to the corner the mark points at: the plate fills from the exit while the mark leaves by it, so the pair is two directions on one diagonal rather than one said twice — the trap card 124 names. The mark still only rotates. It used to lift and then leave along the line it was now pointing down, three properties arguing that the turn and the travel were one statement, where they read as two things happening to agree. The label's colour waits one beat and the mark's does not, because the mark is standing where the fill starts.
CSSCode in FramerBold
92Changes sides
The mark starts left of the label and finishes right of it, crossing rather than going around — the position card 79 declines to take. It stays lit the whole way and shrinks as it passes the letters.
CSS + JSCode in FramerBold
67Mark walk
The two pieces exchange places: the mark crosses the whole label to the far end while the plate slides into the slot it vacates. Card 92 walks a bare icon; this is one solid mass crossing another.
CSS + JSCode in FramerBold
128Buds a mark
The silhouette changes. The plate opens a slot for the mark — padding carries 28 to 48 pixels — and the disc scales up one delay later, so the room is made before anything arrives in it; at 33 pixels inside a 45 pixel plate it keeps six pixels of plate on three sides and stays contained by the button rather than bolted to its edge.
CSSCode in FramerBold
100Plus to X
A plus becomes an X without passing through a single angle: four cells step one place around the centre, 26ms apart, and the fifth is already where it needs to be. Nothing rotates; the mark is redrawn.
CSSVariant in FramerBold
93Pieces join
The mark's own plate closes the gap and the two facing corners give up their radius, so what were two objects read as one.
CSSCode in FramerBold
66Split apart
Card 93 read backwards: this one arrives joined and comes apart. The same gap and the same two corners, arguing for separation rather than for one object.
CSSVariant in FramerBold
97Grid steps
The mark crosses twelve pixels in three jumps of four and the label makes room in one, so the button is never between two positions. The exact argument section L is built to deny.
CSSCode in FramerBold
54Anticipation
The arrow winds a pixel and a half backwards before it goes — one easing whose curve dips below zero, nothing more.
CSSCode in FramerSubtle
79Optical centre
The mark's space is reserved from the start, so the label alone reads as centred until the mark arrives.
CSSVariant in FramerSubtle
Material
The button behaves like a physical thing — lit, glazed, printed, knurled or cut — and hover changes the material, not the layout.
04Bloom
The first light on this page that leaves the plate. Cards 31 and 42 both work inside the boundary; this spends its light outward, the only way to say brighter on one grayscale.
CSSVariant in FramerSubtle
05Inner light
Light gathers along the bottom edge on hover and floods the whole plate on the press, instead of the plate pushing down. Card 43 answers the press with depth; this answers it with energy, the other thing a physical control does when you close it.
CSSVariant in FramerSubtle
34Light flip
The plate is lit from the top left, and pressing it moves the light to the bottom right. Nothing travels — the four edges stay where they are. Cards 43 and 86 are also press-only, but neither moves the light.
CSSVariant in FramerSubtle
109Fixed light
A plate lit from above, with the flood passing underneath the light rather than over it — so the surface changes colour without changing material. The first study here to light the face rather than its edges.
CSSCode in FramerSubtle
10Sheen
A soft light crosses the dark surface, once per hover.
CSSVariant in FramerSubtle
31Frosted glass
The glass materialises: the blur grows in as the surface tints up and a light edge catches along the top.
CSSVariant in FramerSubtle
36Sprite swap
Rest, hover and press are three flat sprite frames and the swap between them is the whole effect — plate, type and stair changing in one paint. The only study with no transition, and the argument against this page's second rule.
CSSCode in FramerBold
104Bevel flip
Two light sources, four edges, and the pair swapping the instant you press. No hover state at all and no transition anywhere — and it still reports what it is doing faster than anything else on this page.
CSSVariant in FramerSubtle
State
These answer the click rather than the pointer: the button takes an instruction and reports on it in place, with no spinner and no second surface.
72Status button
The button takes the instruction and reports on it in place, with no spinner. Every state change is the same move — one row of the label rolling upward, the check riding the row it belongs to — and the plate takes the impact as the bar hits the end. Card 83 is the other loop you start by acting, but that one is bound to a hover; this one ends when the work does.
CSS + JSCode in FramerBold
73Plate to check
The plate closes to a disc the height of the button and the check draws itself inside it. Card 80 stays a button the whole way; this one spends the plate, so the button becomes the confirmation.
CSS + JSCode in FramerBold
74Hold to confirm
Press and hold; let go early and nothing happens. Cards 86 and 43 answer the instant of contact — this is the only study that makes the duration of the press the input, putting the friction in the gesture.
CSS + JSCode in FramerBold
83Working state
The mark turns a quarter and a dashed ring runs around it. A loop that is already running when you arrive gives up the moment you point at it; this is the loop that starts because you pointed.
CSSCode in FramerBold
Row
These need siblings to be read. Hovering one changes the others, so the row is the unit and a single button shows nothing.
60Others recede
Nothing is added to the item you are pointing at — the rest of the row simply stops competing with it.
CSSCode in FramerSubtle
62Conserved compression
The item you point at takes twenty-four pixels and its two neighbours give up twelve each, so the row's width is unchanged by construction rather than by rounding.
CSSCode in FramerSubtle
63Repulsion
The neighbours step away from the item you point at, five pixels for the ones beside it and two for the ones beyond, and the item itself holds still.
CSSCode in FramerSubtle
151Weight budget
The row is allowed sixteen hundred units of weight and no more, so the item you point at can only reach 650 by the other three dropping to 317 each. The cells are fixed, which is what keeps the conservation honest: the debt is settled in ink and the layout never learns about it.
CSSCode in FramerSubtle
152Radius budget
Forty-eight pixels of corner, shared four ways. The one you point at rounds to twenty-four — half its height, where the plate becomes a true pill and past which nothing further happens — and the other three square off to eight.
CSSCode in FramerSubtle
153Gap budget
Card 62 moved the items and left the gaps alone. This moves only the gaps: the two flanking the one you point at open, the rest close, and because every item is a flex track inside a fixed-width row the outer edges cannot move to pay for it.
CSSCode in FramerSubtle
154Lever
The row is one rigid body pinned at its middle. Point left of centre and the whole row tips left, by an angle taken from how far off centre you are — the ends travel most, the pivot not at all, and nothing is added to any button.
CSSCode in FramerSubtle
155Elevation trade
There is one raise in the row and only one button may hold it. Taking it presses the other three into the card, so the lift is paid for locally rather than added on top — four buttons lifting at once would be four objects, and this stays one surface with a dent in it.
CSSCode in FramerBold
156Depth of field
The row has a focal plane and the item you point at is on it. Every other edge takes blur by how far it sits from you, so the row reads as one photograph refocusing. The words stay sharp on purpose: a blurred glyph cannot hold its contrast, and there is no blur small enough to both pass and be seen.
CSSCode in FramerSubtle
157Fan
Every button rotates about the same origin, eleven heights below the row, so the angles splay instead of each one spinning in place. Sign comes from which side of you a button sits on and magnitude from how far — a hand of cards opening away from your thumb.
CSSCode in FramerBold
158Stiff beam
The inverse of every other falloff here: the row is clamped at both ends, so each button’s deflection is its own compliance times its proximity to you. Point at the middle and the row gives; point at an end and almost nothing happens, because that end is held.
CSSCode in FramerSubtle
161Icon to label
Four squares at rest, and the one you point at grows to say what it is. The growth is paid for out of the row’s trailing space rather than out of its neighbours, which is the honest version — a real toolbar has that space, and pretending the neighbours shrink would be card 62 wearing a different hat.
CSSCode in FramerSubtle
162Fanned deck
At rest the buttons overlap by twenty pixels — as far as the plate’s own padding allows before a label slides under its neighbour — stacked front-to-back, so the row reads as a held deck and only the first label is fully clear. Entering the row anywhere spreads the whole deck; only then does the one you are on come forward. The deck needs about four hundred and ninety pixels of card to open into — four plates side by side are wider than a narrow card, so below that the spread is held and only the lift runs.
CSSCode in FramerBold
159One plate for the row
Card 61 slides a rule under the row; this slides the plate. There is exactly one filled surface, the four buttons are outlines with text in them, and the plate takes each target’s width and its radius on the way — so the shared object changes shape to become the thing it is standing in for.
CSSCode in FramerBold
160Shared caret
One caret above the row slides to whatever you point at, and it leans back the way it came — travelling right it tips left for the length of the journey, then rights itself on arrival. So the row says not only where you are but which direction you got there from.
CSS + JSCode in FramerSubtle
61Travelling rule
One rule serves the whole row and slides to whichever item you point at, taking that item’s own width as it goes rather than a fixed quarter of the row, and parking back on the current one when you leave.
CSSCode in FramerSubtle
65Divider yields
The two hairlines touching the segment you point at stand down, so it reads as lifted out of the row rather than tinted inside it.
CSSCode in FramerSubtle
64Emphasis trade
Emphasis is a fixed quantity, so the secondary can only take it by the primary giving it up — point at the outline and the two trade places.
CSSCode in FramerBold
132One light for the row
One source lights the whole row, so a button you are not pointing at is still lit if its neighbour is. Give every button its own lamp and the row reads as four separate objects; here the four share a coordinate space, and what changes between them is only how far each one sits from the light.
CSS + JSCode in FramerSubtle
134Handover
Card 75 reads the edge one button was crossed at; this reads the edge between two of them. Sweep the row and each fill enters from the side you arrived on while the one you left drains toward the side you are heading for, so four buttons answer as one continuous movement rather than four separate ones. Sweep back and the whole row reverses with you.
CSS + JSCode in FramerBold
133The row that doesn’t fit
The other six rows on this page assume every item is on screen. This one is wider than what holds it, which is what a filter row actually looks like on a phone: the end of it goes under a mask, and pointing at the last stretch of track advances the row by exactly one item. The mask is a mask and not a gradient painted in the card colour, so the row keeps working on any ground you drop it on.