# How Archify Handles Reduced Motion Preferences: CSS Media Queries and JavaScript Runtime Checks

> Archify respects reduced motion preferences by disabling animations with CSS media queries and JavaScript matchMedia checks. Ensure a better user experience for all.

- Repository: [tt-a1i/archify](https://github.com/tt-a1i/archify)
- Tags: deep-dive
- Published: 2026-09-06

---

**Archify automatically disables or shortens animations when a user's operating system is set to prefers-reduced-motion, using both CSS media queries at build time and JavaScript matchMedia checks at runtime.**

Accessibility isn't an afterthought in Archify—it's baked into every generated viewer. The repository implements a dual-layer approach that respects user motion preferences through declarative CSS rules and imperative JavaScript detection. This ensures animated transitions, smooth scrolling, and visual effects are either removed or rendered instantly when users need reduced motion.

## CSS-Level Reduced Motion Handling in Templates

Archify's UI templates use the standard **prefers-reduced-motion** media query to strip animations before JavaScript even executes. This creates a solid baseline that works regardless of script loading or execution order.

Each template applies the same pattern. In [`scripts/start-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/start-template.html) at line 174, the CSS forces instant state changes:

```css
@media (prefers-reduced-motion: reduce) {
  * { 
    transition: none !important; 
    scroll-behavior: auto !important; 
  }
}

```

The same media query appears in:
- [`scripts/guide-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/guide-template.html) at line 179
- [`scripts/gallery-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/gallery-template.html) at line 218

This blanket rule targets all elements, eliminating transition delays and swapping smooth scrolling for immediate jumps. Because these styles use `!important`, they override any component-level animation definitions.

## JavaScript Runtime Detection in Generated Viewers

Once the page loads, Archify's generated viewers perform fine-grained motion control through `window.matchMedia`. The [`generated/maka-regenerated.workflow.html`](https://github.com/tt-a1i/archify/blob/main/generated/maka-regenerated.workflow.html) file contains the canonical implementation, with logic reused across other outputs like [`web-app.html`](https://github.com/tt-a1i/archify/blob/main/web-app.html) and [`workflow-agent-tool-call-rendered.html`](https://github.com/tt-a1i/archify/blob/main/workflow-agent-tool-call-rendered.html).

### Creating the Media Query Object

At line 7193, the viewer initializes a reusable query object with fallback for older browsers:

```javascript
var motionQuery = window.matchMedia
    ? window.matchMedia('(prefers-reduced-motion: reduce)')
    : null;

```

This pattern defensively checks for `matchMedia` support before attempting to query the preference.

### Computing Animation Delays Conditionally

The most critical runtime check appears at line 12232, where Archify calculates whether to apply its default 540ms delay or skip straight to 0ms:

```javascript
var delay = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches
    ? 0
    : 540;

```

This ternary pattern appears throughout the codebase whenever timing needs to respect motion preferences. The 540ms value represents Archify's standard animation duration; reduced-motion users get immediate feedback instead.

### Helper Function for Boolean Checks

For cleaner conditional logic, line 8990 exposes a dedicated helper:

```javascript
function prefersReducedMotion() {
  return !!(window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches);
}

```

The double-bang (`!!`) coerces the result to a strict boolean, making this function safe for direct use in `if` statements and component props.

## Key Implementation Files

| File | Purpose | Lines |
|------|---------|-------|
| [`scripts/start-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/start-template.html) | Base template CSS rules | 174 |
| [`scripts/guide-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/guide-template.html) | Guide template CSS rules | 179 |
| [`scripts/gallery-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/gallery-template.html) | Gallery template CSS rules | 218 |
| [`generated/maka-regenerated.workflow.html`](https://github.com/tt-a1i/archify/blob/main/generated/maka-regenerated.workflow.html) | Main viewer: query initialization, delay calculation, helper functions | 7193, 8990, 12232 |

These files demonstrate how Archify implements reduced motion handling across the entire generation pipeline—from static templates through dynamic viewers.

## Practical Code Patterns

When building with Archify or adapting its patterns, combine both approaches for robust accessibility:

```html
<!-- In your template head -->
<style>
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; scroll-behavior: auto !important; }
}
</style>

```

```javascript
// In your viewer script
function getMotionDelay(defaultMs = 540) {
  const reduced = window.matchMedia 
    && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  return reduced ? 0 : defaultMs;
}

// Usage
const element = document.querySelector('.animated');
setTimeout(() => element.classList.add('visible'), getMotionDelay());

```

This mirrors Archify's exact implementation as found in the source code.

## Summary

- **CSS media queries** in [`scripts/start-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/start-template.html), [`guide-template.html`](https://github.com/tt-a1i/archify/blob/main/guide-template.html), and [`gallery-template.html`](https://github.com/tt-a1i/archify/blob/main/gallery-template.html) disable transitions and smooth scrolling at the stylesheet level
- **JavaScript matchMedia checks** in generated viewers like [`maka-regenerated.workflow.html`](https://github.com/tt-a1i/archify/blob/main/maka-regenerated.workflow.html) toggle between 0ms and 540ms delays based on real-time preference detection
- **Helper functions** (`prefersReducedMotion()`) provide reusable boolean checks for component-level conditional rendering
- **Dual-layer protection** ensures reduced motion preferences are honored even if JavaScript fails or loads slowly

## Frequently Asked Questions

### How does Archify detect reduced motion preferences?

Archify uses the standard `prefers-reduced-motion` media query. In CSS, this appears as `@media (prefers-reduced-motion: reduce)` blocks in template files. In JavaScript, the code calls `window.matchMedia('(prefers-reduced-motion: reduce)')` and checks the `.matches` property, as implemented in [`generated/maka-regenerated.workflow.html`](https://github.com/tt-a1i/archify/blob/main/generated/maka-regenerated.workflow.html) at lines 7193 and 12232.

### What happens to animations when reduced motion is enabled?

Transitions are set to `none !important` and scroll behavior becomes `auto` (instant) through CSS rules in the template files. JavaScript calculations return 0ms instead of the default 540ms delay, causing any scripted animations to execute immediately without visible motion.

### Does Archify work in browsers without matchMedia support?

Yes. The JavaScript code explicitly guards against missing `matchMedia` by returning `null` from the query initialization and using short-circuit evaluation (`window.matchMedia && ...`) before accessing `.matches`. This ensures graceful degradation rather than runtime errors.

### Which Archify files should I examine to understand this implementation?

Start with [`scripts/start-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/start-template.html) (line 174) for the CSS foundation, then review [`generated/maka-regenerated.workflow.html`](https://github.com/tt-a1i/archify/blob/main/generated/maka-regenerated.workflow.html) at lines 7193, 8990, and 12232 for the complete JavaScript implementation including query creation, delay calculation, and the `prefersReducedMotion()` helper function.