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
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.mode → OrgTheme.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
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:
Fork the repo
gh repo fork seldonframe/seldonframe --clone
cd seldonframe
pnpm install
pnpm devEdit a block component
packages/crm/src/components/landing/sections/. Each is a standalone React component (hero.tsx, pricing.tsx, etc.). Edit freely; deploy.Add custom blocks
packages/crm/src/components/landing/block-registry.tsx. It instantly becomes available to Claude Code via the MCP — the registry IS the contract.Use the motion primitives
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
What's deferred (and why)
- Renderer-level preset gating. Today the
balancedset's primitives apply universally;minimalstores 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
editorialmotion on the hero butminimalon the booking calendar? Today, you fork the section component. v1.5 ships per-block overrides via MCP.