Mark Design

Effects

What an element does when you point at it. Four opt-in classes, composable, and available to anything — a card, a button, a link, an icon. A component should never re-derive a hover; it wears one.

Lift

.mk-lift-sm · .mk-lift · .mk-lift-lg

Motion only — the element rises. Three stops, and that is the whole scale. Transforms need a block-ish box, so pair with d-inline-block on something inline.

Rises 2px

mk-lift-sm — hover or tab to it

Rises 4px

mk-lift — hover or tab to it

Rises 8px

mk-lift-lg — hover or tab to it


Shadow

.mk-shadow-sm · .mk-shadow · .mk-shadow-lg

The shadow half — three stops, doubling like the lift scale beside it.

Drawn in ink, so it flips with the mode on its own. Every stop is rgba(var(--bs-body-color-rgb), …), which is near-black on a light page and near-white on a dark one — from one declaration each, with no -light/-dark twin and no per-mode override to keep in step. It follows the surface, not the page: inside a dark band on a light page the ink is already re-bound, so the shadow is already white.

A literal black shadow cannot work on a dark ground — there is nothing left to darken, and it disappears. What reads as elevation on dark is light. Opacity rises with size because a larger shadow spreads the same ink over more pixels.

Small

mk-shadow-sm — hover or tab to it

Base

mk-shadow — hover or tab to it

Large

mk-shadow-lg — hover or tab to it


Highlight

.mk-highlight

The border answers in the accent — the “this one” cue, and the only one of the four that communicates rather than moves.

It needs a border it is allowed to repaint. Two ways to lose it, both silent: an element with border: none has no width or style for the colour to land on, and — the one that actually catches people — Bootstrap's .border utility is a shorthand carrying !important, so it sets border-color too and nothing without !important can repaint it. Give the element a real border rule. Every card in this system does, which is why all three could drop their hand-written version.

Border answers

mk-highlight — hover or tab to it

All three — the card hover

mk-lift mk-shadow mk-highlight — hover or tab to it


Nudge

.mk-nudge · .mk-nudge--back

For an inline “go” link: the trailing icon slides in the reading direction instead of the whole element moving. Icon-library agnostic — it targets a direct <i> or <svg> child. --back inverts both halves, so a back-link's arrow leads the label and still moves away from it.

Go on Back


Composing

class="mk-lift mk-shadow mk-highlight"

The three halves are separate because they are separately useful — a button raises without lifting, an icon nudges without either. Together they are the card hover this system had been writing out by hand in three stylesheets:

<a class="mk-feature-card mk-lift-sm mk-shadow-sm mk-highlight">…</a>
<a class="page-card mk-lift mk-shadow mk-highlight">…</a>
<article class="article-card mk-lift mk-shadow mk-highlight">…</article>

Reduced motion

@media (prefers-reduced-motion: reduce)

mk-lift and mk-nudge stand down entirely — they are movement. mk-shadow and mk-highlight do not, deliberately: a shadow appearing and a border changing colour are not motion, and suppressing them would leave someone with reduced motion — and every keyboard user, since all four fire on :focus-visible — with no hover feedback at all.

The focus ring (--ring) is documented under Tokens. It looks like an effect and is not one: it is an accessibility contract, and it should never be retuned alongside hover taste.