Upgrade your UI

Every SeldonFrame workspace ships polished by default — scroll-reveal on sections, stagger on grids, hover-lift on CTAs. When you want more, four levers stack on top, each composable through Claude Code in one prompt.

Start with the smart defaults

Before reaching for any of the levers below — your site already does the right thing out of the box. Every published page wraps its sections in scroll-triggered fades; grid blocks (benefits, features, pricing, process) stagger their children in sequentially; the primary CTA lifts and glows on hover.

This is the balanced motion preset, applied universally. It's calibrated to feel premium without being theatrical. For 80% of operators, this is the finish line.

Why we don't ask

SeldonFrame doesn't pop a wizard asking you to "configure your animations" after workspace creation. The defaults are the defaults. You only need this page if you want to push beyond.

The four levers, in order of effort

Lever 1 — Tune motion intensity

One MCP tool, one prompt. Pick a preset that matches your brand voice:

  • minimal — no motion. Accessibility-first. Respects prefers-reduced-motion. Pages feel fast, deliberate, restrained.
  • subtle — fade-up reveals only. Quiet, professional, never distracts from your content.
  • balanced (default) — reveals + stagger + hover-lift. Premium feel without being theatrical.
  • editorial — full effects. Animated stat counters, magnetic CTAs that follow the cursor, scroll-linked parallax, word-by-word headline reveals. Use when your brand is brave.

In Claude Code:

> Make my site feel more editorial.

  ● apply_motion_preset({ preset: "editorial" })  200 ok
  ✓ Switched motion preset from "balanced" to "editorial"

The preset is also stored as operator intent — when Claude Code generates new content (a custom block, a new section), it reads your preset and matches the level you picked.

Lever 2 — Bring your DESIGN.md

If you have a brand kit defined in the Google Labs DESIGN.md format — YAML front matter with tokens (colors, typography, spacing) + Markdown rationale — apply it in one prompt:

> Apply the DESIGN.md in this folder to my workspace.

  ● apply_design_md({ design_md_content: <file content> })  200 ok
  ✓ Applied tokens: primary_color, accent_color, font_family
  → 2 token group(s) didn't map to OrgTheme fields. Surface
    via update_landing_page if you want them as CSS custom
    properties on specific pages.

Maps cleanly: tokens.colors.primary OrgTheme.primaryColor; tokens.colors.accent OrgTheme.accentColor; tokens.modeOrgTheme.mode; tokens.typography.body OrgTheme.fontFamily. Tokens that don't have a 1:1 equivalent come back in unmapped for Claude Code to apply via update_landing_page as CSS custom properties on individual pages.

Use this for

Agencies running 20+ client workspaces from one DESIGN.md per client. Brand teams with a single canonical token file. Operators who want consistent branding without manually setting each color.

Lever 3 — Import a Claude Design handoff

If you designed a custom hero, pricing table, or case-study section in Anthropic Claude Design, export the handoff bundle and pipe it through Claude Code:

> I just exported a handoff from Claude Design. Import it.

  ● import_claude_design_handoff({ bundle: { ... } })  200 ok
  → 4 components validated: HeroV2, TrustStrip, PricingTable, CTAStrip
  → Tokens applied: primary_color, accent_color
  → For each component, run update_landing_page with the source from
    the bundle to wire it into the chosen surface.

The handoff endpoint validates structure, applies any embedded design tokens, and returns a manifest with per-component next-step instructions. Components are not auto-applied to live pages — they route through the same review gate that protects published agents. Customer-facing surfaces still pass the eval suite before going live.

Lever 4 — Fork the block library directly

SeldonFrame is MIT-licensed. For pixel-perfect customization beyond what the levers above support:

1

Fork the repo

gh repo fork seldonframe/seldonframe --clone
cd seldonframe
pnpm install
pnpm dev
2

Edit a block component

Block components live at packages/crm/src/components/landing/sections/. Each is a standalone React component (hero.tsx, pricing.tsx, etc.). Edit freely; deploy.
3

Add custom blocks

Register a new block in packages/crm/src/components/landing/block-registry.tsx. It instantly becomes available to Claude Code via the MCP — the registry IS the contract.
4

Use the motion primitives

SF ships 8 composable motion primitives at packages/crm/src/components/motion/ — RevealOnScroll, Stagger, HoverLift, Counter, TextReveal, Marquee, MagneticButton, Parallax. Mix into any custom block:
import { TextReveal, Stagger, MagneticButton } from "@/components/motion";

<TextReveal as="h1" wordDelay={0.08}>
  Your custom hero headline
</TextReveal>

<Stagger className="grid gap-4 md:grid-cols-3" childDelay={0.1}>
  {features.map(f => <Card key={f.id}>{...}</Card>)}
</Stagger>

<MagneticButton strength={10}>
  Book your service
</MagneticButton>

The thin-harness, fat-skill principle

The four levers above stack because of one architectural choice: SeldonFrame doesn't hardcode "specific animations for specific blocks." That would be brittle — every new vertical needs a new preset, and the animations don't get better when models do.

Instead, the platform ships a small set of composable primitives. The skill of choosing which primitives to compose lives in Claude Code, not in our TypeScript. When an operator says "make my hero more impactful," Claude Code picks TextReveal on the headline + Stagger on CTAs + MagneticButton on the primary button + RevealOnScroll on the section below.

As frontier models improve at this composition, every workspace gets richer — without us shipping new animation code. That's antifragile. That's the bet.

The principle in one line

The platform is dumb. The skill-pack is markdown. The model gets better, your site gets better — same code, better outcome.

What's deferred (and why)

  • Renderer-level preset gating. Today the balanced set's primitives apply universally; minimal stores intent but doesn't yet short-circuit wrapping in the renderer. Ships in v1.34.x as a context provider.
  • Counter on stat blocks. No dedicated stat block exists in the current library. When one's added (or you add one), wire <Counter> into it directly.
  • Per-block motion overrides. Want editorial motion on the hero but minimal on the booking calendar? Today, you fork the section component. v1.5 ships per-block overrides via MCP.

Next