# Spotlight

> Featured-product banner on the product's own artwork field, with mark, name, pitch and call to action; scopes the product's brand so one primary button takes its colour.

Source: https://docs.nasaqui.com/components/spotlight

## Install

```bash
npx shadcn@latest add https://docs.nasaqui.com/r/spotlight.json
```

A banner that features one product. It renders the product's artwork field with its mark, name, pitch, buttons and a quiet meta line. The whole banner sits in that product's brand scope (`data-brand`), so a Mahaam spotlight shows Mahaam's colour even inside another product's store, and a primary `Button` inside it takes the product colour.

## When to use

- The hero of a store or product page (`size="lg"`).
- A compact featured tile next to or under the hero (`size="md"`).

## When not to use

- A list of products: use [`ProductCard`](https://docs.nasaqui.com/components/product-card) in a `ProductGrid`.
- A bundle: use [`BundleCard`](https://docs.nasaqui.com/components/bundle-card).
- A generic marketing hero with no product: compose your own layout.

## Import

```tsx
import { Spotlight } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"
```

## Quick start

```tsx
import { Badge, Button, Spotlight } from "@fadymondy/nasaq/web";

export function StoreHero() {
  return (
    <Spotlight
      brand="mahaam"
      title="Mahaam"
      eyebrow={<Badge variant="accent">Editor's pick</Badge>}
      description="Projects, tasks, time and invoices in one place."
      actions={
        <>
          <Button>Start free trial</Button>
          <Button variant="ghost">Details</Button>
        </>
      }
    />
  );
}
```

## Anatomy

```
Spotlight                    data-slot="spotlight", data-size="lg|md"   <section aria-labelledby>
└─ ProductArtwork            the product's field; @container
   ├─ eyebrow
   ├─ mark + title           ProductMark (or `mark`) and the heading (id for aria-labelledby)
   ├─ description
   ├─ actions
   ├─ meta
   └─ media                  size "lg" only, from 48rem of banner width
```

## API

### `Spotlight`

`SpotlightProps extends Omit<ComponentProps<"section">, "title">`. Remaining props go to the `<section>`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `brand` | `BrandKey \| (string & {})` | required | The featured product. Its manifest tints the banner and its primary button. |
| `size?` | `"lg" \| "md"` | `"lg"` | `lg` is the page hero with room for `media`. `md` is a compact tile. |
| `eyebrow?` | `ReactNode` | none | Small line above the title. A `Badge` reads well. |
| `mark?` | `ReactNode` | product mark | Replaces the `ProductMark` beside the title. |
| `title` | `ReactNode` | required | Product name; the section's heading. |
| `description?` | `ReactNode` | none | The pitch. Clamped to two lines in `md`. |
| `actions?` | `ReactNode` | none | Buttons. At most one primary in the whole view. |
| `meta?` | `ReactNode` | none | Price, trial, rating: one quiet line. |
| `media?` | `ReactNode` | none | A product glimpse beside the copy. `lg` only, from `@md` of banner width; hidden on the narrowest screens. |
| `titleAs?` | `"h1" \| "h2" \| "h3"` | `"h2"` | Heading element for the title. |
| `className?` | `string` | none | Merged onto the `<section>`. |

## Examples

### Hero with media, price and rating

```tsx
import { Badge, Button, Price, Rating, ScreenshotFrame, Spotlight } from "@fadymondy/nasaq/web";

export function Hero() {
  return (
    <Spotlight
      brand="mahaam"
      titleAs="h1"
      title="مهام"
      eyebrow={<Badge variant="accent">اختيار المحررين</Badge>}
      description="المشاريع والمهام والوقت والفواتير في مكان واحد."
      actions={
        <>
          <Button>ابدأ التجربة</Button>
          <Button variant="ghost">التفاصيل</Button>
        </>
      }
      meta={
        <>
          <Price amount={12} period="seat-month" size="sm" />
          <Rating value={4.8} count={2140} />
        </>
      }
      media={
        <ScreenshotFrame variant="window" title="Mahaam" label="Mahaam board" className="w-72">
          <div className="h-32" />
        </ScreenshotFrame>
      }
    />
  );
}
```

### Compact tile

```tsx
import { Button, Spotlight } from "@fadymondy/nasaq/web";

export function Tile() {
  return (
    <Spotlight
      size="md"
      brand="zekra"
      title="Zekra"
      description="A memory organ for AI agents."
      actions={<Button size="sm" variant="secondary">Open</Button>}
    />
  );
}
```

## Accessibility

- A `<section>` labelled by the title heading (`aria-labelledby`), so it is a named landmark region.
- The default mark is decorative (`title=""`). Put the product name in `title`.
- Pass `titleAs="h1"` when the banner is the page title; keep heading levels in order.

| Key | Action |
| --- | --- |
| `Tab` | Moves through the buttons in `actions` |
| `Enter` / `Space` | Activates the focused button |

- Localise `title`, `eyebrow`, `description`, button labels and `meta`.

## RTL & i18n

- Layout uses logical properties and grid, so the copy sits at the inline start and `media` at the end; both swap in RTL.
- Directional icons in buttons need `rtl:-scale-x-100`.
- Numbers in `meta` come from `Price` and `Rating` and follow the locale.
- No built-in strings.

## Styling & tokens

- The banner is a `ProductArtwork` field. `--nq-brand` inside the banner is the product's colour, so a primary `Button` picks it up.
- Text: `text-display` (lg title), `text-h3` (md), `text-body`, `text-caption`, `text-foreground`, `text-muted-foreground`.
- Target with `[data-slot=spotlight]` or `[data-size=md]`.
- Extend with `className`. Do not recolour with raw hex; change `brand`.

## Do / Don't

- **Do** use at most one primary button per view. In a Spotlight it takes the product colour.
- **Do** keep `meta` to one quiet line.
- **Don't** wrap the Spotlight in a bordered card.
- **Don't** put several Spotlights of different brands side by side with a primary button each.
- **Don't** pass a `title` that names a different product than `brand`.

## Related

- [ProductCard](https://docs.nasaqui.com/components/product-card) · [BundleCard](https://docs.nasaqui.com/components/bundle-card) · [ProductArtwork](https://docs.nasaqui.com/components/product-artwork) · [SectionHeader](https://docs.nasaqui.com/components/section-header)

## Lab

https://docs.nasaqui.com/?path=/docs/components-brand-spotlight--docs

## Code

### React

```tsx
import { Badge, Button, Spotlight } from "@fadymondy/nasaq/web";

export function StoreHero() {
  return (
    <Spotlight
      brand="mahaam"
      title="Mahaam"
      eyebrow={<Badge variant="accent">Editor's pick</Badge>}
      description="Projects, tasks, time and invoices in one place."
      actions={
        <>
          <Button>Start free trial</Button>
          <Button variant="ghost">Details</Button>
        </>
      }
    />
  );
}
```

### shadcn

```tsx
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Spotlight } from "@/components/ui/spotlight";

export function StoreHero() {
  return (
    <Spotlight
      brand="mahaam"
      title="Mahaam"
      eyebrow={<Badge variant="accent">Editor's pick</Badge>}
      description="Projects, tasks, time and invoices in one place."
      actions={
        <>
          <Button>Start free trial</Button>
          <Button variant="ghost">Details</Button>
        </>
      }
    />
  );
}
```

### Vue

```vue
<script setup lang="ts">
import { NqButton, NqSpotlight } from "@fadymondy/nasaq/vue";
</script>

<template>
  <NqSpotlight brand="mahaam" title="Mahaam" class="max-w-3xl">
    <template #eyebrow><span class="text-label text-muted-foreground">Editor's pick</span></template>
    <template #description>Projects, time and invoices for small studios, in one calm place.</template>
    <template #actions><NqButton>Start free</NqButton><NqButton variant="secondary">See pricing</NqButton></template>
    <template #meta><span>From $9 per month</span><span>14-day trial</span></template>
  </NqSpotlight>
</template>
```

### Blade

```blade
<x-nq::spotlight brand="mahaam" title="Mahaam" class="max-w-3xl">
    <x-slot:eyebrow><span class="text-label text-muted-foreground">Editor's pick</span></x-slot:eyebrow>
    <x-slot:description>Projects, time and invoices for small studios, in one calm place.</x-slot:description>
    <x-slot:actions><x-nq::button>Start free</x-nq::button><x-nq::button variant="secondary">See pricing</x-nq::button></x-slot:actions>
    <x-slot:meta><span>From $9 per month</span><span>14-day trial</span></x-slot:meta>
</x-nq::spotlight>
```

### HTML + Alpine

```html
<section data-slot="spotlight" data-size="lg" aria-labelledby="nq-spotlight-8b6cbfc1" class="flex max-w-3xl">
    <div data-slot="product-artwork" data-brand="mahaam" style="background-image: radial-gradient(110% 130% at var(--art-x) 0%, color-mix(in oklab, var(--nq-brand) 34%, transparent), transparent 65%),radial-gradient(90% 110% at calc(100% - var(--art-x)) 100%, color-mix(in oklab, var(--nq-brand) 14%, transparent), transparent 70%)"
    class="relative isolate flex overflow-hidden rounded-card bg-nq-surface-raised [--art-x:100%] rtl:[--art-x:0%] @container w-full items-stretch justify-stretch min-h-[22rem]">
    <span aria-hidden="true" class="pointer-events-none absolute inset-0 rounded-[inherit] ring-1 ring-inset ring-[color-mix(in_oklab,var(--nq-brand)_16%,transparent)]"></span>
            <div class="grid w-full gap-8 p-6 @md:p-8 @3xl:grid-cols-[minmax(0,1fr)_auto]">
                <div class="flex max-w-md flex-col items-start justify-center gap-4">
                    <span class="text-label text-muted-foreground">Editor's pick</span>                    <div class="flex items-center gap-3">
                        <svg data-slot="product-mark" viewBox="0 0 100 100" width="44" height="44"  aria-hidden="true"  shape-rendering="crispEdges"  class="shrink-0">
                        <rect x="25" y="25" width="25" height="25" fill="#8C3FB5" />
                    <rect x="75" y="25" width="25" height="25" fill="#C9A227" />
                    <rect x="0" y="50" width="25" height="25" fill="#8C3FB5" />
                    <rect x="50" y="50" width="25" height="25" fill="#8C3FB5" />
            </svg>
                        <h2 id="nq-spotlight-8b6cbfc1" class="text-display leading-none text-foreground">Mahaam</h2>
                    </div>
                    <div class="text-pretty text-body text-foreground/90">Projects, time and invoices for small studios, in one calm place.</div>                    <div class="flex flex-wrap items-center gap-3 pt-1"><button data-slot="button"
     type="button"                         class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border-border bg-card text-foreground hover:bg-nq-hover h-control px-[var(--nq-control-pad)]">
        Start free</button>
<button data-slot="button"
     type="button"                         class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border-border bg-card text-foreground hover:bg-nq-hover h-control px-[var(--nq-control-pad)]">
        See pricing</button></div>                    <div class="flex flex-wrap items-center gap-x-3 gap-y-1 text-caption text-muted-foreground"><span>From $9 per month</span><span>14-day trial</span></div>                </div>
                            </div>
    </div>
</section>
```
