Skip to main content

Crate makeover_touch

Crate makeover_touch 

Source
Expand description

The adaptation layer of the make-family design system.

makeover answers what colour. makeover-geometry answers how much space, and owns the two axes an adaptation is stated against: Density (pointer or touch) and SizeClass (compact, medium, expanded). makeover-layout answers what the thing is. This crate answers one question and no other:

Does this affordance exist here?

Like makeover-layout it emits nothing. It is a description, rendered to CSS by makeover-webview and to whatever the other renderers can express.

§Why this is a crate and not a density preset

Measured across the MNW server’s @media blocks (137) and goingson’s ui-mode-* blocks (192), bucketed by what the declarations inside actually change:

bucketMNWGOretired by
density32%27%a makeover-geometry preset
type23%15%the type scale
columns20%12%makeover_layout::Column
reflow16%17%makeover_layout::Arrangement
show/hide12%12%this crate
reposition6%20%this crate
appearance1%17%this crate

The bottom three are the roughly 43% that no spacing scale can retire, and trying is the mistake this whole family already made once. display: none on a keyboard hint says the affordance does not exist on touch. No amount of gap retuning expresses that, and a scale that tried would be smuggling a product claim onto a measurement axis — which is exactly what the 2026-07-29 Touch demolition was for.

Two of the eight members are not in that census at all, and the exception is worth stating rather than leaving to be noticed. Affordance::Gesture and Affordance::Haptic adapt behaviour, which no stylesheet contains, so counting @media blocks could never have found them. Their evidence has the same shape in a different file: goingson frontend/js/touch.js:12 and Balanced Breakfast frontend/js/touch.js:12 carry the identical line

const isTouchDevice = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0);

and each hangs five gestures off it. Two apps, arrived at independently, hand-rolling the density question this crate exists to answer.

§The two axes are borrowed, never redefined

Boundaries are not this crate’s job. makeover-geometry quotes Material 3’s window size classes at 600 and 840 and carries Density; this crate names affordances against those two and adds no third axis, no fourth class and no breakpoint of its own. If a rule here wants a boundary that does not exist, that is a conversation with makeover-geometry, not a constant.

§What density is allowed to gate

Density is a claim about the contact patch and nothing else. So it gates affordances that depend on an interaction a fingertip cannot perform — hovering, and the keyboard chrome that documents shortcuts a touch surface has no way to send. It does not gate anything that is really about how much screen there is. A phone is small and touch; a tablet is big and touch.

That separation is asserted, not merely intended, by density_gates_only_what_the_contact_patch_touches. Putting a screen-budget claim on the input device is the specific failure that produced this crate, and re-introducing it should have to come to the test and say so.

§Both densities gain something (0.3.0)

Until 0.3.0 this crate asserted that touch is pointer minus what a fingertip cannot do — availability only ever subtracted as you moved from Density::Pointer to Density::Touch, and a test called touch_never_gains_an_affordance_pointer_lacks said so. That claim is withdrawn, deliberately, because it left a hole the crate could not name: Affordance::Hover’s own doc says a fingertip has no hover state and that something else has to carry the same actions, and nothing here was allowed to be that something. Affordance::Anchored and Affordance::Overflow compensate on the size axis; nothing compensated on the density axis.

Affordance::Gesture and Affordance::Haptic are that compensation, and both are gained by touch rather than lost to it.

The claim is replaced rather than dropped. Affordance::gained_by makes each member declare which density it belongs to, and a_density_member_is_available_on_exactly_the_density_it_declares checks the declaration against the rule. So a new member still cannot quietly invert: it has to say which way it goes, in code, and the test is where a wrong answer surfaces.

§Collapsing is allowed, inverting is not

Borrowed verbatim from makeover-geometry, where two gap relationships both resolve to zero cells on a terminal and stay two members regardless. Two affordances here may have identical availability today — Affordance::Hover and Affordance::Hint do — and are still two members, because the call site names what is being gated, not the rule. What must never happen is one of them becoming available where the other is not for a reason that is really the same reason.

§Deliberately absent

A navigation shell fork. goingson currently carries two: 12 forked selectors and 10 desktop-only rules concentrated in .app-header, .tab, .tab-navigation, .pill-nav, .saved-views-sidebar and .modal-container. That is not one shell adapting, it is two shells, and choosing to build two is a product decision rather than an adaptation. This crate will not describe it, and goingson’s own restructure is the way it stops being true. Named here the way makeover-layout names validation absent, so nobody has to discover it.

Which class applies. The app decides, from a measured width via SizeClass::at_width and from whatever it already knows about the input. This crate takes both as arguments and never sniffs.

What a renderer does when an affordance is unavailable. Hiding it, substituting it, or showing it unconditionally anyway is renderer policy. makeover-layout already deleted Fill::fallback for being exactly that.

Enums§

Affordance
An affordance whose existence depends on the surface it is offered on.
Density
Which input the layout is being sized for.
Priority
What a member is worth when there is not room for all of them.
SizeClass
How much screen there is, independent of what is pointing at it.

Functions§

column_cutoff
The column-drop cutoff a window of this size class asks for.