# Bento Closer Look

> A feature spotlight that pairs an auto-advancing accordion of features with a matching cross-fading image.

A shadcn/ui block from the [@esuiss](https://suiss.app/ui?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/esuiss/bento-closer-look).

- Page, with a live preview: https://shadcn.exchange/r/esuiss/bento-closer-look
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/esuiss/bento-closer-look-light-0def204e08ec12bc.png
- Registry item: https://suiss.app/ui/r/new-york-v4/bento-closer-look.json
- Categories: blocks, bento
- Listed: 2026-10-20, source last changed 2026-10-20

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/esuiss/bento-closer-look.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `@esuiss/accordion`

## Files

### `bases/radix/components/blocks/bento-closer-look.tsx`

```tsx
"use client"

import * as React from "react"

import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion"

const photo = (id: string) =>
  `https://images.unsplash.com/photo-${id}?w=1000&q=80&auto=format&fit=crop`

type Feature = {
  title: string
  description: string
  image: string
  alt: string
}

const features: [Feature, ...Feature[]] = [
  {
    title: "Camera Control",
    description:
      "A faster way to take photos. Slide to zoom, press lightly to focus.",
    image: photo("1714972384975-fbd4f19b1bb3"),
    alt: "An orange phone on a warm gradient",
  },
  {
    title: "Fusion camera",
    description:
      "Three rear cameras capture detail at every angle with 48 MP resolution.",
    image: photo("1604677209244-6569d050557a"),
    alt: "A camera lens lit in red and pink",
  },
  {
    title: "Aluminum body",
    description: "A unibody design that spreads heat better and weighs less.",
    image: photo("1664883410931-2edffc8be5e6"),
    alt: "A silver phone on a light grey background",
  },
  {
    title: "New colors",
    description: "Cosmic Orange, Deep Blue and Silver.",
    image: photo("1633596683562-4a47eb4983c5"),
    alt: "Layered orange paper waves",
  },
]

export function BentoCloserLook() {
  const [active, setActive] = React.useState(features[0].title)
  const [auto, setAuto] = React.useState(true)

  React.useEffect(() => {
    if (!auto) return
    const timer = window.setInterval(() => {
      setActive((current) => {
        const index = features.findIndex((item) => item.title === current)
        return features[(index + 1) % features.length]?.title ?? current
      })
    }, 4000)
    return () => window.clearInterval(timer)
  }, [auto])

  return (
    <section className="flex flex-col gap-6 bg-muted p-5 md:p-8">
      <h2 className="text-4xl font-semibold tracking-tight md:text-5xl">
        Take a closer look.
      </h2>
      <div className="grid overflow-hidden rounded-[1.75rem] bg-background md:min-h-117 md:grid-cols-[minmax(16rem,0.8fr)_1.2fr]">
        <Accordion
          type="single"
          value={active}
          onValueChange={(value: string) => {
            setAuto(false)
            if (value) setActive(value)
          }}
          className="order-2 justify-center gap-1.5 p-4 md:order-1 md:py-7 md:ps-7 md:pe-4.5"
        >
          {features.map((feature) => (
            <AccordionItem
              key={feature.title}
              value={feature.title}
              className="ms-0 rounded-[1.125rem] px-5 not-first:border-t-0 transition-[background-color,padding] duration-400 ease-[cubic-bezier(0.32,0.72,0,1)] data-open:bg-muted data-open:py-2 motion-reduce:transition-none"
            >
              <AccordionTrigger className="justify-start gap-2.5 pe-0 text-lg font-semibold hover:no-underline **:data-[slot=accordion-trigger-icon]:hidden">
                <span className="flex size-6.5 shrink-0 items-center justify-center rounded-full bg-secondary text-secondary-foreground transition-[rotate,background-color,color] duration-350 ease-[cubic-bezier(0.32,0.72,0,1)] group-aria-expanded/accordion-trigger:rotate-45 group-aria-expanded/accordion-trigger:bg-foreground group-aria-expanded/accordion-trigger:text-background motion-reduce:transition-none">
                  <IconPlaceholder
                    lucide="PlusIcon"
                    tabler="IconPlus"
                    hugeicons="PlusSignIcon"
                    phosphor="PlusIcon"
                    remixicon="RiAddLine"
                    className="size-3.5"
                  />
                </span>
                {feature.title}
              </AccordionTrigger>
              <AccordionContent className="ps-9 pe-0 text-base leading-normal">
                {feature.description}
              </AccordionContent>
            </AccordionItem>
          ))}
        </Accordion>
        <div className="relative order-1 m-4 aspect-4/3 overflow-hidden rounded-[1.25rem] bg-secondary md:order-2 md:aspect-auto">
          {features.map((feature) => (
            <img
              key={feature.title}
              src={feature.image}
              alt={feature.alt}
              aria-hidden={feature.title !== active}
              data-active={feature.title === active ? "" : undefined}
              className="absolute inset-0 size-full scale-104 object-cover opacity-0 transition-[opacity,scale] duration-[700ms,1200ms] ease-[ease,cubic-bezier(0.32,0.72,0,1)] data-active:scale-100 data-active:opacity-100 motion-reduce:transition-none"
            />
          ))}
        </div>
      </div>
    </section>
  )
}
```
