How Reduced Motion Accessibility Works in Taste Skill: CSS, Hooks, and Motion Intensity Policies
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, the policy changelog, and the component scaffolding script.
Motion Intensity Policy and Accessibility Rules
The design guidelines in 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 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 around lines 528–531, this guarantees static behavior when the user requests reduced motion.
/* 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 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 at lines 372–382.
Using the useReducedMotion Hook
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:
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 specification defines three explicit behavioral modes:
prefers-reduced-motion: no-preference— Full animated experience enabled, includingmotioncomponents, 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
:hoverand:activestates 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— Contains the design guidelines, motion intensity definitions, CSS media query rules, anduseReducedMotionhook patterns.CHANGELOG.md(line 74) — Records the introduction of the mandatory reduced-motion rule for high-intensity animations.skill.sh— The scaffolding helper script that auto-generates new components with the correctmotion/reactimports, encouraging adoption of the accessibility hooks from file creation.
Summary
- Taste Skill grades animation severity using a
MOTION_INTENSITYscale, and any effect above level 3 must integrateprefers-reduced-motionsupport. - CSS media queries provide the first line of defense, isolating animations inside
no-preferenceblocks and nullifying them insidereduceblocks. - The
useReducedMotionhook frommotion/reactenables runtime branching in React components, letting developers swapmotionelements 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.mdand enforced by the changelog entry atCHANGELOG.mdline 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 and tracked in 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 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, which documents the CSS media queries, hook usage, and intensity policy. The changelog in CHANGELOG.md at line 74 marks the rule as mandatory, and skill.sh seeds new components with the correct motion/react imports.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →