Horizontal Scroller
Pinned kinetic viewport camera that seamlessly translates horizontal cards in 1:1 synchronization with vertical page scroll (Brix Agency architecture).
Interactive Specification & Studio
Quick Start & Consumer Example
Copy-paste ready implementation for React (.tsx). Automatically updates when you modify parameters in the Workbench above.
import React from 'react';
import { HorizontalScroller } from './components/ui/HorizontalScroller';
const SERVICES = [
{ num: '01', category: 'DESIGN', title: 'Web Design & Concept', desc: 'Crafting intuitive digital experiences that convert.', cta: 'Explore web design', badge: 'PROTOTYPING' },
{ num: '02', category: 'ENGINEERING', title: 'Development & Motion', desc: '120 FPS kinetic transitions and zero layout thrash.', cta: 'Explore development', badge: '120 FPS' },
{ num: '03', category: 'IDENTITY', title: 'Brand Strategy', desc: 'Distinct typography and strategic positioning.', cta: 'Explore branding', badge: 'STRATEGY' },
{ num: '04', category: 'GROWTH', title: 'Conversion Optimization', desc: 'Data-driven landing pages and experimentation.', cta: 'Explore growth', badge: 'ANALYTICS' },
];
export default function App() {
return (
<div className="min-h-[200vh] bg-background text-foreground py-20">
<div className="max-w-6xl mx-auto px-6 mb-12">
<h1 className="text-4xl font-bold">Featured Capabilities</h1>
</div>
<HorizontalScroller
speed={1}
itemGap={28}
cardWidth={320}
showProgress={true}
showFadeEdges={true}
fadeWidth={48}
fadeEdgeColor="#ffffff"
fadeEdgeColorDark="#09090b"
mobileMode="scroll"
>
{SERVICES.map((s, idx) => (
<div key={idx} className="flex flex-col md:flex-row h-full rounded-2xl border border-border bg-card p-6 min-h-[360px]">
<div className="flex-1 flex flex-col justify-between pr-4">
<div>
<span className="font-mono text-xs text-emerald-500 font-bold">{s.num} / {s.category}</span>
<h3 className="text-2xl font-bold mt-2">{s.title}</h3>
<p className="text-muted-foreground text-sm mt-2">{s.desc}</p>
</div>
<span className="text-xs font-semibold mt-4 text-foreground hover:text-emerald-400 cursor-pointer">{s.cta} →</span>
</div>
<div className="w-full md:w-1/2 bg-muted/20 rounded-xl p-4 flex items-center justify-center font-mono text-xs text-muted-foreground">
{s.badge} // EKM RAIL
</div>
</div>
))}
</HorizontalScroller>
</div>
);
}
Props & Configuration
Exhaustive parameter contract for Horizontal Scroller. Validated in the live Studio workbench above and statically checked across all 13 ecosystem templates.
| Prop | Type | Default | Description |
|---|---|---|---|
itemGap | number | 28 | Spacing in pixels between horizontal cards (default: 28px). |
speed | number | 1 | Scroll distance multiplier mapping vertical page scroll to horizontal translation distance. |
cardWidth | number | 320 | Fixed card width in pixels (default: 320px). |
showProgress | boolean | true | Display a kinetic telemetry progress bar indicating track traversal percentage. |
showFadeEdges | boolean | true | Show subtle gradient mask at horizontal boundaries for graceful card entry and exit. |
fadeWidth | number | 48 | Width in pixels of the left and right gradient fade masks. |
fadeEdgeColor | color | #ffffff | Custom edge gradient color. When empty, an alpha mask is used. |
fadeEdgeColorDark | color | #09090b | Edge gradient color when dark mode is active. Falls back to fadeEdgeColor. |
mobileMode | select | scroll | Mobile fallback behavior below 768px (scroll = native touch swipe with snap, stack = vertical list, pinned = retain pinned rail). |
Spacing in pixels between horizontal cards (default: 28px).
Scroll distance multiplier mapping vertical page scroll to horizontal translation distance.
Fixed card width in pixels (default: 320px).
Display a kinetic telemetry progress bar indicating track traversal percentage.
Show subtle gradient mask at horizontal boundaries for graceful card entry and exit.
Width in pixels of the left and right gradient fade masks.
Custom edge gradient color. When empty, an alpha mask is used.
Edge gradient color when dark mode is active. Falls back to fadeEdgeColor.
Mobile fallback behavior below 768px (scroll = native touch swipe with snap, stack = vertical list, pinned = retain pinned rail).
Component Source
Component source definition for React (.tsx). Toggle between the clean wrapper and the standalone ejected engine micro-kernel.
import * as React from 'react';
import * as HorizontalScrollerPrimitive from '@exhuma/core';
import { clsx } from 'clsx';
export interface HorizontalScrollerProps extends React.ComponentPropsWithoutRef<typeof HorizontalScrollerPrimitive.HorizontalScroller> {
className?: string;
}
export const HorizontalScroller = React.forwardRef<HTMLDivElement, HorizontalScrollerProps>(
({ className, children, ...props }, ref) => (
<HorizontalScrollerPrimitive.HorizontalScroller
ref={ref}
className={clsx(
'relative overflow-hidden w-full py-8',
className
)}
{...props}
>
{children}
</HorizontalScrollerPrimitive.HorizontalScroller>
)
);
HorizontalScroller.displayName = 'HorizontalScroller';
Lifecycle Safety & Performance
Engineered for high-frequency user interactions with zero memory leaks.
Deterministic Cleanup
GPU Compositor Acceleration
will-change: transform without triggering browser layout recalculations.Accessibility Considerations
Fully compliant with WCAG guidelines and respects user motion preferences.
prefers-reduced-motion Support
prefers-reduced-motion: reduce enabled in their operating system, Exhuma components automatically disable 3D gyroscope tilt and spring animations, rendering static accessible content.