{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "bento-features",
  "title": "Bento features",
  "description": "A features section as a bento grid of Tiles, with one inverted lead tile for the feature that matters most.",
  "registryDependencies": [
    "utils",
    "@manniche/data-tile"
  ],
  "files": [
    {
      "path": "registry/manniche/bento-features/bento-features.tsx",
      "content": "// Bento features: a section heading over a bento of feature tiles. The first feature is the lead tile: it spans two\n// columns and two rows on wide boxes and is the inverted tile, so the one thing the page is about is lifted. Every\n// tile has a title, one sentence and a visual slot you fill with whatever you like (DOM, SVG, a figure).\n//\n// How it reads: one `h2` for the section, a real list of features, and each tile is its own labelled region with an\n// `h3`. The visual slot is decorative by default and hidden from screen readers; the sentence carries the meaning.\n// Layout follows the box the section sits in (container queries): one column, then two, then a 3 x 3 bento.\n// Motion: none of its own. Visuals you pass in decide that and should respect reduced motion.\nimport { useId, type ComponentProps, type ReactNode } from 'react'\nimport { cn } from '@/lib/utils'\nimport { DataTile } from '@/registry/manniche/data-tile/data-tile'\n\nexport type BentoFeature = {\n  /** A stable key for the tile. */\n  id: string\n  /** The tile's name, shown as an `h3`. */\n  title: ReactNode\n  /** One sentence that says what the feature does for the reader. */\n  description: ReactNode\n  /** A small visual for the tile: DOM, SVG or a figure. Hidden from screen readers unless `visualLabel` is set. */\n  visual?: ReactNode\n  /** Names the visual for screen readers. Leave it out when the visual only decorates the sentence. */\n  visualLabel?: string\n}\n\nexport type BentoFeaturesProps = Omit<ComponentProps<'section'>, 'children' | 'title'> & {\n  /** The section's `h2`. */\n  heading: ReactNode\n  /** A short line under the heading. */\n  intro?: ReactNode\n  /** A small mono label above the heading, such as \"Features\". */\n  eyebrow?: ReactNode\n  /** The features, lead first. Six fill the bento exactly; other counts reflow without holes at the ends. */\n  features: readonly BentoFeature[]\n}\n\nexport function BentoFeatures({ heading, intro, eyebrow, features, className, ...rest }: BentoFeaturesProps) {\n  const headingId = useId()\n  return (\n    <section aria-labelledby={headingId} className={cn('@container w-full py-12 @3xl:py-20', className)} {...rest}>\n      <div className=\"mx-auto max-w-6xl px-4 sm:px-6\">\n        <header className=\"mb-8 grid max-w-2xl gap-3 @3xl:mb-12\">\n          {eyebrow && <p className=\"font-mono text-xs tracking-[0.04em] text-muted-foreground tabular-nums\">{eyebrow}</p>}\n          <h2\n            id={headingId}\n            className=\"text-[clamp(30px,5.4cqw,52px)] leading-[1.02] font-extrabold tracking-[-0.035em] text-balance text-foreground\"\n            style={{ fontFamily: 'var(--font-display, inherit)', fontStretch: '86%' }}\n          >\n            {heading}\n          </h2>\n          {intro && <p className=\"text-base leading-relaxed text-pretty text-muted-foreground\">{intro}</p>}\n        </header>\n        <ul className=\"grid list-none grid-cols-1 gap-3 p-0 @2xl:grid-cols-2 @2xl:gap-4 @4xl:grid-cols-3\">\n          {features.map((f, i) => {\n            const lead = i === 0\n            return (\n              <li\n                key={f.id}\n                className={cn(\n                  'flex min-w-0',\n                  lead && '@2xl:col-span-2 @4xl:row-span-2',\n                  // An odd tile at the end of the two-up layout takes the full row; the 3-up layout needs no help.\n                  i === features.length - 1 && i % 2 === 1 && '@2xl:col-span-2 @4xl:col-span-1',\n                )}\n              >\n                <DataTile title={f.title} inverted={lead} className=\"w-full\">\n                  <div className={cn('flex h-full flex-col gap-5', lead && '@4xl:gap-8')}>\n                    {f.visual && (\n                      <div\n                        role={f.visualLabel ? 'img' : undefined}\n                        aria-label={f.visualLabel}\n                        aria-hidden={f.visualLabel ? undefined : true}\n                        className={cn(\n                          'relative min-h-32 flex-1 overflow-hidden rounded-[14px] bg-muted',\n                          lead && 'min-h-48 @4xl:min-h-72',\n                        )}\n                      >\n                        {f.visual}\n                      </div>\n                    )}\n                    <p\n                      className={cn(\n                        'text-pretty text-muted-foreground',\n                        lead ? 'max-w-prose text-base leading-relaxed' : 'text-[15px] leading-normal',\n                      )}\n                    >\n                      {f.description}\n                    </p>\n                  </div>\n                </DataTile>\n              </li>\n            )\n          })}\n        </ul>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "categories": [
    "templates"
  ],
  "type": "registry:block"
}