1280×720 · 7s · 30fps

Pricing focus · 7s

Landscape (1280×720) pricing move. Three tiers — Free, Pro, Enterprise — settle in side by side, then the camera commits to the recommended middle tier: it scales up on a push-in while the two side cards dim and blur into the background, and a shimmer sweep crosses its CTA to seal the choice. A focus pull built from Camera/useCameraRig plus frame-driven opacity + blur.

SRC

The whole composition

Below is the entire source for this showcase — every component, every transition, every prop. Copy it into your Remotion project as a starting point, then swap copy, swap colors, swap timing.

TSX
'use client';

import React from 'react';
import { AbsoluteFill, useCurrentFrame, interpolate, Easing } from 'remotion';
import { Camera, useCameraRig } from '@onda/lib/index';
import { PricingCard, pricingCardSchema } from '@onda/registry/components/pricing-card/PricingCard';
import { ShimmerSweep, shimmerSweepSchema } from '@onda/registry/components/shimmer-sweep/ShimmerSweep';
import { Vignette, vignetteSchema } from '@onda/registry/components/vignette/Vignette';

const VIEWPORT_W = 1280;
const VIEWPORT_H = 720;

// Three 380px cards laid out in a row inside the world, centered vertically.
// The middle card is the focus target — the camera pushes in on its center
// and the two side cards dim + blur into the background.
const CARD_W = 380;
const GAP = 56;
const ROW_W = CARD_W * 3 + GAP * 2;
const ROW_LEFT = (VIEWPORT_W - ROW_W) / 2; // 70
const CARD_TOP = 150;
const LEFT_X = ROW_LEFT; // 70
const MID_X = ROW_LEFT + CARD_W + GAP; // 506
const RIGHT_X = ROW_LEFT + (CARD_W + GAP) * 2; // 942
const MID_CENTER_X = MID_X + CARD_W / 2; // 696
const MID_CENTER_Y = CARD_TOP + 250;

const HOUSE_EASE = Easing.bezier(0.16, 1, 0.3, 1);

// The two side tiers recede as the camera commits to the middle: opacity falls
// and a blur builds, pushing them behind the recommended card. Pure function of
// frame, clamped (CLAUDE.md §1, §3).
const SideCard: React.FC<{ left: number; children: React.ReactNode }> = ({ left, children }) => {
  const frame = useCurrentFrame();
  const opacity = interpolate(frame, [55, 95], [1, 0.32], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
    easing: HOUSE_EASE,
  });
  const blur = interpolate(frame, [55, 95], [0, 6], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
    easing: HOUSE_EASE,
  });
  return (
    <div style={{ position: 'absolute', left, top: CARD_TOP, opacity, filter: `blur(${blur}px)` }}>
      {children}
    </div>
  );
};

// Three pricing tiers settle in side by side, then the camera focuses the
// recommended middle tier — it scales up via zoom while the side cards dim and
// blur back, and a shimmer sweeps the focused CTA to seal the choice.
export const PricingFocusComposition: React.FC = () => {
  const rig = useCameraRig([
    { frame: 0, focusX: VIEWPORT_W / 2, focusY: VIEWPORT_H / 2, zoom: 1 },
    { frame: 50, focusX: VIEWPORT_W / 2, focusY: VIEWPORT_H / 2, zoom: 1 },
    { frame: 95, focusX: MID_CENTER_X, focusY: MID_CENTER_Y, zoom: 1.25 },
  ]);

  return (
    <AbsoluteFill style={{ background: '#08080A' }}>
      <Camera {...rig} viewportWidth={VIEWPORT_W} viewportHeight={VIEWPORT_H}>
        <div style={{ position: 'absolute', inset: 0 }}>
          {/* Free — left, recedes on focus */}
          <SideCard left={LEFT_X}>
            <PricingCard
              {...pricingCardSchema.parse({
                tier: 'Free',
                price: 'Free',
                period: '',
                cta: 'Start free',
                features: ['Up to 3 renders / mo', 'Watermark on export', 'Community support'],
                delay: 0,
              })}
            />
          </SideCard>

          {/* Pro — middle, the recommended focus tier */}
          <div style={{ position: 'absolute', left: MID_X, top: CARD_TOP }}>
            <PricingCard
              {...pricingCardSchema.parse({
                tier: 'Pro',
                price: '$29',
                period: '/month',
                cta: 'Get started',
                recommended: true,
                features: [
                  'Unlimited renders',
                  'Signature motion identity',
                  'Source you own, copied in',
                  'Priority support',
                ],
                delay: 8,
              })}
            />
            {/* Shimmer sweep over the focused CTA — placed at the button row. */}
            <div style={{ position: 'absolute', left: 40, right: 40, bottom: 54, height: 28, overflow: 'hidden' }}>
              <ShimmerSweep
                {...shimmerSweepSchema.parse({
                  text: 'Get started',
                  fontSize: 17,
                  align: 'center',
                  delay: 100,
                  duration: 36,
                  color: '#08080A',
                  shimmerColor: '#FFFFFF',
                  fontFamily: '"Space Grotesk", sans-serif',
                  fontWeight: 600,
                })}
              />
            </div>
          </div>

          {/* Enterprise — right, recedes on focus */}
          <SideCard left={RIGHT_X}>
            <PricingCard
              {...pricingCardSchema.parse({
                tier: 'Enterprise',
                price: 'Custom',
                period: '',
                cta: 'Talk to sales',
                features: ['SSO & SAML', 'Dedicated support', 'Custom motion presets', 'SLA & invoicing'],
                delay: 16,
              })}
            />
          </SideCard>
        </div>
      </Camera>

      <Vignette {...vignetteSchema.parse({ intensity: 0.5 })} />
    </AbsoluteFill>
  );
};

Install the pieces

This showcase uses the following Onda categories — every item is one CLI install:

  • interface
  • scenes
  • entrances

Browse the full component catalog for the individual slugs.

Other showcases