# FeedbackReporter

> The interface around the feedback dialog. A floating launcher as a pill, circle or edge tab that visitors can drag aside, a hub of reports already made on this page, a launcher configurator with install code, and a shake-to-report sheet for phones.

Source: https://docs.nasaqui.com/components/feedback-reporter

## Install

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

Everything around a feedback dialog that a design system can own. The dialog itself, with screenshot capture, the
element picker and the console and network log, already exists in the `@nasaq/feedback` package (`ReportDialog`,
`FeedbackLauncher`, `mahaamSubmitter`). This component does not repeat it: it adds the floating launcher, the list of
reports already made on the page, the launcher configurator with its install code, and the shake-to-report sheet. Open
`ReportDialog` from any of them.

## When to use

- A persistent "Feedback" control on a product or a client's site.
- Showing visitors what has been reported on the page, so they vote instead of duplicating.
- Letting a mobile user shake the phone to report.

## When not to use

- Capturing the report (title, screenshot, logs): use `ReportDialog` from `@nasaq/feedback`.
- Live support chat: use [`ChatWidget`](https://docs.nasaqui.com/components/chat-widget).

## Import

```tsx
import { FeedbackFloatingLauncher, FeedbackHub } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"; the dialog comes from "@nasaq/feedback"
```

## Quick start

```tsx
import { ReportDialog, mahaamSubmitter, submit } from "@nasaq/feedback";
import { FeedbackFloatingLauncher } from "@fadymondy/nasaq/web";
import { useState } from "react";

const target = mahaamSubmitter(process.env.NEXT_PUBLIC_MAHAAM_FEEDBACK_KEY!);

export function Feedback() {
  const [open, setOpen] = useState(false);
  return (
    <>
      <FeedbackFloatingLauncher shape="pill" position="bottom-end" onClick={() => setOpen(true)} />
      <ReportDialog open={open} onOpenChange={setOpen} onSubmit={(report) => submit(target, report)} />
    </>
  );
}
```

## Anatomy

```
FeedbackFloatingLauncher      data-slot="feedback-launcher" (data-shape, data-position or data-side, data-movable, data-dragging)
FeedbackHub                   data-slot="feedback-hub": header, status / Mine filter, report list with votes, Load more
FeedbackLauncherConfigurator  data-slot="feedback-configurator": shape, position, text, preview, install code
ShakeReportSheet              data-slot="shake-report-sheet": bottom sheet, report, not now, setting
useShakeToReport              devicemotion listener, counts jolts
```

## API

**FeedbackFloatingLauncher**: button props except `children` and `type`, plus `shape` (`"pill" | "circle" | "tab"`), `position` (`"bottom-end" | "bottom-start" | "top-end" | "top-start" | "edge-end" | "edge-start"`), `label`, `count`, `placement` (`"fixed"`), `icon`. A tab always sits on an edge and a pill or circle never does: `normalizePosition` settles a mismatch.

With `movable` the visitor can drag the launcher out of the way. On release it snaps to the nearer side and keeps its height (`FeedbackLauncherSpot`: `{ side: "start" | "end", y }`, `y` a fraction of the height); a drag never counts as a click. Alt + arrow keys move it too. The spot is saved in `localStorage` under `storageKey` (default `"nasaq-feedback-launcher"`, `null` to keep it in memory) and read back after mount. `spot` makes it controlled, `defaultSpot` sets the first one, `onSpotChange(spot)` reports drops and key moves.

**FeedbackHub**: `issues` (`FeedbackHubIssue[]`: `id`, `title`, `status` `"open" | "in-progress" | "resolved"`, `createdAt`, `votes`, `voted`, `author`), `page`, `onVote(id)`, `onReportNew`, `onOpenIssue(id)`, `labels`. Issues with `mine: true` are the visitor's own: they get a "Yours" badge and a **Mine** tab (`mineTab` forces it on or off).

For a server-paged list pass the first page as `issues`, the totals as `counts` (`{ all, open, "in-progress", resolved, mine }`), refetch on `onFilterChange(filter)`, and set `hasMore`, `onLoadMore` and `loadingMore` for the **Load more** row.

**FeedbackLauncherConfigurator**: `value` (`{ shape, position, label }`), `onChange`, `labels`.

**ShakeReportSheet**: `open`, `onOpenChange`, `onReport`, `enabled`, `onEnabledChange`, `labels`.

**useShakeToReport({ onShake, enabled, threshold, jolts, cooldown })** returns `{ supported, permission, requestPermission }`. On iOS call `requestPermission()` from a tap.

Pure helpers in `feedback-reporter-utils.ts`: `feedbackInstallSnippet`, `normalizePosition`, `isShake`, `motionDelta`, `countByStatus`, `filterHubIssues`, and for the movable launcher `snapLauncherSpot`, `moveLauncherSpot`, `spotFromPosition`, `parseLauncherSpot`.

## Examples

**Shake to report**

```tsx
const [sheet, setSheet] = useState(false);
const shake = useShakeToReport({ onShake: () => setSheet(true) });
// on iOS: <Button onClick={shake.requestPermission}>Enable shake</Button>
<ShakeReportSheet open={sheet} onOpenChange={setSheet} onReport={() => setDialog(true)} />;
```

## Accessibility

- The launcher is a real button with a name (the circle gets an `aria-label`). A movable one also moves with Alt + arrow keys (`aria-keyshortcuts`, and a title that says so). The status filter is a labelled toggle group and votes are pressed-state buttons.
- The sheet is a dialog: focus is trapped and Escape closes it. Shaking is optional and can be switched off from the sheet.

## RTL & i18n

- English and Arabic follow the locale. `end` and `start` positions flip in Arabic, and the tab text turns the right way for its side. The page address stays left-to-right.

## Styling & tokens

- Uses `bg-primary`, `shadow-floating`, card and border tokens. Target `[data-slot="feedback-launcher"]`, `[data-slot="feedback-hub"]`.

## Do / Don't

- Do keep the public feedback key in an environment variable. The install code reads it from one.
- Do show the hub before the dialog when a page already has reports.
- Don't put a floating launcher over a primary action: move it to the other side, or make it `movable`.
- Don't rely on shaking alone: it is not available on desktops or when motion access is refused.

## Related

- [`Sheet`](https://docs.nasaqui.com/components/sheet)
- [`Dialog`](https://docs.nasaqui.com/components/dialog)
- [`ChatWidget`](https://docs.nasaqui.com/components/chat-widget)

## Code

### React

```tsx
import { ReportDialog, mahaamSubmitter, submit } from "@nasaq/feedback";
import { FeedbackFloatingLauncher } from "@fadymondy/nasaq/web";
import { useState } from "react";

const target = mahaamSubmitter(process.env.NEXT_PUBLIC_MAHAAM_FEEDBACK_KEY!);

export function Feedback() {
  const [open, setOpen] = useState(false);
  return (
    <>
      <FeedbackFloatingLauncher shape="pill" position="bottom-end" onClick={() => setOpen(true)} />
      <ReportDialog open={open} onOpenChange={setOpen} onSubmit={(report) => submit(target, report)} />
    </>
  );
}
```

### shadcn

```tsx
import { ReportDialog, mahaamSubmitter, submit } from "@nasaq/feedback";
import { FeedbackFloatingLauncher } from "@/components/ui/feedback-reporter";
import { useState } from "react";

const target = mahaamSubmitter(process.env.NEXT_PUBLIC_MAHAAM_FEEDBACK_KEY!);

export function Feedback() {
  const [open, setOpen] = useState(false);
  return (
    <>
      <FeedbackFloatingLauncher shape="pill" position="bottom-end" onClick={() => setOpen(true)} />
      <ReportDialog open={open} onOpenChange={setOpen} onSubmit={(report) => submit(target, report)} />
    </>
  );
}
```

### Vue

```vue
<script setup lang="ts">
import { NqFeedbackFloatingLauncher } from "@fadymondy/nasaq/vue";
import { ref } from "vue";

// Open your report dialog from the click (the dialog itself comes from your feedback SDK).
const open = ref(false);
</script>

<template>
  <div class="relative h-40">
    <NqFeedbackFloatingLauncher shape="pill" position="bottom-end" placement="absolute" @click="open = true" />
    <p v-if="open" class="text-body-sm">Report dialog open</p>
  </div>
</template>
```

### Blade

```blade
{{-- The launcher only draws the button: open your own report dialog from its click. The parts around it follow. --}}
<div class="flex flex-col gap-6">
    <div class="relative h-40">
        <x-nq::feedback-reporter shape="pill" position="bottom-end" placement="absolute" x-on:click="$dispatch('nq-report-open')" />
    </div>
    <div class="relative h-40 rounded-card border border-border">
        <x-nq::feedback-reporter shape="circle" placement="absolute" movable storage-key="" x-on:click="$dispatch('nq-report-open')" />
    </div>

    <x-nq::feedback-reporter.hub
        page="/checkout"
        :can-open="true"
        :has-more="true"
        :counts="['all' => 9]"
        :issues="[
            ['id' => 'a', 'title' => 'Cannot pay by card', 'status' => 'open', 'votes' => 4, 'author' => 'Sara', 'createdAt' => '2025-01-01T10:00:00Z'],
            ['id' => 'd', 'title' => 'Coupon is not applied', 'status' => 'open', 'votes' => 2, 'author' => 'Me', 'mine' => true],
            ['id' => 'b', 'title' => 'Page is slow', 'status' => 'in-progress', 'votes' => 1, 'voted' => true],
            ['id' => 'c', 'title' => 'Typo in the footer', 'status' => 'resolved', 'votes' => 0],
        ]"
        x-on:nq-feedback-vote="$event.detail.waitUntil(new Promise((done) => setTimeout(done, 50)))" />

    <x-nq::feedback-reporter.configurator shape="pill" position="bottom-end" label="Feedback" />

    <x-nq::feedback-reporter.shake-sheet setting />
</div>
```

### HTML + Alpine

```html
<div class="flex flex-col gap-6">
    <div class="relative h-40">
        <button type="button" data-slot="feedback-launcher" data-shape="pill"  data-position="bottom-end"             x-on:click="$dispatch(&#039;nq-report-open&#039;)" class="z-40 inline-flex items-center justify-center gap-2 bg-primary text-label text-primary-foreground shadow-floating outline-none transition-[filter,translate] duration-150 ease-nq hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus absolute bottom-4 end-4 h-control rounded-full px-4">
    <svg aria-hidden="true" class="size-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"/>
  <path d="M12 8v6"/>
  <path d="M9 11h6"/>
</svg>    <span class="">Feedback</span>    </button>
    </div>
    <div class="relative h-40 rounded-card border border-border">
        <button type="button" data-slot="feedback-launcher" data-shape="circle"  data-position="bottom-end"      x-data="nqFeedbackLauncher(JSON.parse('{\u0022storageKey\u0022:null,\u0022spot\u0022:null,\u0022position\u0022:\u0022bottom-end\u0022,\u0022placement\u0022:\u0022absolute\u0022,\u0022shape\u0022:\u0022circle\u0022,\u0022positionClass\u0022:\u0022bottom-4 end-4\u0022}'))" data-movable aria-keyshortcuts="Alt+ArrowUp Alt+ArrowDown Alt+ArrowLeft Alt+ArrowRight" title="Drag to move it out of the way. Alt + arrow keys move it too."
        x-bind:data-position="spot ? null : where" x-bind:data-side="spot ? spot.side : null" x-bind:data-dragging="dragAt ? 'true' : null" x-bind:class="classes" x-bind:style="placed"
        x-on:pointerdown="down($event)" x-on:pointermove="move($event)" x-on:pointerup="up($event)" x-on:pointercancel="cancel()" x-on:keydown="key($event)" x-on:click.capture="click($event)"
                         aria-label="Feedback"     x-on:click="$dispatch(&#039;nq-report-open&#039;)" class="z-40 inline-flex items-center justify-center gap-2 bg-primary text-label text-primary-foreground shadow-floating outline-none transition-[filter,translate] duration-150 ease-nq hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus bottom-4 end-4 touch-none relative size-12 rounded-full">
    <svg aria-hidden="true" class="size-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"/>
  <path d="M12 8v6"/>
  <path d="M9 11h6"/>
</svg>        </button>
    </div>
    <section data-slot="feedback-hub" aria-label="Reports on this page" x-data="nqFeedbackHub(JSON.parse('{\u0022counts\u0022:{\u0022all\u0022:9,\u0022open\u0022:2,\u0022in-progress\u0022:1,\u0022resolved\u0022:1,\u0022mine\u0022:1},\u0022showing\u0022:\u0022Showing {shown} of {total}\u0022}'))"
    x-on:nq-feedback-vote="$event.detail.waitUntil(new Promise((done) =&gt; setTimeout(done, 50)))" class="flex w-full max-w-2xl flex-col gap-4 rounded-card border border-border bg-card p-4">
    <header class="flex items-start justify-between gap-3">
        <div class="flex min-w-0 flex-col gap-1">
            <h2 class="text-h3">Reports on this page</h2>
            <p class="text-body-sm text-muted-foreground">What other people already told us about this page. Add your vote instead of sending a duplicate.</p>
                            <p class="text-caption text-muted-foreground">Page <bdi dir="ltr" class="font-mono text-foreground">/checkout</bdi></p>
                    </div>
                    <button data-slot="button"
     type="button"                         x-on:click="reportNew()" class="inline-flex select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border border-transparent 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 bg-primary text-primary-foreground hover:bg-[color-mix(in_oklab,var(--nq-action)_88%,var(--nq-fg))] h-control-sm px-2.5 shrink-0">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M12 20v-9"/>
  <path d="M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z"/>
  <path d="M14.12 3.88 16 2"/>
  <path d="M21 21a4 4 0 0 0-3.81-4"/>
  <path d="M21 5a4 4 0 0 1-3.55 3.97"/>
  <path d="M22 13h-4"/>
  <path d="M3 21a4 4 0 0 1 3.81-4"/>
  <path d="M3 5a4 4 0 0 0 3.55 3.97"/>
  <path d="M6 13H2"/>
  <path d="m8 2 1.88 1.88"/>
  <path d="M9 7.13V6a3 3 0 1 1 6 0v1.13"/>
</svg>Report a problem</button>
            </header>
    <div role="group" data-slot="toggle-group" data-variant="segmented" data-orientation="horizontal"
    x-data="nqToggleGroup(JSON.parse('[\u0022all\u0022]'), false)" x-modelable="value" x-bind="root"
            x-model="filter" aria-label="Filter by status" class="flex w-fit max-w-full gap-0.5 rounded-control bg-secondary p-0.5 flex-wrap">
    <button type="button" data-slot="toggle" aria-pressed="true"
     x-bind="toggle('all')"      data-pressed         class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">All<span class="text-caption tabular-nums opacity-70">9</span></button>
                    <button type="button" data-slot="toggle" aria-pressed="false"
     x-bind="toggle('open')"             class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">Open<span class="text-caption tabular-nums opacity-70">2</span></button>
                    <button type="button" data-slot="toggle" aria-pressed="false"
     x-bind="toggle('in-progress')"             class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">In progress<span class="text-caption tabular-nums opacity-70">1</span></button>
                    <button type="button" data-slot="toggle" aria-pressed="false"
     x-bind="toggle('resolved')"             class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">Resolved<span class="text-caption tabular-nums opacity-70">1</span></button>
                    <button type="button" data-slot="toggle" aria-pressed="false"
     x-bind="toggle('mine')"             class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">Mine<span class="text-caption tabular-nums opacity-70">1</span></button>
</div>
            <ul role="list" aria-label="Reports on this page" x-show="visible() > 0" class="flex flex-col rounded-control border border-border">
                                            <li data-id="a" data-status="open"  x-show="shows('open', false)" class="flex items-start gap-3 border-t border-border p-3 first:border-t-0">
                    <div class="flex min-w-0 flex-1 flex-col gap-1">
                                                    <button type="button" dir="auto" x-on:click="open(0)" class="w-fit max-w-full truncate rounded-control text-start text-label underline-offset-4 outline-none hover:underline focus-visible:outline-2 focus-visible:outline-nq-focus">Cannot pay by card</button>
                                                <span class="flex flex-wrap items-center gap-x-2 gap-y-1 text-caption text-muted-foreground">
                            <span data-slot="badge"     class="inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-[4px] border px-1.5 text-caption font-medium [&_svg]:size-3 border-border bg-secondary text-foreground">Open</span>
                            <span dir="auto">by Sara</span>                            <time data-slot="date-time" datetime="2025-01-01T10:00:00+00:00" dir="auto"  title="Jan 1, 2025"     class="tabular-nums [unicode-bidi:isolate]">1 year ago</time>
                        </span>
                    </div>
                                            <button data-slot="button"
     type="button"                         aria-pressed="false" title="4 people have this" x-on:click="vote(0)" x-bind:disabled="blocked(0, false)" x-bind:aria-busy="busy === 0 ? &#039;true&#039; : null" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border border-transparent 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 text-foreground hover:bg-nq-hover h-control-sm px-2.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"/>
  <path d="M7 10v12"/>
</svg>                            <span>Me too</span>
                            <span class="tabular-nums text-muted-foreground">4</span></button>
                                    </li>
                                            <li data-id="d" data-status="open"  data-mine  x-show="shows('open', true)" class="flex items-start gap-3 border-t border-border p-3 first:border-t-0">
                    <div class="flex min-w-0 flex-1 flex-col gap-1">
                                                    <button type="button" dir="auto" x-on:click="open(1)" class="w-fit max-w-full truncate rounded-control text-start text-label underline-offset-4 outline-none hover:underline focus-visible:outline-2 focus-visible:outline-nq-focus">Coupon is not applied</button>
                                                <span class="flex flex-wrap items-center gap-x-2 gap-y-1 text-caption text-muted-foreground">
                            <span data-slot="badge"     class="inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-[4px] border px-1.5 text-caption font-medium [&_svg]:size-3 border-border bg-secondary text-foreground">Open</span>
                            <span data-slot="badge"     class="inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-[4px] border px-1.5 text-caption font-medium [&_svg]:size-3 border-border bg-secondary text-foreground">Yours</span>
                                                    </span>
                    </div>
                                            <button data-slot="button"
     type="button"                         aria-pressed="false" title="2 people have this" x-on:click="vote(1)" x-bind:disabled="blocked(1, false)" x-bind:aria-busy="busy === 1 ? &#039;true&#039; : null" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border border-transparent 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 text-foreground hover:bg-nq-hover h-control-sm px-2.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"/>
  <path d="M7 10v12"/>
</svg>                            <span>Me too</span>
                            <span class="tabular-nums text-muted-foreground">2</span></button>
                                    </li>
                                            <li data-id="b" data-status="in-progress"  x-show="shows('in-progress', false)" class="flex items-start gap-3 border-t border-border p-3 first:border-t-0">
                    <div class="flex min-w-0 flex-1 flex-col gap-1">
                                                    <button type="button" dir="auto" x-on:click="open(2)" class="w-fit max-w-full truncate rounded-control text-start text-label underline-offset-4 outline-none hover:underline focus-visible:outline-2 focus-visible:outline-nq-focus">Page is slow</button>
                                                <span class="flex flex-wrap items-center gap-x-2 gap-y-1 text-caption text-muted-foreground">
                            <span data-slot="badge"     class="inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-[4px] border px-1.5 text-caption font-medium [&_svg]:size-3 border-nq-info/40 bg-nq-info-soft text-nq-info-text">In progress</span>
                                                                                </span>
                    </div>
                                            <button data-slot="button"
     type="button"                  disabled      data-disabled     aria-pressed="true" title="1 people have this" x-on:click="vote(2)" x-bind:disabled="blocked(2, true)" x-bind:aria-busy="busy === 2 ? &#039;true&#039; : null" 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-sm px-2.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg>                            <span>You said this too</span>
                            <span class="tabular-nums text-muted-foreground">1</span></button>
                                    </li>
                                            <li data-id="c" data-status="resolved"  x-show="shows('resolved', false)" class="flex items-start gap-3 border-t border-border p-3 first:border-t-0">
                    <div class="flex min-w-0 flex-1 flex-col gap-1">
                                                    <button type="button" dir="auto" x-on:click="open(3)" class="w-fit max-w-full truncate rounded-control text-start text-label underline-offset-4 outline-none hover:underline focus-visible:outline-2 focus-visible:outline-nq-focus">Typo in the footer</button>
                                                <span class="flex flex-wrap items-center gap-x-2 gap-y-1 text-caption text-muted-foreground">
                            <span data-slot="badge"     class="inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-[4px] border px-1.5 text-caption font-medium [&_svg]:size-3 border-nq-success/40 bg-nq-success-soft text-nq-success-text">Resolved</span>
                                                                                </span>
                    </div>
                                            <button data-slot="button"
     type="button"                  disabled      data-disabled     aria-pressed="false" title="0 people have this" x-on:click="vote(3)" x-bind:disabled="blocked(3, true)" x-bind:aria-busy="busy === 3 ? &#039;true&#039; : null" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border border-transparent 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 text-foreground hover:bg-nq-hover h-control-sm px-2.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"/>
  <path d="M7 10v12"/>
</svg>                            <span>Me too</span>
                            <span class="tabular-nums text-muted-foreground">0</span></button>
                                    </li>
                    </ul>
            <div data-slot="empty-state" style="display: none;" x-show="visible() === 0 &amp;&amp; current() === &#039;all&#039;" class="flex flex-col items-center justify-center gap-3 border border-dashed border-border px-6 text-center rounded-card py-8">
            <span data-slot="state-icon" class="inline-flex size-10 items-center justify-center rounded-control border border-border bg-card [&amp;_svg]:size-5 text-muted-foreground">
            <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M12 20v-9"/>
  <path d="M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z"/>
  <path d="M14.12 3.88 16 2"/>
  <path d="M21 21a4 4 0 0 0-3.81-4"/>
  <path d="M21 5a4 4 0 0 1-3.55 3.97"/>
  <path d="M22 13h-4"/>
  <path d="M3 21a4 4 0 0 1 3.81-4"/>
  <path d="M3 5a4 4 0 0 0 3.55 3.97"/>
  <path d="M6 13H2"/>
  <path d="m8 2 1.88 1.88"/>
  <path d="M9 7.13V6a3 3 0 1 1 6 0v1.13"/>
</svg>        </span>
        <div class="flex max-w-sm flex-col gap-1">
        <p class="text-label text-foreground">Nothing reported here</p>
                    <p class="text-body-sm text-muted-foreground">No one has reported a problem on this page yet.</p>
            </div>
    </div>
    <div data-slot="empty-state" style="display: none;" x-show="visible() === 0 &amp;&amp; current() === &#039;mine&#039;" class="flex flex-col items-center justify-center gap-3 border border-dashed border-border px-6 text-center rounded-card py-8">
            <span data-slot="state-icon" class="inline-flex size-10 items-center justify-center rounded-control border border-border bg-card [&amp;_svg]:size-5 text-muted-foreground">
            <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M12 20v-9"/>
  <path d="M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z"/>
  <path d="M14.12 3.88 16 2"/>
  <path d="M21 21a4 4 0 0 0-3.81-4"/>
  <path d="M21 5a4 4 0 0 1-3.55 3.97"/>
  <path d="M22 13h-4"/>
  <path d="M3 21a4 4 0 0 1 3.81-4"/>
  <path d="M3 5a4 4 0 0 0 3.55 3.97"/>
  <path d="M6 13H2"/>
  <path d="m8 2 1.88 1.88"/>
  <path d="M9 7.13V6a3 3 0 1 1 6 0v1.13"/>
</svg>        </span>
        <div class="flex max-w-sm flex-col gap-1">
        <p class="text-label text-foreground">You have not reported anything</p>
                    <p class="text-body-sm text-muted-foreground">Reports you send from this page show up here, with their status.</p>
            </div>
    </div>
    <div data-slot="empty-state" style="display: none;" x-show="visible() === 0 &amp;&amp; current() !== &#039;all&#039; &amp;&amp; current() !== &#039;mine&#039;" class="flex flex-col items-center justify-center gap-3 border border-dashed border-border px-6 text-center rounded-card py-8">
            <span data-slot="state-icon" class="inline-flex size-10 items-center justify-center rounded-control border border-border bg-card [&amp;_svg]:size-5 text-muted-foreground">
            <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M12 20v-9"/>
  <path d="M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z"/>
  <path d="M14.12 3.88 16 2"/>
  <path d="M21 21a4 4 0 0 0-3.81-4"/>
  <path d="M21 5a4 4 0 0 1-3.55 3.97"/>
  <path d="M22 13h-4"/>
  <path d="M3 21a4 4 0 0 1 3.81-4"/>
  <path d="M3 5a4 4 0 0 0 3.55 3.97"/>
  <path d="M6 13H2"/>
  <path d="m8 2 1.88 1.88"/>
  <path d="M9 7.13V6a3 3 0 1 1 6 0v1.13"/>
</svg>        </span>
        <div class="flex max-w-sm flex-col gap-1">
        <p class="text-label text-foreground">Nothing reported here</p>
                    <p class="text-body-sm text-muted-foreground">No reports with this status.</p>
            </div>
    </div>
            <div class="flex items-center justify-between gap-3">
            <span class="text-caption text-muted-foreground tabular-nums" x-text="showingText()">Showing 4 of 9</span>
            <button data-slot="button"
     type="button"                         x-on:click="loadMore()" x-bind:disabled="loadingMore" x-bind:aria-busy="loadingMore ? &#039;true&#039; : null" 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-sm px-2.5">
        Load more</button>
        </div>
    </section>
    <section data-slot="feedback-configurator" aria-label="Launcher" x-data="nqFeedbackConfigurator(JSON.parse('{\u0022shape\u0022:\u0022pill\u0022,\u0022position\u0022:\u0022bottom-end\u0022,\u0022label\u0022:\u0022Feedback\u0022,\u0022fallback\u0022:\u0022Feedback\u0022,\u0022classes\u0022:{\u0022position\u0022:{\u0022bottom-end\u0022:\u0022bottom-4 end-4\u0022,\u0022bottom-start\u0022:\u0022bottom-4 start-4\u0022,\u0022top-end\u0022:\u0022top-4 end-4\u0022,\u0022top-start\u0022:\u0022top-4 start-4\u0022,\u0022edge-end\u0022:\u0022end-0 top-1\\\/2 -translate-y-1\\\/2\u0022,\u0022edge-start\u0022:\u0022start-0 top-1\\\/2 -translate-y-1\\\/2\u0022},\u0022shape\u0022:{\u0022pill\u0022:\u0022h-control rounded-full px-4\u0022,\u0022circle\u0022:\u0022relative size-12 rounded-full\u0022,\u0022tab\u0022:\u0022flex-col px-2 py-3\u0022},\u0022tabEnd\u0022:\u0022rounded-s-card\u0022,\u0022tabStart\u0022:\u0022rounded-e-card\u0022,\u0022tabText\u0022:\u0022[writing-mode:vertical-rl] rtl:rotate-180\u0022}}'))"
    class="flex w-full max-w-3xl flex-col gap-4 rounded-card border border-border bg-card p-4">
    <header class="flex flex-col gap-1">
        <h2 class="text-h3">Launcher</h2>
        <p class="text-body-sm text-muted-foreground">Choose how the feedback button looks and where it sits, then copy the install code.</p>
    </header>
    <div class="grid gap-4 md:grid-cols-2">
        <div class="flex flex-col gap-4">
            <div class="flex flex-col gap-1.5">
                <span class="text-label">Shape</span>
                <div role="group" data-slot="toggle-group" data-variant="segmented" data-orientation="horizontal"
    x-data="nqToggleGroup(JSON.parse('[\u0022pill\u0022]'), false)" x-modelable="value" x-bind="root"
            x-model="shapeV" aria-label="Shape" class="flex w-fit max-w-full gap-0.5 rounded-control bg-secondary p-0.5">
    <button type="button" data-slot="toggle" aria-pressed="true"
     x-bind="toggle('pill')"      data-pressed         class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">Pill</button>
                                            <button type="button" data-slot="toggle" aria-pressed="false"
     x-bind="toggle('circle')"             class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">Circle</button>
                                            <button type="button" data-slot="toggle" aria-pressed="false"
     x-bind="toggle('tab')"             class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">Edge tab</button>
</div>
            </div>
            <div class="flex flex-col gap-1.5">
                <span class="text-label">Position</span>
                <div role="group" data-slot="toggle-group" data-variant="segmented" data-orientation="horizontal"
    x-data="nqToggleGroup(JSON.parse('[\u0022bottom-end\u0022]'), false)" x-modelable="value" x-bind="root"
            x-model="posV" aria-label="Position" class="flex w-fit max-w-full gap-0.5 rounded-control bg-secondary p-0.5 flex-wrap">
    <button type="button" data-slot="toggle" aria-pressed="true"
     x-bind="toggle('bottom-end')"      data-pressed         class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">Bottom end</button>
                                            <button type="button" data-slot="toggle" aria-pressed="false"
     x-bind="toggle('bottom-start')"             class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">Bottom start</button>
                                            <button type="button" data-slot="toggle" aria-pressed="false"
     x-bind="toggle('top-end')"             class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">Top end</button>
                                            <button type="button" data-slot="toggle" aria-pressed="false"
     x-bind="toggle('top-start')"             class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">Top start</button>
                                            <button type="button" data-slot="toggle" aria-pressed="false"
     x-bind="toggle('edge-end')"             class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">Edge end</button>
                                            <button type="button" data-slot="toggle" aria-pressed="false"
     x-bind="toggle('edge-start')"             class="inline-flex h-7 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-3 text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 rounded-[calc(var(--radius-control)-2px)] data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-xs">Edge start</button>
</div>
            </div>
            <div class="flex flex-col gap-1.5">
                <label for="nq-feedback-text" class="text-label">Button text</label>
                <input data-slot="input" type="text"
                    id="nq-feedback-text" value="Feedback" maxlength="24" x-model="label" class="w-full min-w-0 rounded-control border border-input bg-card px-3 text-body text-foreground min-h-[var(--nq-touch-min,0px)] transition-colors duration-150 ease-nq outline-none placeholder:text-muted-foreground focus-visible:border-nq-focus focus-visible:outline-1 focus-visible:outline-nq-focus data-invalid:border-nq-danger aria-invalid:border-nq-danger disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:text-[16px] h-control">
            </div>
        </div>
        <div class="flex flex-col gap-1.5">
            <span class="text-label">Preview</span>
            <div class="relative h-56 overflow-hidden rounded-control border border-dashed border-border bg-background hatch" data-slot="feedback-configurator-preview">
                <button type="button" tabindex="-1" data-slot="feedback-launcher" x-bind:data-shape="shape" x-bind:data-position="effective" x-bind:aria-label="shape === 'circle' ? text : null"
                    x-bind:class="launcherClass"
                    class="absolute z-40 inline-flex items-center justify-center gap-2 bg-primary text-label text-primary-foreground shadow-floating outline-none transition-[filter,translate] duration-150 ease-nq hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus">
                    <svg aria-hidden="true" class="size-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"/>
  <path d="M12 8v6"/>
  <path d="M9 11h6"/>
</svg>                    <span x-show="shape !== 'circle'" x-bind:class="shape === 'tab' ? classes.tabText : ''" x-text="text">Feedback</span>
                </button>
            </div>
        </div>
    </div>
    <div class="flex flex-col gap-1.5">
        <span class="text-label">Install</span>
        <div data-slot="tabs" data-orientation="horizontal" x-data="nqTabs('react')" x-modelable="value" x-id="['nq-tabs']" class="flex flex-col gap-4">
    <div data-slot="tabs-list" data-variant="segmented" aria-orientation="horizontal" x-bind="list"
    class="relative z-0 flex max-w-full overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden w-fit gap-0.5 rounded-control bg-secondary p-0.5">
    <button type="button" data-slot="tabs-tab" x-bind="tab('react')"
     data-active aria-selected="true"         class="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground data-active:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 h-7 rounded-[calc(var(--radius-control)-2px)] px-3">React</button>
                <button type="button" data-slot="tabs-tab" x-bind="tab('json')"
            class="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground data-active:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 h-7 rounded-[calc(var(--radius-control)-2px)] px-3">Config</button>
                <span data-slot="tabs-indicator" aria-hidden="true"
    class="absolute -z-10 transition-[left,width] duration-200 ease-nq left-[var(--active-tab-left)] w-[var(--active-tab-width)] top-[var(--active-tab-top)] h-[var(--active-tab-height)] rounded-[calc(var(--radius-control)-2px)] bg-background shadow-xs"></span>
</div>
                            <div data-slot="tabs-panel" x-bind="panel('react')"
        class="outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus"><figure data-slot="feedback-code" class="relative m-0 overflow-hidden rounded-control border border-border bg-secondary">
                        <pre dir="ltr" role="region" aria-label="Install code" tabindex="0" class="max-h-72 overflow-auto p-3 text-left font-mono text-caption"><code x-text="snippet('react')"></code></pre>
                        <button data-slot="button"
     type="button"                         x-on:click="copy(&#039;react&#039;)" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border border-transparent 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 text-foreground hover:bg-nq-hover h-control-sm px-2.5 absolute end-2 top-2">
        Copy code</button>
                    </figure></div>
                            <div data-slot="tabs-panel" x-bind="panel('json')"
     hidden     class="outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus"><figure data-slot="feedback-code" class="relative m-0 overflow-hidden rounded-control border border-border bg-secondary">
                        <pre dir="ltr" role="region" aria-label="Install code" tabindex="0" class="overflow-auto p-3 text-left font-mono text-caption"><code x-text="snippet('json')"></code></pre>
                        <button data-slot="button"
     type="button"                         x-on:click="copy(&#039;json&#039;)" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border border-transparent 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 text-foreground hover:bg-nq-hover h-control-sm px-2.5 absolute end-2 top-2">
        Copy code</button>
                    </figure></div>
</div>
    </div>
</section>
    <div data-slot="shake-report" x-data="nqShakeReport(JSON.parse('{\u0022enabled\u0022:true,\u0022threshold\u0022:18,\u0022jolts\u0022:3,\u0022cooldown\u0022:3000}'))" x-on:nq-shake-open.window="show()" class="contents">
    <div data-slot="sheet" x-data="nqDialog(false)" x-modelable="open" x-id="['nq-dialog']" x-model="shown" class="contents">
    <template x-teleport="body">
    <div data-slot="sheet-portal">
        <div data-slot="sheet-backdrop" x-nq-presence="open" x-on:click="close()" class="fixed inset-0 z-50 bg-nq-fg/10 transition-opacity duration-200 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0 dark:bg-nq-bg/60"></div>
        <div data-slot="sheet-content" data-side="bottom" x-bind="popup" x-nq-presence="open" x-trap.noscroll="open"
            class="fixed z-50 flex flex-col bg-popover text-popover-foreground outline-none shadow-floating transition-[translate,opacity] duration-200 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0 inset-x-0 bottom-0 max-h-[85dvh] rounded-t-floating border-t border-border data-starting-style:translate-y-8 data-ending-style:translate-y-8 pb-[env(safe-area-inset-bottom)]">
            <div data-slot="shake-report-sheet" class="flex flex-col">
                <div data-slot="sheet-header" class="flex flex-col gap-1 border-b border-border px-4 py-3.5 pe-12 items-start"><span aria-hidden="true" class="mb-1 inline-flex size-10 items-center justify-center rounded-full bg-secondary"><svg class="size-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="m2 8 2 2-2 2 2 2-2 2"/>
  <path d="m22 8-2 2 2 2-2 2 2 2"/>
  <rect width="8" height="14" x="8" y="5" rx="1"/>
</svg></span>
                    <h2 data-slot="sheet-title" :id="$id('nq-dialog', 'title')" class="text-foreground text-h3">Something wrong?</h2>
                    <p data-slot="sheet-description" :id="$id('nq-dialog', 'description')" class="text-muted-foreground text-body-sm">You shook your phone. Do you want to report a problem on this screen?</p></div>
                <div class="flex flex-col gap-3 p-4">
                    <button data-slot="button"
     type="button"                         x-on:click="report()" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border border-transparent font-sans 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 bg-primary text-primary-foreground hover:bg-[color-mix(in_oklab,var(--nq-action)_88%,var(--nq-fg))] h-[calc(var(--nq-control)+8px)] px-5 text-body">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M12 20v-9"/>
  <path d="M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z"/>
  <path d="M14.12 3.88 16 2"/>
  <path d="M21 21a4 4 0 0 0-3.81-4"/>
  <path d="M21 5a4 4 0 0 1-3.55 3.97"/>
  <path d="M22 13h-4"/>
  <path d="M3 21a4 4 0 0 1 3.81-4"/>
  <path d="M3 5a4 4 0 0 0 3.55 3.97"/>
  <path d="M6 13H2"/>
  <path d="m8 2 1.88 1.88"/>
  <path d="M9 7.13V6a3 3 0 1 1 6 0v1.13"/>
</svg>Report a problem</button>
                    <button data-slot="button"
     type="button"                         x-on:click="shown = false" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border border-transparent 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 text-foreground hover:bg-nq-hover h-control px-[var(--nq-control-pad)]">
        Not now</button>
                                            <div class="mt-1 flex items-center justify-between gap-4 border-t border-border pt-3">
                            <div class="flex flex-col">
                                <span class="text-label">Shake to report</span>
                                <span class="text-caption text-muted-foreground">Shaking your phone opens this sheet.</span>
                            </div>
                            <button type="button" role="switch" data-slot="switch" x-data="nqSwitch(true)" x-modelable="checked" x-bind="root"
    aria-checked="true"
     data-checked                 x-model="enabled" aria-label="Shake to report" class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-transparent bg-nq-line-strong p-0.5 outline-none transition-colors duration-150 ease-nq data-checked:bg-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:cursor-not-allowed data-disabled:opacity-50">
    <span data-slot="switch-thumb"  data-checked         x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
        class="block size-4 rounded-full bg-background shadow-xs data-checked:bg-primary-foreground transition-[translate] duration-150 ease-nq data-checked:translate-x-3.5 rtl:data-checked:-translate-x-3.5"></span>
    </button>
                        </div>
                                    </div>
            </div>
                            <button type="button" data-slot="sheet-close" x-on:click="close()" aria-label="Close"
                    class="absolute end-3 top-3 inline-flex size-8 items-center justify-center rounded-control text-muted-foreground transition-colors duration-150 hover:bg-nq-hover hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus [&_svg]:size-4"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M18 6 6 18"/>
  <path d="m6 6 12 12"/>
</svg></button>
                    </div>
    </div>
</template>
</div>
</div>
</div>
```
