# Product tour
> Product tour over a mock app: dithered dimming, a rounded cut-out with a comet on its edge, and a step card that moves between targets.
- Element: `<hf-spotlight>`
- React: `import { HfSpotlight } from "@/components/lumesec/hf-spotlight"`
- Collection: Pixel HD (https://elements.lumesec.ai/components/pixel-hd)
- Registry item: https://elements.lumesec.ai/r/hf-spotlight.json
- Page: https://elements.lumesec.ai/components/pixel-hd/spotlight



Live preview: https://elements.lumesec.ai/view/hf-spotlight

```html
<hf-spotlight></hf-spotlight>
```

## Installation

```bash
npx shadcn@latest add @lumesec/hf-spotlight
```

First time with the @lumesec registry? Register it once, or install by URL:

```bash
npx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.json
npx shadcn@latest add https://elements.lumesec.ai/r/hf-spotlight.json
```

## Usage

React:

```tsx
import { HfSpotlight } from "@/components/lumesec/hf-spotlight";

export function Example() {
  return (
    <HfSpotlight />
  );
}
```

HTML:

```html
<script type="module" src="https://elements.lumesec.ai/cdn/hf-spotlight.js"></script>

<hf-spotlight></hf-spotlight>
```

## Behaviour

Dims the interface with dither, cuts a rounded hole around each step’s target with a comet on its edge, and springs between steps.

## API reference

### Events

Events bubble and cross the shadow boundary unless the description says otherwise.

| Event    | React prop | Detail                             | Description                                            |
| -------- | ---------- | ---------------------------------- | ------------------------------------------------------ |
| `step`   | `onStep`   | `{ index: number, title: string }` | Fires each time a step is shown.                       |
| `finish` | `onFinish` | `{}`                               | Fires when the tour ends through Done, Skip or Escape. |

### Methods

Call them on the element, for example through a React ref.

| Method              | Description                                                                        |
| ------------------- | ---------------------------------------------------------------------------------- |
| `go(index: number)` | Shows step `index` (0 to 3); 4 or more ends the tour. Negative values are ignored. |

## Keyboard

| Keys                   | Action                                      |
| ---------------------- | ------------------------------------------- |
| ArrowRight / ArrowLeft | While the tour runs: next or previous step. |
| Escape                 | While the tour runs: end the tour.          |

## Accessibility

* The mock interface is a `role="region"` labelled `Product tour demo`; its buttons are outside the tab order.
* The step card has `role="dialog"` and `aria-live="polite"`; it is not modal.
* Focus moves to Next on every step and to the start button when the tour ends. Back is disabled on the first step.
* The dimming and cut-out are drawn on an `aria-hidden` canvas.
* Reduced motion: the dimming appears at once, the cut-out jumps to each target without easing and the comet is not drawn; the step card still slides.

## Theming

The element reads your shadcn theme tokens through its shadow root, so light and dark follow your theme. The accent comes from `--lumesec`. See [Theming](/docs/theming).

This component reads `--border`, `--card`, `--foreground`, `--lumesec`, `--lumesec-foreground`, `--muted` and `--muted-foreground`.

To restyle only LumeSec elements, set the matching `--ui-*` overrides: `--ui-accent`, `--ui-border`, `--ui-fg`, `--ui-muted`, `--ui-on-accent`, `--ui-raised`, `--ui-surface` and `--ui-track`.

## Notes

* The mock app and its four steps are built in. The tour targets elements inside the component and cannot point at your page.
* The frame is 236px tall. Next reads Done on the last step.


