---
title: Micro-Motion Philosophy & Sub-100ms Hover
description: Motion serves as spatial anchors, not entertainment; zero-delay 0ms hover principles and state morph class isolation.
---

# Micro-Motion Philosophy & Sub-100ms Hover

In desktop productivity applications, micro-motion exists solely to sustain spatial continuity in the user's mental model. Sluggish transitions destroy professional velocity.

## Motion as Spatial Anchors, Not Entertainment

Consumer apps indulge in 600ms card flips. In Tuff, users execute hundreds of rapid operations daily:
- Motion's sole legitimate role is an **optical spatial anchor**: communicating where elements originate from and collapse into.
- The vast majority of micro-interactions complete within **90ms–180ms**.
- Motion must never block incoming keyboard inputs or pointer clicks.

## Hover States Require 0ms Instant Response

Moving a pointer across a screen is a high-intent exploratory action.
**Iron Rule: When the cursor enters an interactive hit area, background fills and text inks must update in 0ms!**

Attempting to ease colors on hover makes the pointer feel bogged down in molasses, ruining responsive tactile feedback.

## Why Easing Hover Colors Feels Laggy

Human motor reflexes expect visual feedback under the 100ms threshold.
If an engineer declares:
```scss
// Severe anti-pattern!
.btn { transition: background-color 200ms ease; }
```
As the cursor traverses a button cluster, backgrounds fade in lethargically. The cursor exits before the transition resolves, inducing the physiological sensation of input lag.

## State Morph Transition Class Isolation

When is color easing permissible? **Only during semantic state shifts (e.g. converting a chip from muted to dangerous)**.

To prevent state transitions from polluting hover states, TuffEx's rule is: **Color transitions must attach exclusively to temporary morph classes, never to the element root**. Here is how TxModeChip writes it (variable fallbacks omitted):

:::TuffCodeBlock{lang="scss"}
---
code: |
  .tx-mode-chip {
    // Hover remains immediate: 0ms delay
    &:hover:not(:disabled) {
      background-color: var(--tx-mode-chip-fill-hover);
      color: var(--tx-mode-chip-ink-hover, var(--tx-mode-chip-ink));
    }

    // Activated only during explicit semantic morphs
    &.is-morphing {
      transition: 
        background-color 240ms var(--tx-ease-out-strong), 
        color 240ms var(--tx-ease-out-strong);
    }
  }
---
:::

Through class isolation, hovers retain instant snap, while semantic state changes morph smoothly.

Every TuffEx component now keeps this rule: a hover always repaints at once. A color transition either lives on `.is-morphing` alone, which a state change such as selecting, opening or focusing adds and the end of its longest color leg removes, or sits on an element whose color no hover changes. A highlight that follows the pointer counts as a hover too, for example TxSearchPanel's options and TxCascader's expanded path, and repaints at once as well.

:::TuffDemoWrapper{demo="ConceptHoverLatencyDemo"}
:::
