Features

Features 03 — Ledger Features

Golden-ratio split with a sticky indexed brief beside a hairline ledger of three quantified capabilities, one expanded into a 3D-tilt A/B-test mock panel framed by a pulsing glow border, revealed with stagger over subtle grain.

$ npx shadcn@latest add @ludusvibe/features-03
Open in v0

Code

Installed to components/sections/features-03.tsx — it's yours to edit.

"use client"

import * as React from "react"
import { motion } from "motion/react"
import { ArrowUpRight } from "lucide-react"

import { GlowBorder } from "@/components/ludus/glow-border"
import { Grain } from "@/components/ludus/grain"
import { TiltCard } from "@/components/ludus/tilt-card"
import { fadeUp, stagger, viewport } from "@/lib/motion"
import { cn } from "@/lib/utils"

type Feature = {
  name: string
  benefit: string
}

export type Features03Props = {
  index?: string
  label?: string
  note?: string
  title?: React.ReactNode
  description?: string
  cta?: { label: string; href: string }
  features?: Feature[]
  /** Index (0-based) of the row that expands into the featured panel. */
  featuredIndex?: number
  featuredMetricLabel?: string
  featuredMetricValue?: string
  featuredMetricNote?: string
  /** Heading element — use "h1" when this is the page's main heading. */
  as?: "h1" | "h2"
  className?: string
}

const DEFAULT_FEATURES: Feature[] = [
  {
    name: "Funnel X-ray",
    benefit: "Maps every drop-off in your checkout within 48 hours of connecting.",
  },
  {
    name: "Experiment engine",
    benefit: "Ship A/B tests in minutes — median winner adds 12% to conversion.",
  },
  {
    name: "Revenue attribution",
    benefit: "Ties every fix to dollars: teams recover $18k/month on average.",
  },
]

export function Features03({
  index = "02",
  label = "Capabilities",
  note = "Three tools, one funnel",
  title = "Everything between a visit and a sale, instrumented.",
  description = "Find the leak, test the fix, keep the revenue — most teams ship their first winning experiment in week one.",
  cta = { label: "Explore the platform", href: "#" },
  features = DEFAULT_FEATURES,
  featuredIndex = 1,
  featuredMetricLabel = "Test 214 — Pricing page CTA",
  featuredMetricValue = "+12.4%",
  featuredMetricNote = "conversion lift · 99% significance · shipped in 6 days",
  as: Heading = "h2",
  className,
}: Features03Props) {
  return (
    <section className={cn("relative overflow-hidden bg-background", className)}>
      <Grain opacity={0.04} />

      <motion.div
        initial="hidden"
        whileInView="visible"
        viewport={viewport}
        variants={stagger(0.08)}
        className="relative mx-auto max-w-6xl px-6 py-20 md:py-28"
      >
        {/* Swiss index bar */}
        <motion.div
          variants={fadeUp}
          className="flex items-baseline justify-between border-b pb-3 text-xs tracking-[0.2em] text-muted-foreground uppercase"
        >
          <span>
            <span className="text-primary">{index}</span> — {label}
          </span>
          <span className="hidden sm:block">{note}</span>
        </motion.div>

        {/* Golden split: sticky brief / feature ledger */}
        <div className="mt-12 grid gap-x-12 gap-y-12 lg:grid-cols-[1fr_1.618fr]">
          <motion.div variants={fadeUp} className="self-start lg:sticky lg:top-24">
            <Heading className="text-[clamp(1.9rem,3.6vw,2.75rem)] leading-[1.05] font-medium tracking-tight text-balance">
              {title}
            </Heading>
            <p className="mt-5 max-w-[60ch] text-pretty text-muted-foreground">
              {description}
            </p>
            <a
              href={cta.href}
              className="mt-8 inline-flex items-center gap-1.5 text-sm font-medium text-foreground underline-offset-4 hover:text-primary hover:underline"
            >
              {cta.label}
              <ArrowUpRight className="size-4" aria-hidden />
            </a>
          </motion.div>

          {/* Feature ledger */}
          <div className="border-t">
            {features.map((feature, i) => {
              const num = String(i + 1).padStart(2, "0")

              if (i === featuredIndex) {
                return (
                  <motion.div
                    key={feature.name}
                    variants={fadeUp}
                    custom={i * 0.05}
                    className="border-b py-6"
                  >
                    <div className="grid grid-cols-[2.5rem_1fr] items-baseline gap-x-4">
                      <span className="text-xs tracking-[0.2em] text-primary uppercase">
                        {num}
                      </span>
                      <div>
                        <h3 className="font-medium">{feature.name}</h3>
                        <p className="mt-1 max-w-[60ch] text-sm text-pretty text-muted-foreground">
                          {feature.benefit}
                        </p>
                      </div>
                    </div>

                    {/* Featured mock panel */}
                    <TiltCard maxTilt={3} className="mt-6 border bg-background">
                      <GlowBorder intensity={0.4} />
                      <div aria-hidden className="p-5 md:p-6">
                        <div className="flex items-baseline justify-between text-xs tracking-[0.2em] text-muted-foreground uppercase">
                          <span>{featuredMetricLabel}</span>
                          <span className="flex items-center gap-1.5">
                            <span className="size-1.5 animate-pulse rounded-full bg-primary" />
                            Running
                          </span>
                        </div>
                        <div className="mt-5 flex flex-wrap items-end justify-between gap-6">
                          <p className="text-4xl font-medium tracking-tight md:text-5xl">
                            {featuredMetricValue}
                          </p>
                          <p className="max-w-[34ch] text-xs text-muted-foreground/70">
                            {featuredMetricNote}
                          </p>
                        </div>
                        <div className="mt-6 grid grid-cols-2 gap-px border bg-border text-xs">
                          <div className="bg-background p-3">
                            <p className="tracking-[0.2em] text-muted-foreground/70 uppercase">
                              Variant A
                            </p>
                            <div className="mt-3 flex h-12 items-end gap-1">
                              {[38, 42, 40, 45, 43, 47, 46].map((h, j) => (
                                <div
                                  key={j}
                                  style={{ height: `${h}%` }}
                                  className="flex-1 bg-muted-foreground/25"
                                />
                              ))}
                            </div>
                            <p className="mt-2 text-muted-foreground">3.1% conv.</p>
                          </div>
                          <div className="bg-background p-3">
                            <p className="tracking-[0.2em] text-primary uppercase">
                              Variant B
                            </p>
                            <div className="mt-3 flex h-12 items-end gap-1">
                              {[44, 50, 48, 56, 60, 66, 72].map((h, j) => (
                                <div
                                  key={j}
                                  style={{ height: `${h}%` }}
                                  className="flex-1 bg-primary"
                                />
                              ))}
                            </div>
                            <p className="mt-2 text-muted-foreground">
                              3.5% conv. <span className="text-primary">↑ winner</span>
                            </p>
                          </div>
                        </div>
                      </div>
                    </TiltCard>
                  </motion.div>
                )
              }

              return (
                <motion.div
                  key={feature.name}
                  variants={fadeUp}
                  custom={i * 0.05}
                  className="grid grid-cols-[2.5rem_1fr] items-baseline gap-x-4 border-b py-6"
                >
                  <span className="text-xs tracking-[0.2em] text-primary uppercase">
                    {num}
                  </span>
                  <div>
                    <h3 className="font-medium">{feature.name}</h3>
                    <p className="mt-1 max-w-[60ch] text-sm text-pretty text-muted-foreground">
                      {feature.benefit}
                    </p>
                  </div>
                </motion.div>
              )
            })}
          </div>
        </div>
      </motion.div>
    </section>
  )
}