# How Reduced Motion Accessibility Works in Taste Skill: CSS, Hooks, and Motion Intensity Policies

> Learn how Taste Skill implements reduced motion accessibility using CSS and the useReducedMotion hook. Discover how animation intensity policies ensure a better user experience for those with motion sensitivities.

- Repository: [Leon Lin/taste-skill](https://github.com/Leonxlnx/taste-skill)
- Tags: deep-dive
- Published: 2026-06-06

---

**Taste Skill enforces reduced motion accessibility through CSS media queries and the `useReducedMotion` hook from `motion/react`, requiring any animation with a `MOTION_INTENSITY` greater than 3 to respect the user's `prefers-reduced-motion` setting.**

Taste Skill is an open-source skill framework that treats motion as a graded design element rather than an all-or-nothing toggle. According to the source code in `Leonxlnx/taste-skill`, the repository mandates specific patterns for disabling high-intensity effects when users request reduced motion. This article breaks down the exact implementation rules found in [`skills/taste-skill/SKILL.md`](https://github.com/Leonxlnx/taste-skill/blob/main/skills/taste-skill/SKILL.md), the policy changelog, and the component scaffolding script.

## Motion Intensity Policy and Accessibility Rules

The design guidelines in [`skills/taste-skill/SKILL.md`](https://github.com/Leonxlnx/taste-skill/blob/main/skills/taste-skill/SKILL.md) establish a hard rule: **any animation with a `MOTION_INTENSITY` greater than 3 must respect the user's `prefers-reduced-motion` setting**. This rule was introduced in [`CHANGELOG.md`](https://github.com/Leonxlnx/taste-skill/blob/main/CHANGELOG.md) at line 74 and applies across the codebase.

When a user prefers reduced motion, all high-intensity animations collapse to static or instantly changing elements. The policy explicitly disables infinite loops, parallax, scroll-hijack, and magnetic physics for these users, ensuring the interface remains usable without vestibular triggers.

## CSS Media Query Fallbacks

Taste Skill recommends a CSS-first defensive strategy. Animations are wrapped in `@media (prefers-reduced-motion: no-preference)` blocks, while a separate `@media (prefers-reduced-motion: reduce)` block removes or simplifies the animation. As documented in [`SKILL.md`](https://github.com/Leonxlnx/taste-skill/blob/main/SKILL.md) around lines 528–531, this guarantees static behavior when the user requests reduced motion.

```css
/* Normal animated styles */
@media (prefers-reduced-motion: no-preference) {
  .card {
    animation: slide-in 0.5s ease-out;
  }
}

/* Reduced-motion override */
@media (prefers-reduced-motion: reduce) {
  .card {
    animation: none;               /* Disable animation */
    transform: none;               /* Ensure static layout */
  }
}

```

By default, if no explicit preference is set, the framework treats the default mode as static with an intensity of 1–3, limiting motion to only `:hover` and `:active` states as noted in [`SKILL.md`](https://github.com/Leonxlnx/taste-skill/blob/main/SKILL.md) at lines 561–562.

## Runtime Detection with useReducedMotion

For React components, Taste Skill imports the **`useReducedMotion`** hook directly from `motion/react`. This hook queries the live `prefers-reduced-motion` media feature and returns a boolean that components can use to conditionally render either `motion` elements or plain static markup. The pattern is documented in [`SKILL.md`](https://github.com/Leonxlnx/taste-skill/blob/main/SKILL.md) at lines 372–382.

### Using the useReducedMotion Hook

```tsx
import { motion, useReducedMotion } from "motion/react";

export function FancyButton() {
  const reduce = useReducedMotion();   // true → user wants reduced motion

  return reduce ? (
    // Static fallback – plain button without animation
    <button className="btn">Click me</button>
  ) : (
    // Animated version – motion component enabled
    <motion.button
      whileHover={{ scale: 1.1 }}
      whileTap={{ scale: 0.9 }}
      className="btn"
    >
      Click me
    </motion.button>
  );
}

```

When `useReducedMotion()` returns `true`, the component swaps animated elements for static equivalents at render time. This JavaScript layer complements the CSS media queries by allowing component-level branching logic.

## Combining CSS and JavaScript Approaches

In practice, Taste Skill components combine both techniques for defense in depth. The following example from the design documentation shows a card that applies static classnames via the hook while also conditionally rendering a `motion.div`:

```tsx
import { motion, useReducedMotion } from "motion/react";

export function Card({ children }) {
  const reduce = useReducedMotion();

  return (
    <div className={reduce ? "card static" : "card animated"}>
      {reduce ? (
        children
      ) : (
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.4 }}
        >
          {children}
        </motion.div>
      )}
    </div>
  );
}

```

This dual-layer approach ensures that reduced-motion users receive identical content and layout without surprise movement, even if JavaScript executes before stylesheets parse.

## Behavior Matrix by User Preference

The [`SKILL.md`](https://github.com/Leonxlnx/taste-skill/blob/main/SKILL.md) specification defines three explicit behavioral modes:

- **`prefers-reduced-motion: no-preference`** — Full animated experience enabled, including `motion` components, parallax, and magnetic physics.
- **`prefers-reduced-motion: reduce`** — All high-intensity animations collapse to static or instantly-changing elements; infinite loops, parallax, scroll-hijack, and magnetic physics are disabled according to lines 529–531.
- **Default (no explicit preference)** — Treated as static with intensity 1–3, permitting only `:hover` and `:active` states as defined at lines 561–562.

## Key Source Files and References

The reduced-motion rules in `Leonxlnx/taste-skill` are centralized in the following files:

- **[`skills/taste-skill/SKILL.md`](https://github.com/Leonxlnx/taste-skill/blob/main/skills/taste-skill/SKILL.md)** — Contains the design guidelines, motion intensity definitions, CSS media query rules, and `useReducedMotion` hook patterns.
- **[`CHANGELOG.md`](https://github.com/Leonxlnx/taste-skill/blob/main/CHANGELOG.md)** (line 74) — Records the introduction of the mandatory reduced-motion rule for high-intensity animations.
- **[`skill.sh`](https://github.com/Leonxlnx/taste-skill/blob/main/skill.sh)** — The scaffolding helper script that auto-generates new components with the correct `motion/react` imports, encouraging adoption of the accessibility hooks from file creation.

## Summary

- Taste Skill grades animation severity using a `MOTION_INTENSITY` scale, and any effect above level 3 must integrate `prefers-reduced-motion` support.
- CSS media queries provide the first line of defense, isolating animations inside `no-preference` blocks and nullifying them inside `reduce` blocks.
- The `useReducedMotion` hook from `motion/react` enables runtime branching in React components, letting developers swap `motion` elements for static markup.
- Default sessions without an explicit preference are treated as low-intensity static experiences with only hover and active states.
- Source policy is defined in [`skills/taste-skill/SKILL.md`](https://github.com/Leonxlnx/taste-skill/blob/main/skills/taste-skill/SKILL.md) and enforced by the changelog entry at [`CHANGELOG.md`](https://github.com/Leonxlnx/taste-skill/blob/main/CHANGELOG.md) line 74.

## Frequently Asked Questions

### How does Taste Skill enforce reduced motion accessibility for high-intensity animations?

Taste Skill mandates that any animation with a `MOTION_INTENSITY` greater than 3 must respect the user's `prefers-reduced-motion` setting. This policy is declared in [`skills/taste-skill/SKILL.md`](https://github.com/Leonxlnx/taste-skill/blob/main/skills/taste-skill/SKILL.md) and tracked in [`CHANGELOG.md`](https://github.com/Leonxlnx/taste-skill/blob/main/CHANGELOG.md) at line 74. High-intensity effects must be disabled or simplified when the user prefers reduced motion.

### What is the difference between the CSS and JavaScript approaches in Taste Skill?

The CSS approach uses `@media (prefers-reduced-motion: reduce)` to strip animations at the stylesheet level, while the JavaScript approach uses the `useReducedMotion` hook from `motion/react` to conditionally render static markup inside React components. Taste Skill recommends using both together for reliable, layered enforcement.

### What motion intensity levels are considered safe without reduced-motion checks?

Animations with an intensity of 1–3 are considered safe and are treated as static by default, limited to `:hover` and `:active` states. Only effects above intensity 3 require explicit reduced-motion handling according to [`SKILL.md`](https://github.com/Leonxlnx/taste-skill/blob/main/SKILL.md) lines 561–562.

### Which source files define the reduced-motion rules in Leonxlnx/taste-skill?

The primary rules live in [`skills/taste-skill/SKILL.md`](https://github.com/Leonxlnx/taste-skill/blob/main/skills/taste-skill/SKILL.md), which documents the CSS media queries, hook usage, and intensity policy. The changelog in [`CHANGELOG.md`](https://github.com/Leonxlnx/taste-skill/blob/main/CHANGELOG.md) at line 74 marks the rule as mandatory, and [`skill.sh`](https://github.com/Leonxlnx/taste-skill/blob/main/skill.sh) seeds new components with the correct `motion/react` imports.