capad.fyi · hero · riso, likeness first

You were right about the darkening

That was not a taste disagreement, it was a bug, and it is measurable. The old treatment ran grayscale(1) contrast(1.5) brightness(.6) and then multiplied three plates together. Your face is 50.4% saturated, so grayscale(1) threw away exactly half the colour information in it, brightness(.6) pulled the key plate down, and multiply darkened again at every layer. Skin lives in the midtones, so skin suffers most. A generic ink palette cannot fix that. Yours can.

So the palette is now sampled off the photograph rather than invented: #170f0d deep shadow, #7a4634 shadow, #b7775b midtone skin, #e4a584 light, #f8d7bc highlight. Everything below is built from those five values. Nothing is greyed out.

palette measured off face_revel pointer + drag to register full page fold, shown end to end 900px q78 · lossless alpha
1

Four ways to print him and still have a face

Same riso idea, four different relationships between "this is a screen print" and "this is a photograph of a person". All four keep hue. The question is only how much of the original survives underneath.

On your halftone objection, which was the right one. A dot screen applied to the whole image prints the face as dots, and at hero size you stop being able to read the face. T3 is the answer: put the halftone only on a shadow plate whose alpha is driven by luminance, so the dots live in the shadow masses and the skin stays continuous tone. That is how screen-printed portraits actually work — nobody halftones a face uniformly. It is a different mechanism, not a smaller dot.

T1 true tritone

Three inks, and all three are yours.
Aadarsh UpadhyaySee the work

Fully riso, zero hue loss. Three plates mapped straight onto #170f0d / #b7775b / #f8d7bc. Reads as a two-colour screen print and still reads as you. The most stylised of the four and the most honest to the medium.

T2 one warm ink

One ink, and the photograph survives.
Aadarsh UpadhyaySee the work

Maximum likeness. The photo is the base, untouched. A single warm plate takes ink in the shadows and is a no-op on highlights, because its bright end is white and white multiplies to nothing. The misregistration fringe lands on your silhouette and nowhere else.

T3 halftone, shadows only

Dots in the shadows, skin left smooth.
Aadarsh UpadhyaySee the work

The halftone you asked for, rebuilt. A shadow plate whose alpha comes from luminance, screened at two frequencies so the dots interfere the way two misaligned screens do. You get the texture without losing the face.

T4 photocopy chew, in colour

A bad copy, at full colour.
Aadarsh UpadhyaySee the work

The chew you liked, without the ink crush. One displacement filter eroding the alpha edge, colour untouched. Cheap in effect, and unlike the halftone it costs nothing at render time once rasterised. The ragged edge is the whole idea here.

LikenessT4 keeps all of it. T2 nearly all. T3 all of it above the midtones. T1 is the biggest departure and still carries your hue.
Reads as risoT1 most, T3 next, T2 least, T4 not really — T4 reads as photocopy, which is a different and equally good excuse.
CostT1 and T2 are one static filter each. T3 is one filter plus two masks. T4 is one displacement filter, which is per-pixel but only rasterises once while static.
Combines with dragAll four. T2 and T3 gain the most from it, because their second plate is offset independently.
My pick: T3 + T4's edge. Shadow-only halftone gives you the screen-print texture you asked for without touching your face, and the chewed alpha edge from T4 on top of it makes the whole thing read as a physical print rather than a filter. T2 if you want maximum resemblance and do not care much about "riso".
2

The whole page, and how it folds

One continuous surface at 1440px: hero, work, testimonials, contact. The paper value and the film grain do not change at a section boundary, so every fold below is carried by motion rather than by a background swap. That is the constraint that shapes all three.

the five measured tones, used as the ink set
capadwork · words · stack · contact
developer tools · desktop apps

I build the tools that shouldn’t need to exist.

See the work open for the right problem
fold 1 · print settles as it leaves

01 — shipped

What that produced.

01
searchtsA web unlocker for pages that block scrapers.python · cli
02
GlyphMapsTurn-by-turn arrows on the back of a phone.android · kotlin
03
GroveA reading app that keeps your place.flutter
04
beep-beep-ossOffline hearing-test buzzes.android
fold 2 · glass carries across

02 — kind words

What people say.

Thank you, for the PR and for #133, which is one of the best bug reports this project has had.

Amir Lehmam  /  maintainer at wmux

fling, tap or use the dots

fold 3 · card material becomes panel

03 — contact

Start a conversation.

I read everything and reply to most of it. If you have a tool that should exist, say so.

Open the widget

elsewhere

github · / capad-xyz
x · / aadarsh_io
read.cv · / capad

capad — Aadarsh Upadhyayshipping in the open
Fold 1The print settles as it leaves. The riso misregistration eases toward zero as the hero scrolls up, and drifts again when you scroll back. The print appears to be pulled into register by leaving. One custom property, already written, no new work.
Fold 2Nothing happens, on purpose. The project cards and the testimonial deck are the same material — translucent white, 1px light border, the same shadow. A reader crossing the boundary should not perceive a change, and the dot rail is the only persistent element that tells them where they are.
Fold 3The card becomes the panel. The deck's front card and the contact panel are one shared .glass surface, so the contact widget can expand the card in place rather than cross-fade into a new one. This is the fold most likely to feel cheap if faked with opacity, so it wants a real shared element.
The grainOne fixed overlay for the whole document, never re-created per section. That is what stops the folds reading as seams. It is also the single most expensive thing on the page under a software rasteriser, which is the open perf question.
Note what I did not do. I have not invented transitions between sections because you asked to see the page, not because the folds were missing. The three above are the minimum that makes the material continuous. If the page reads as too flat once you see it whole, that is the finding, and the fix is one deliberate moment rather than three.
3

Pointer and drag, together

You picked both, so here they are in one panel: the inks lean toward the pointer, and grabbing the plate lets you pull the registration apart or push it home. The two compose rather than compete — the pointer sets where you are looking, the drag sets what you are correcting.

Drag past zero and it snaps. Release at registration and the plates lock together with a short settle, the way a printer locks a plate once it finds the mark. That snap is the whole reward; without it, dragging is just a slider.

LIVE — try it

mis 1.2px
Pull the plates back into register. Aadarsh Upadhyay
developer toolsSee the work

Move the pointer and the shadow plate leans after it. Press and drag horizontally and you take over the registration directly. Let go near zero and it locks. Everything is one custom property; there is no second code path.

what it costs

Per moveOne getBoundingClientRect per pointer event on the plate, and one custom-property write. No layout read after the first, no class churn, no filter re-run beyond what the offset already forces.
Per frameNothing scheduled. There is no rAF loop in this behaviour at all, which is why it does not compete with the testimonials deck for budget.
Touchtouch-action:pan-y so a vertical swipe still scrolls the page and only a horizontal drag is captured. A drag that fights the scroller is worse than no drag.
Reduced motionThe pointer lean is a direct response to a direct pointer, so it stays. The idle breathing does not. A drag that did nothing would be a broken control.
The honest riskBoth behaviours write the same property, so on a touch device a horizontal drag to register is one gesture away from a back-swipe. That is a real conflict and it needs testing on hardware, not in a mockup.
Open question I cannot answer from here: whether the pointer lean is too subtle to notice, or too obvious once you have seen it. Both readings are possible from a mockup and only one is true. Worth deciding on a real screen before this ships.