Motion

La grammatica del movimento Qoovex: vivo ma calmo, semantico, interrompibile e comprensibile anche con movimento ridotto.

@qoovex/ui/styles/base.css · @qoovex/ui/lib/motion

Principi

Vivo ma calmo
Il movimento conferisce presenza all'interfaccia senza mai competere per l'attenzione. Ogni transizione ha una ragione; se non la ha, non esiste.
Semantico, non decorativo
La durata descrive il motivo della transizione, non il componente che la usa. Nessun ruolo autorizza transition-all: le proprietà restano esplicite.
Comprensibile senza movimento
Con prefers-reduced-motion lo stato cambia istantaneamente. L'informazione è identica; solo il percorso visuale è diverso.

Token di durata

Quattro ruoli semantici: la durata descrive il motivo della transizione, non il componente. Le proprietà restano esplicite — nessun ruolo autorizza transition-all.

Instant
--motion-duration-instant
100 ms
100 ms

Percezione immediata e opacity breve senza latenza apparente.

opacitycolor

Da evitare: Movimento spaziale e lifecycle di superficie.

Feedback
--motion-duration-feedback
160 ms
160 ms

Hover fine-pointer, press e risposta tattile locale.

colorborderopacitytransform locale

Da evitare: Stato persistente e attese asincrone.

State
--motion-duration-state
200 ms
200 ms

Continuità tra checked, selected, expanded e stato reale.

transformopacitycolor

Da evitare: Entrata o uscita di overlay.

Surface
--motion-duration-surface
300 ms
300 ms

Presence, distanza spaziale e orientamento tra superfici.

transformopacityclip quando motivato

Da evitare: Input frequente e feedback di controllo.

Curve di easing

Due curve che coprono l'intera gamma: standard per feedback diretto, emphasized per presenza spaziale. Entrambe favoriscono decelerazione naturale.

Standard
--ease-standard
instant · feedback · state
cubic-bezier(0.2, 0, 0, 1)

Feedback e cambi di stato ordinari. Risposta controllata e diretta.

Emphasized
--ease-emphasized
surface
cubic-bezier(0.16, 1, 0.3, 1)

Decelerazione più leggibile per presence e distanza spaziale.

Laboratorio di interazione

Controlla la preferenza di preview, esegui, inverti o ripeti rapidamente l'input. I quattro specimen semantici condividono lo stesso stato reale ma applicano ruoli differenti; gli altri esempi isolano easing e consumer runtime.

Anteprima movimento
Stato: inattivoPreferenza: normale
  1. Rest
  2. Interaction
  3. Transition
  4. Settled

Instant

100 ms · opacity
CSS
In attesa

Percezione istantanea senza transizione spaziale. Ideale per badge e tooltip.

Feedback

160 ms · scale + colore
CSS

Risposta locale alla pressione del cursore o del tocco. Hover attivo solo su pointer fine.

State

200 ms · transform
CSS + Base UI
Unchecked

Continuità tra stati: se invertito durante il moto, retargetta dalla posizione corrente senza scatti.

Surface

300 ms · ease-emphasized
CSS Surface
Superficie chiusa (DOM smontato)

Decelerazione enfatizzata per orientamento spaziale. Lifecycle e presence rispettati in uscita.

Fasi del ciclo

Ogni interazione attraversa quattro fasi. La fase osservata non sostituisce lo stato del prodotto: serve a verificare causalità, retargeting e corrispondenza finale.

1
Rest
Lo stato reale e quello visuale coincidono.
2
Interaction
L'input viene ricevuto senza attese o blocchi.
3
Transition
Il valore visuale retargetta dalla posizione corrente.
4
Settled
La transizione termina sullo stato reale più recente.

Guida pratica

Come usare i token nei componenti. CSS è la scelta predefinita; resolveMotionTransition serve solo quando il consumer ha bisogno di valori numerici a runtime.

CSS
Predefinito
Usa direttamente i custom property. Dichiara sempre le proprietà esplicite.
.my-element {
  transition-property: opacity, transform;
  transition-duration:
    var(--motion-duration-instant),
    var(--motion-duration-state);
  transition-timing-function:
    var(--ease-standard),
    var(--ease-standard);
}

@media (prefers-reduced-motion: reduce) {
  .my-element {
    transition-property: opacity;
    transition-duration:
      var(--motion-duration-feedback);
  }
}
Runtime
Solo se necessario
Proietta i token CSS in secondi e tuple Bézier per Motion o animazioni JS.
import {
  resolveMotionTransition
} from "@qoovex/ui/lib/motion";

const styles = getComputedStyle(el);
const t = resolveMotionTransition(
  styles,
  "state",      // ruolo durata
  "standard",   // curva easing
  prefersReduced
);
// → { duration: 0.2, ease: [0.2, 0, 0, 1] }
Movimento ridotto
Obbligatorio
  • ✓Rimuovi transform spaziale — cambia solo colore, opacity o proprietà non spaziali.
  • ✓Usa --motion-duration-feedback per le transizioni residue.
  • ✓Il runtime restituisce { duration: 0 } quando reduced è attivo.
  • ✗Non disabilitare tutte le transizioni — il feedback non spaziale rimane attivo.