# LandingPageEditor

> Section-based landing page editor with an outline (add, reorder, hide, duplicate, delete), a live preview at desktop or phone width and forms for hero, features, FAQ, call to action and text sections plus page address, search fields and direction.

Source: https://docs.nasaqui.com/components/landing-page-editor

## Install

```bash
npx shadcn@latest add https://docs.nasaqui.com/r/landing-page-editor.json
```

Build a page from ready sections and watch it as it will publish. Three panes: the **Sections** outline, the live
**Preview** (desktop or phone width) and the **Edit** inspector, which switches between the selected section and
the **Page** settings. Below `lg` the panes become tabs.

## Bundle cost

Text sections use [`RichTextEditor`](https://docs.nasaqui.com/components/rich-text-editor) (Tiptap, roughly 150-200 KB minified). Lazy-load
the editor route if the page is not the main screen.

## When to use

- Marketing, launch or product pages that follow a fixed set of sections.

## When not to use

- Free-form canvas layout: sections are stacked in a column with a fixed design.
- Long articles: use [`RichTextEditor`](https://docs.nasaqui.com/components/rich-text-editor).

## Import

```tsx
import { LandingPageEditor, createSection, type LandingPage } from "@fadymondy/nasaq/web";
```

## Quick start

```tsx
const [page, setPage] = useState<LandingPage>({
  title: "Launch",
  slug: "launch",
  seoTitle: "",
  seoDescription: "",
  dir: "ltr",
  status: "draft",
  sections: [createSection("hero", "en"), createSection("cta", "en")],
});

<LandingPageEditor value={page} onValueChange={setPage} onSave={(p) => api.saveDraft(p)} onPublish={(p) => api.publish(p)} />;
```

## Anatomy

- Outline: each section is a button; its menu moves it up or down, hides or shows it, duplicates and deletes it. "Add section" inserts after the selected one.
- Preview: renders the visible sections with Nasaq tokens and container queries, in the page's own direction. Clicking a section selects it.
- Inspector: fields for the section (features and FAQ items use `Repeater`, so they drag to reorder). The Page tab holds title, address (slug), search title and description with character counts, and direction.
- Header: status badge, unsaved indicator, Save draft, Publish. Publish stays disabled while the page has blockers, which are listed under the header.

## API

| Prop | Type | Description |
| --- | --- | --- |
| `value`, `defaultValue`, `onValueChange` | `LandingPage` | Controlled or uncontrolled. |
| `onSave` | `(page) => Promise<void \| { error? }>` | Save as draft. Shows "Draft saved." when it resolves. |
| `onPublish` | `(page) => Promise<void \| { error? }>` | Receives the page with `status: "published"`. |
| `sectionTypes` | `LandingSectionType[]` | Section types offered by "Add section". Default all. |
| `labels` | `Partial<LandingPageEditorLabels>` | Override any string, including `types` and `blockers`. |

`LandingPage` is `{ title, slug, seoTitle, seoDescription, dir, sections, status }`. A section is
`{ id, type, visible, data }` with `type` one of `hero`, `features`, `faq`, `cta`, `text`. Helpers without React:
`createSection`, `moveSection`, `patchSection`, `duplicateSection`, `slugify`, `isValidSlug`, `isSafeHref`, `publishBlockers`.

## Publish blockers

No title, an invalid slug (lowercase letters, digits, hyphens), no visible section, or a button link that is not
`https://`, `http://`, `mailto:`, `tel:`, `/...` or `#...`.

## Accessibility

The outline is a list of real buttons with `aria-current` on the selected one; every section action is in a menu
with a labelled trigger, so everything the preview click does is reachable by keyboard. Hidden sections show an
icon with a text label. Errors are announced in an alert.

## RTL & i18n

- English and Arabic strings ship, including section names. The preview follows `page.dir`, independent of the app direction.
- Links and slugs are entered left-to-right. Text fields use `dir="auto"`.
- Preview buttons are not links; they never navigate.

## Styling & tokens

- Chrome and preview use Nasaq tokens (`bg-secondary`, `border-border`, `text-foreground`). The preview sizes with container queries (`@lg`), so the phone width really lays out as a phone.

## Do / Don't

- Do render the published page with your own components from the same `LandingPage` JSON.
- Don't publish user HTML from `text` sections without keeping it inside the editor's schema.

## Related

- [`RichTextEditor`](https://docs.nasaqui.com/components/rich-text-editor)
- [`Repeater`](https://docs.nasaqui.com/components/repeater)

## Lab

https://docs.nasaqui.com/?path=/docs/components-editors-landing-page-editor--docs

## Code

### React

```tsx
const [page, setPage] = useState<LandingPage>({
  title: "Launch",
  slug: "launch",
  seoTitle: "",
  seoDescription: "",
  dir: "ltr",
  status: "draft",
  sections: [createSection("hero", "en"), createSection("cta", "en")],
});

<LandingPageEditor value={page} onValueChange={setPage} onSave={(p) => api.saveDraft(p)} onPublish={(p) => api.publish(p)} />;
```

### shadcn

```tsx
const [page, setPage] = useState<LandingPage>({
  title: "Launch",
  slug: "launch",
  seoTitle: "",
  seoDescription: "",
  dir: "ltr",
  status: "draft",
  sections: [createSection("hero", "en"), createSection("cta", "en")],
});

<LandingPageEditor value={page} onValueChange={setPage} onSave={(p) => api.saveDraft(p)} onPublish={(p) => api.publish(p)} />;
```

### Vue

```vue
<script setup lang="ts">
import { NqLandingPageEditor, createSection, type LandingPage } from "@fadymondy/nasaq/vue";
import { ref } from "vue";

const page = ref<LandingPage>({
  title: "Launch",
  slug: "launch",
  seoTitle: "",
  seoDescription: "",
  dir: "ltr",
  status: "draft",
  sections: [createSection("hero", "en"), createSection("cta", "en")],
});

async function save(p: LandingPage) {
  // Your request. Return { error } to show a message.
}
async function publish(p: LandingPage) {
  // Your request.
}
</script>

<template>
  <NqLandingPageEditor v-model="page" :on-save="save" :on-publish="publish" />
</template>
```

### Blade

```blade
@php
    $page = [
        'title' => 'Launch', 'slug' => 'launch', 'seoTitle' => '', 'seoDescription' => '', 'dir' => 'ltr', 'status' => 'draft',
        'sections' => [
            ['id' => 's-hero', 'type' => 'hero', 'visible' => true, 'data' => ['headline' => 'A headline that says it in one line', 'subheadline' => 'One or two sentences on who this is for and why it matters.', 'primaryLabel' => 'Get started', 'primaryHref' => '/signup', 'secondaryLabel' => 'Learn more', 'secondaryHref' => '#features', 'align' => 'center']],
            ['id' => 's-faq', 'type' => 'faq', 'visible' => true, 'data' => ['title' => 'Frequently asked questions', 'items' => [['id' => 'q1', 'question' => 'A common question?', 'answer' => 'A short, direct answer.']]]],
            ['id' => 's-cta', 'type' => 'cta', 'visible' => true, 'data' => ['title' => 'Ready to start?', 'body' => 'Set up in minutes. No card needed.', 'buttonLabel' => 'Create your account', 'buttonHref' => '/signup']],
        ],
    ];
@endphp
<x-nq::landing-page-editor :page="$page"
    @nq-landing-save="$event.detail.promise = api.save($event.detail.page)"
    @nq-landing-publish="$event.detail.promise = api.publish($event.detail.page)" />
```

### HTML + Alpine

```html
<div data-slot="landing-page-editor" role="group" aria-label="Landing page editor" x-data="nqLandingPageEditor(JSON.parse('{\u0022page\u0022:{\u0022title\u0022:\u0022Launch\u0022,\u0022slug\u0022:\u0022launch\u0022,\u0022seoTitle\u0022:\u0022\u0022,\u0022seoDescription\u0022:\u0022\u0022,\u0022dir\u0022:\u0022ltr\u0022,\u0022status\u0022:\u0022draft\u0022,\u0022sections\u0022:[{\u0022id\u0022:\u0022s-hero\u0022,\u0022type\u0022:\u0022hero\u0022,\u0022visible\u0022:true,\u0022data\u0022:{\u0022headline\u0022:\u0022A headline that says it in one line\u0022,\u0022subheadline\u0022:\u0022One or two sentences on who this is for and why it matters.\u0022,\u0022primaryLabel\u0022:\u0022Get started\u0022,\u0022primaryHref\u0022:\u0022\\\/signup\u0022,\u0022secondaryLabel\u0022:\u0022Learn more\u0022,\u0022secondaryHref\u0022:\u0022#features\u0022,\u0022align\u0022:\u0022center\u0022}},{\u0022id\u0022:\u0022s-faq\u0022,\u0022type\u0022:\u0022faq\u0022,\u0022visible\u0022:true,\u0022data\u0022:{\u0022title\u0022:\u0022Frequently asked questions\u0022,\u0022items\u0022:[{\u0022id\u0022:\u0022q1\u0022,\u0022question\u0022:\u0022A common question?\u0022,\u0022answer\u0022:\u0022A short, direct answer.\u0022}]}},{\u0022id\u0022:\u0022s-cta\u0022,\u0022type\u0022:\u0022cta\u0022,\u0022visible\u0022:true,\u0022data\u0022:{\u0022title\u0022:\u0022Ready to start?\u0022,\u0022body\u0022:\u0022Set up in minutes. No card needed.\u0022,\u0022buttonLabel\u0022:\u0022Create your account\u0022,\u0022buttonHref\u0022:\u0022\\\/signup\u0022}}]},\u0022sectionTypes\u0022:[\u0022hero\u0022,\u0022features\u0022,\u0022faq\u0022,\u0022cta\u0022,\u0022text\u0022],\u0022locale\u0022:\u0022en\u0022,\u0022canSave\u0022:true,\u0022canPublish\u0022:true,\u0022labels\u0022:{\u0022editor\u0022:\u0022Landing page editor\u0022,\u0022sections\u0022:\u0022Sections\u0022,\u0022addSection\u0022:\u0022Add section\u0022,\u0022noSections\u0022:\u0022No sections yet\u0022,\u0022noSectionsHint\u0022:\u0022Add a hero to start the page.\u0022,\u0022types\u0022:{\u0022hero\u0022:\u0022Hero\u0022,\u0022features\u0022:\u0022Features\u0022,\u0022faq\u0022:\u0022FAQ\u0022,\u0022cta\u0022:\u0022Call to action\u0022,\u0022text\u0022:\u0022Text\u0022},\u0022hidden\u0022:\u0022Hidden\u0022,\u0022sectionActions\u0022:\u0022Actions for {n}\u0022,\u0022moveUp\u0022:\u0022Move up\u0022,\u0022moveDown\u0022:\u0022Move down\u0022,\u0022hide\u0022:\u0022Hide section\u0022,\u0022show\u0022:\u0022Show section\u0022,\u0022duplicate\u0022:\u0022Duplicate\u0022,\u0022remove\u0022:\u0022Delete\u0022,\u0022section\u0022:\u0022Section\u0022,\u0022page\u0022:\u0022Page\u0022,\u0022edit\u0022:\u0022Edit\u0022,\u0022preview\u0022:\u0022Preview\u0022,\u0022desktop\u0022:\u0022Desktop\u0022,\u0022mobile\u0022:\u0022Mobile\u0022,\u0022selectHint\u0022:\u0022Select a section to edit it.\u0022,\u0022pageTitle\u0022:\u0022Page title\u0022,\u0022slug\u0022:\u0022Address\u0022,\u0022slugHint\u0022:\u0022Lowercase letters, numbers and hyphens.\u0022,\u0022slugInvalid\u0022:\u0022Use lowercase letters, numbers and hyphens only.\u0022,\u0022seoTitle\u0022:\u0022Search title\u0022,\u0022seoDescription\u0022:\u0022Search description\u0022,\u0022characters\u0022:\u0022{n} of {max} characters\u0022,\u0022direction\u0022:\u0022Page direction\u0022,\u0022ltr\u0022:\u0022Left to right\u0022,\u0022rtl\u0022:\u0022Right to left\u0022,\u0022eyebrow\u0022:\u0022Small label above\u0022,\u0022headline\u0022:\u0022Headline\u0022,\u0022subheadline\u0022:\u0022Subheadline\u0022,\u0022primaryLabel\u0022:\u0022Main button text\u0022,\u0022primaryHref\u0022:\u0022Main button link\u0022,\u0022secondaryLabel\u0022:\u0022Second button text\u0022,\u0022secondaryHref\u0022:\u0022Second button link\u0022,\u0022align\u0022:\u0022Alignment\u0022,\u0022alignStart\u0022:\u0022Start\u0022,\u0022alignCenter\u0022:\u0022Center\u0022,\u0022title\u0022:\u0022Title\u0022,\u0022subtitle\u0022:\u0022Subtitle\u0022,\u0022items\u0022:\u0022Items\u0022,\u0022itemTitle\u0022:\u0022Title\u0022,\u0022itemDescription\u0022:\u0022Description\u0022,\u0022feature\u0022:\u0022Feature {n}\u0022,\u0022question\u0022:\u0022Question\u0022,\u0022answer\u0022:\u0022Answer\u0022,\u0022faqItem\u0022:\u0022Question {n}\u0022,\u0022addFeature\u0022:\u0022Add feature\u0022,\u0022addQuestion\u0022:\u0022Add question\u0022,\u0022body\u0022:\u0022Text\u0022,\u0022buttonLabel\u0022:\u0022Button text\u0022,\u0022buttonHref\u0022:\u0022Button link\u0022,\u0022linkInvalid\u0022:\u0022Use https:\\\/\\\/, a path starting with \\\/, or #.\u0022,\u0022draft\u0022:\u0022Draft\u0022,\u0022published\u0022:\u0022Published\u0022,\u0022unsaved\u0022:\u0022Unsaved changes\u0022,\u0022saveDraft\u0022:\u0022Save draft\u0022,\u0022publish\u0022:\u0022Publish\u0022,\u0022update\u0022:\u0022Publish changes\u0022,\u0022saved\u0022:\u0022Draft saved.\u0022,\u0022publishedOk\u0022:\u0022Page published.\u0022,\u0022failed\u0022:\u0022Something went wrong. Try again.\u0022,\u0022blockers\u0022:{\u0022title\u0022:\u0022Give the page a title.\u0022,\u0022slug\u0022:\u0022Set a valid address for the page.\u0022,\u0022sections\u0022:\u0022Show at least one section.\u0022,\u0022href\u0022:\u0022Fix the invalid button links.\u0022},\u0022previewLabel\u0022:\u0022Page preview\u0022,\u0022previewSelect\u0022:\u0022Edit {n}\u0022,\u0022untitled\u0022:\u0022Untitled page\u0022}}'))" x-modelable="page" @nq-landing-save="$event.detail.promise = api.save($event.detail.page)" @nq-landing-publish="$event.detail.promise = api.publish($event.detail.page)" class="flex min-w-0 flex-col gap-4">
    <div class="flex flex-wrap items-center gap-2">
        <div class="flex min-w-0 items-center gap-2">
            <span class="truncate text-label text-foreground" x-text="page.title || labels.untitled"></span>
            <template x-if="page.status === 'published'"><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">Published</span>
</template>
            <template x-if="page.status !== 'published'"><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">Draft</span>
</template>
            <span x-show="dirty" style="display: none" class="text-caption text-muted-foreground">Unsaved changes</span>
        </div>
        <div class="ms-auto flex flex-wrap items-center gap-2">
            <div role="group" aria-label="Preview" class="inline-flex gap-0.5 rounded-control bg-nq-surface-soft p-0.5 max-lg:hidden">
                <button data-slot="button"
     type="button"                         aria-label="Desktop" x-bind:variant="device === &#039;desktop&#039; ? &#039;secondary&#039; : &#039;ghost&#039;" x-bind:aria-pressed="device === &#039;desktop&#039; ? &#039;true&#039; : &#039;false&#039;" x-on:click="device = &#039;desktop&#039;" 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 size-control-sm p-0">
        <svg data-slot="icon" 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">
  <rect width="20" height="14" x="2" y="3" rx="2"/>
  <line x1="8" x2="16" y1="21" y2="21"/>
  <line x1="12" x2="12" y1="17" y2="21"/>
</svg></button>
                <button data-slot="button"
     type="button"                         aria-label="Mobile" x-bind:aria-pressed="device === &#039;mobile&#039; ? &#039;true&#039; : &#039;false&#039;" x-on:click="device = &#039;mobile&#039;" 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 size-control-sm p-0">
        <svg data-slot="icon" 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">
  <rect width="14" height="20" x="5" y="2" rx="2" ry="2"/>
  <path d="M12 18h.01"/>
</svg></button>
            </div>
            <template x-if="canSave">
                <button data-slot="button"
     type="button"                         x-on:click="run(&#039;save&#039;)" x-bind:aria-busy="busy === &#039;save&#039; ? &#039;true&#039; : null" x-bind:disabled="! dirty || busy ? &#039;&#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 px-[var(--nq-control-pad)]">
        <span x-show="busy === 'save'" style="display: none"><svg data-slot="spinner" aria-hidden="true" class="size-4 animate-spin motion-reduce:animate-none" 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="M21 12a9 9 0 1 1-6.219-8.56"/>
</svg></span>
                    Save draft</button>
            </template>
            <template x-if="canPublish">
                <button data-slot="button"
     type="button"                         x-on:click="run(&#039;publish&#039;)" x-bind:aria-busy="busy === &#039;publish&#039; ? &#039;true&#039; : null" x-bind:disabled="publishDisabled || busy === &#039;publish&#039; ? &#039;&#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 bg-primary text-primary-foreground hover:bg-[color-mix(in_oklab,var(--nq-action)_88%,var(--nq-fg))] h-control px-[var(--nq-control-pad)]">
        <span x-show="busy === 'publish'" style="display: none"><svg data-slot="spinner" aria-hidden="true" class="size-4 animate-spin motion-reduce:animate-none" 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="M21 12a9 9 0 1 1-6.219-8.56"/>
</svg></span>
                    <svg data-slot="icon" 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 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/>
  <path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09"/>
  <path d="M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z"/>
  <path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05"/>
</svg>                    <span x-text="page.status === 'published' ? labels.update : labels.publish"></span></button>
            </template>
        </div>
    </div>
    <template x-if="message && message.tone === 'danger'"><div data-slot="alert" data-tone="danger" role="alert"
        class="relative grid grid-cols-[auto_1fr_auto] items-start gap-x-3 rounded-card border p-3 text-start border-nq-danger/30 bg-nq-danger-soft">
    <svg aria-hidden="true" data-slot="alert-icon" class="mt-0.5 size-4 text-nq-danger-text" 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">
  <circle cx="12" cy="12" r="10"/>
  <path d="m15 9-6 6"/>
  <path d="m9 9 6 6"/>
</svg>    <div data-slot="alert-body" class="flex min-w-0 flex-col gap-0.5">
                            <div data-slot="alert-description" class="text-body-sm text-foreground"><span x-text="message.text"></span></div>
            </div>
    </div>
</template>
    <template x-if="message && message.tone === 'success'"><div data-slot="alert" data-tone="success" role="status"
        class="relative grid grid-cols-[auto_1fr_auto] items-start gap-x-3 rounded-card border p-3 text-start border-nq-success/30 bg-nq-success-soft">
    <svg aria-hidden="true" data-slot="alert-icon" class="mt-0.5 size-4 text-nq-success-text" 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">
  <circle cx="12" cy="12" r="10"/>
  <path d="m9 12 2 2 4-4"/>
</svg>    <div data-slot="alert-body" class="flex min-w-0 flex-col gap-0.5">
                            <div data-slot="alert-description" class="text-body-sm text-foreground"><span x-text="message.text"></span></div>
            </div>
    </div>
</template>
    <template x-if="canPublish && blockers.length > 0">
        <ul aria-label="Publish" class="flex flex-col gap-0.5 text-caption text-muted-foreground">
            <template x-for="b in blockerTexts" x-bind:key="b"><li x-text="b"></li></template>
        </ul>
    </template>
    <div class="flex gap-1 lg:hidden" role="tablist" aria-label="Landing page editor">
                    <button data-slot="button"
     type="button"                         role="tab" x-bind:variant="pane === &#039;sections&#039; ? &#039;secondary&#039; : &#039;ghost&#039;" x-bind:aria-selected="pane === &#039;sections&#039; ? &#039;true&#039; : &#039;false&#039;" x-on:click="pane = &#039;sections&#039;" 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">
        Sections</button>
                    <button data-slot="button"
     type="button"                         role="tab" x-bind:variant="pane === &#039;edit&#039; ? &#039;secondary&#039; : &#039;ghost&#039;" x-bind:aria-selected="pane === &#039;edit&#039; ? &#039;true&#039; : &#039;false&#039;" x-on:click="pane = &#039;edit&#039;" 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">
        Edit</button>
                    <button data-slot="button"
     type="button"                         role="tab" x-bind:variant="pane === &#039;preview&#039; ? &#039;secondary&#039; : &#039;ghost&#039;" x-bind:aria-selected="pane === &#039;preview&#039; ? &#039;true&#039; : &#039;false&#039;" x-on:click="pane = &#039;preview&#039;" 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">
        Preview</button>
            </div>
    <div class="grid min-w-0 items-start gap-4 lg:grid-cols-[15rem_minmax(0,1fr)_20rem]">
        <section aria-label="Sections" class="flex min-w-0 flex-col gap-2 max-lg:[&[data-pane=edit]]:hidden max-lg:[&[data-pane=preview]]:hidden" x-bind:data-pane="pane">
            <div class="flex items-center justify-between gap-2">
                <h3 class="text-label text-foreground">Sections</h3>
                <div data-slot="dropdown-menu" x-data="nqDropdownMenu(false)" x-modelable="open" class="contents"><button data-slot="dropdown-menu-trigger"
     type="button"                         x-bind="trigger" x-ref="trigger" 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)]">
        <svg data-slot="icon" 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="M5 12h14"/>
  <path d="M12 5v14"/>
</svg>Add section</button>
                    <template x-teleport="body">
    <div data-slot="dropdown-menu-content" x-bind="popup" x-init="popupEl = $el" x-nq-presence="open" x-anchor.bottom-end.offset.4="$refs.trigger"
        class="z-50 overflow-hidden rounded-floating border border-border bg-popover p-1.5 text-popover-foreground shadow-floating outline-none max-h-[var(--available-height)] overflow-y-auto transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0 min-w-48"><div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="add(&#039;hero&#039;)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><svg data-slot="icon" 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 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/>
  <path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09"/>
  <path d="M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z"/>
  <path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05"/>
</svg>Hero</div>
                                                    <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="add(&#039;features&#039;)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><svg data-slot="icon" 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="M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z"/>
  <path d="M20 2v4"/>
  <path d="M22 4h-4"/>
  <circle cx="4" cy="20" r="2"/>
</svg>Features</div>
                                                    <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="add(&#039;faq&#039;)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><svg data-slot="icon" 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">
    <circle cx="12" cy="12" r="10"/>
    <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/>
    <path d="M12 17h.01"/>
</svg>FAQ</div>
                                                    <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="add(&#039;cta&#039;)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><svg data-slot="icon" 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="M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z"/>
  <path d="M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14"/>
  <path d="M8 6v8"/>
</svg>Call to action</div>
                                                    <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="add(&#039;text&#039;)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><svg data-slot="icon" 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 4v16"/>
  <path d="M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2"/>
  <path d="M9 20h6"/>
</svg>Text</div></div>
</template></div>
            </div>
            <template x-if="page.sections.length === 0">
                <div data-slot="empty-state" class="flex flex-col items-center justify-center gap-3 border border-dashed border-border px-6 py-12 text-center rounded-card">
            <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">
  <rect width="18" height="7" x="3" y="3" rx="1"/>
  <rect width="9" height="7" x="3" y="14" rx="1"/>
  <rect width="5" height="7" x="16" y="14" rx="1"/>
</svg>        </span>
        <div class="flex max-w-sm flex-col gap-1">
        <p class="text-label text-foreground">No sections yet</p>
                    <p class="text-body-sm text-muted-foreground">Add a hero to start the page.</p>
            </div>
    </div>
            </template>
            <ol class="flex flex-col gap-1.5">
                <template x-for="(s, i) in page.sections" x-bind:key="s.id">
                    <li class="flex items-center gap-1 rounded-control border bg-card ps-1" x-bind:data-active="s.id === selectedId ? '' : null" x-bind:class="s.id === selectedId ? 'border-nq-focus' : 'border-border'">
                        <button type="button" x-bind:aria-current="s.id === selectedId ? 'true' : null" x-on:click="select(s.id)"
                            class="flex min-w-0 flex-1 items-center gap-2 rounded-control p-2 text-start outline-none hover:bg-nq-hover focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-nq-focus"
                            x-bind:class="s.visible ? '' : 'opacity-60'">
                                                            <template x-if="s.type === 'hero'"><svg data-slot="icon" aria-hidden="true" class="size-4 shrink-0 text-muted-foreground" 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 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/>
  <path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09"/>
  <path d="M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z"/>
  <path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05"/>
</svg></template>
                                                            <template x-if="s.type === 'features'"><svg data-slot="icon" aria-hidden="true" class="size-4 shrink-0 text-muted-foreground" 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="M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z"/>
  <path d="M20 2v4"/>
  <path d="M22 4h-4"/>
  <circle cx="4" cy="20" r="2"/>
</svg></template>
                                                            <template x-if="s.type === 'faq'"><svg data-slot="icon" aria-hidden="true" class="size-4 shrink-0 text-muted-foreground" 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">
    <circle cx="12" cy="12" r="10"/>
    <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/>
    <path d="M12 17h.01"/>
</svg></template>
                                                            <template x-if="s.type === 'cta'"><svg data-slot="icon" aria-hidden="true" class="size-4 shrink-0 text-muted-foreground" 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="M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z"/>
  <path d="M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14"/>
  <path d="M8 6v8"/>
</svg></template>
                                                            <template x-if="s.type === 'text'"><svg data-slot="icon" aria-hidden="true" class="size-4 shrink-0 text-muted-foreground" 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 4v16"/>
  <path d="M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2"/>
  <path d="M9 20h6"/>
</svg></template>
                                                        <span class="flex min-w-0 flex-col">
                                <span class="flex items-center gap-1.5 text-label text-foreground">
                                    <span x-text="typeName(s.type)"></span>
                                    <template x-if="! s.visible"><svg data-slot="icon" aria-hidden="true" aria-label="Hidden" class="size-3 text-muted-foreground" 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="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"/>
  <path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"/>
  <path d="M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"/>
  <path d="m2 2 20 20"/>
</svg></template>
                                </span>
                                <span dir="auto" class="truncate text-caption text-muted-foreground" x-text="summary(s)"></span>
                            </span>
                        </button>
                        <div data-slot="dropdown-menu" x-data="nqDropdownMenu(false)" x-modelable="open" class="contents"><button data-slot="dropdown-menu-trigger"
     type="button"                         x-bind="trigger" x-ref="trigger" x-bind:aria-label="fmt(&#039;sectionActions&#039;, { n: typeName(s.type) })" 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 size-control-sm p-0">
        <svg data-slot="icon" 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">
    <circle cx="12" cy="12" r="1"/>
    <circle cx="19" cy="12" r="1"/>
    <circle cx="5" cy="12" r="1"/>
</svg></button>
                            <template x-teleport="body">
    <div data-slot="dropdown-menu-content" x-bind="popup" x-init="popupEl = $el" x-nq-presence="open" x-anchor.bottom-end.offset.4="$refs.trigger"
        class="z-50 overflow-hidden rounded-floating border border-border bg-popover p-1.5 text-popover-foreground shadow-floating outline-none max-h-[var(--available-height)] overflow-y-auto transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0 min-w-44"><div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="move(i, -1)" x-bind:data-disabled="i === 0 ? &#039;&#039; : null" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><svg data-slot="icon" 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="m5 12 7-7 7 7"/>
  <path d="M12 19V5"/>
</svg>Move up</div>
                                <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="move(i, 1)" x-bind:data-disabled="i === page.sections.length - 1 ? &#039;&#039; : null" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><svg data-slot="icon" 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 5v14"/>
  <path d="m19 12-7 7-7-7"/>
</svg>Move down</div>
                                <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="toggleVisible(s.id)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><svg data-slot="icon" 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="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"/>
  <path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"/>
  <path d="M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"/>
  <path d="m2 2 20 20"/>
</svg>                                    <span x-text="s.visible ? labels.hide : labels.show"></span></div>
                                <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="duplicate(i)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><svg data-slot="icon" 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">
  <rect width="14" height="14" x="8" y="8" rx="2" ry="2"/>
  <path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>
</svg>Duplicate</div>
                                <div data-slot="dropdown-menu-separator" role="separator" aria-orientation="horizontal" class="-mx-1.5 my-1.5 h-px bg-border"></div>
                                <div data-slot="dropdown-menu-item" role="menuitem" data-variant="danger" x-bind="item"
        x-on:click="remove(s.id)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 text-nq-danger-text [&_svg]:text-current"><svg data-slot="icon" 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="M10 11v6"/>
  <path d="M14 11v6"/>
  <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/>
  <path d="M3 6h18"/>
  <path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
</svg>Delete</div></div>
</template></div>
                    </li>
                </template>
            </ol>
        </section>
        <section aria-label="Preview" class="min-w-0 max-lg:[&[data-pane=sections]]:hidden max-lg:[&[data-pane=edit]]:hidden" x-bind:data-pane="pane">
            <div class="mb-2 flex items-center justify-between gap-2 lg:hidden">
                <span class="text-label text-foreground">Preview</span>
                <div role="group" aria-label="Preview" class="inline-flex gap-0.5 rounded-control bg-nq-surface-soft p-0.5">
                    <button data-slot="button"
     type="button"                         aria-label="Desktop" x-bind:variant="device === &#039;desktop&#039; ? &#039;secondary&#039; : &#039;ghost&#039;" x-on:click="device = &#039;desktop&#039;" 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 size-control-sm p-0">
        <svg data-slot="icon" 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">
  <rect width="20" height="14" x="2" y="3" rx="2"/>
  <line x1="8" x2="16" y1="21" y2="21"/>
  <line x1="12" x2="12" y1="17" y2="21"/>
</svg></button>
                    <button data-slot="button"
     type="button"                         aria-label="Mobile" x-bind:variant="device === &#039;mobile&#039; ? &#039;secondary&#039; : &#039;ghost&#039;" x-on:click="device = &#039;mobile&#039;" 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 size-control-sm p-0">
        <svg data-slot="icon" 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">
  <rect width="14" height="20" x="5" y="2" rx="2" ry="2"/>
  <path d="M12 18h.01"/>
</svg></button>
                </div>
            </div>
            <div class="flex justify-center rounded-card border border-border bg-secondary p-3">
                <div role="region" aria-label="Page preview" x-bind:dir="page.dir" x-bind:data-device="device"
                    class="@container w-full overflow-hidden rounded-card border border-border bg-background" x-bind:class="device === 'mobile' ? 'max-w-[390px]' : 'max-w-[960px]'">
                    <template x-if="visibleSections.length === 0"><p class="p-10 text-center text-body-sm text-muted-foreground">Add a hero to start the page.</p></template>
                    <template x-for="s in visibleSections" x-bind:key="s.id">
                        <div x-bind:data-selected="s.id === selectedId ? '' : null" x-on:click="select(s.id)" x-bind:title="fmt('previewSelect', { n: typeName(s.type) })"
                            class="relative cursor-pointer outline-offset-[-2px] hover:outline hover:outline-1 hover:outline-nq-line-strong data-selected:outline data-selected:outline-2 data-selected:outline-nq-focus">
                            <template x-if="s.type === 'hero'">
                                <div class="flex flex-col gap-4 px-6 py-12 @lg:py-16" x-bind:class="s.data.align === 'center' ? 'items-center text-center' : 'items-start text-start'">
                                    <template x-if="s.data.eyebrow"><span class="text-caption uppercase tracking-wide text-muted-foreground" x-text="s.data.eyebrow"></span></template>
                                    <h2 class="max-w-2xl text-h1 text-foreground @lg:text-display" x-text="s.data.headline"></h2>
                                    <p class="max-w-xl text-body text-muted-foreground" x-text="s.data.subheadline"></p>
                                    <div class="flex flex-wrap gap-2 pt-2" x-bind:class="s.data.align === 'center' ? 'justify-center' : ''">
                                        <template x-if="s.data.primaryLabel"><button data-slot="button"
     type="button"                         tabindex="-1" 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">
        <span x-text="s.data.primaryLabel"></span></button>
</template>
                                        <template x-if="s.data.secondaryLabel"><button data-slot="button"
     type="button"                         tabindex="-1" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border 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 border-border bg-card text-foreground hover:bg-nq-hover h-[calc(var(--nq-control)+8px)] px-5 text-body">
        <span x-text="s.data.secondaryLabel"></span></button>
</template>
                                    </div>
                                </div>
                            </template>
                            <template x-if="s.type === 'features'">
                                <div class="flex flex-col gap-6 border-t border-border px-6 py-10">
                                    <div class="flex flex-col gap-1 text-start">
                                        <h3 class="text-h2 text-foreground" x-text="s.data.title"></h3>
                                        <template x-if="s.data.subtitle"><p class="text-body text-muted-foreground" x-text="s.data.subtitle"></p></template>
                                    </div>
                                    <ul class="grid gap-4 @lg:grid-cols-3">
                                        <template x-for="item in s.data.items" x-bind:key="item.id">
                                            <li class="flex flex-col gap-1 rounded-card border border-border bg-card p-4 text-start">
                                                <span class="flex size-8 items-center justify-center rounded-control bg-secondary"><svg data-slot="icon" aria-hidden="true" class="size-4 text-muted-foreground" 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="M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z"/>
  <path d="M20 2v4"/>
  <path d="M22 4h-4"/>
  <circle cx="4" cy="20" r="2"/>
</svg></span>
                                                <span class="pt-1 text-label text-foreground" x-text="item.title"></span>
                                                <span class="text-body-sm text-muted-foreground" x-text="item.description"></span>
                                            </li>
                                        </template>
                                    </ul>
                                </div>
                            </template>
                            <template x-if="s.type === 'faq'">
                                <div class="flex flex-col gap-4 border-t border-border px-6 py-10 text-start">
                                    <h3 class="text-h2 text-foreground" x-text="s.data.title"></h3>
                                    <dl class="flex flex-col divide-y divide-border rounded-card border border-border bg-card">
                                        <template x-for="item in s.data.items" x-bind:key="item.id">
                                            <div class="flex flex-col gap-1 p-4">
                                                <dt class="text-label text-foreground" x-text="item.question"></dt>
                                                <dd class="text-body-sm text-muted-foreground" x-text="item.answer"></dd>
                                            </div>
                                        </template>
                                    </dl>
                                </div>
                            </template>
                            <template x-if="s.type === 'cta'">
                                <div class="px-6 py-10">
                                    <div class="flex flex-col items-center gap-3 rounded-card border border-border bg-secondary px-6 py-10 text-center">
                                        <h3 class="text-h2 text-foreground" x-text="s.data.title"></h3>
                                        <p class="max-w-md text-body text-muted-foreground" x-text="s.data.body"></p>
                                        <template x-if="s.data.buttonLabel"><button data-slot="button"
     type="button"                         tabindex="-1" 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">
        <span x-text="s.data.buttonLabel"></span></button>
</template>
                                    </div>
                                </div>
                            </template>
                            <template x-if="s.type === 'text'">
                                <div class="border-t border-border px-6 py-8 text-start text-body text-nq-fg-body [&_a]:underline [&_h2]:text-h2 [&_h3]:text-h3 [&_h2]:text-foreground [&_h3]:text-foreground [&_p]:mb-3 [&_ol]:list-decimal [&_ul]:list-disc [&_ol]:ps-6 [&_ul]:ps-6" x-html="s.data.html"></div>
                            </template>
                        </div>
                    </template>
                </div>
            </div>
        </section>
        <section aria-label="Edit" class="flex min-w-0 flex-col gap-4 max-lg:[&[data-pane=sections]]:hidden max-lg:[&[data-pane=preview]]:hidden" x-bind:data-pane="pane">
            <div class="flex gap-1" role="tablist">
                <button data-slot="button"
     type="button"                         role="tab" x-bind:variant="panel === &#039;section&#039; ? &#039;secondary&#039; : &#039;ghost&#039;" x-bind:aria-selected="panel === &#039;section&#039; ? &#039;true&#039; : &#039;false&#039;" x-on:click="panel = &#039;section&#039;" 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">
        Section</button>
                <button data-slot="button"
     type="button"                         role="tab" x-bind:variant="panel === &#039;page&#039; ? &#039;secondary&#039; : &#039;ghost&#039;" x-bind:aria-selected="panel === &#039;page&#039; ? &#039;true&#039; : &#039;false&#039;" x-on:click="panel = &#039;page&#039;" 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">
        Page</button>
            </div>
            <template x-if="panel === 'page'">
                <div class="flex flex-col gap-4">
                    <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Page title</label>
                        <input data-slot="input" type="text"
                    x-model="page.title" dir="auto" 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 data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Address</label>
                        <input data-slot="input" type="text"
     dir="ltr"                 x-model="page.slug" x-on:input="normalizeSlug()" 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 text-start">
                        <template x-if="! slugInvalid"><p data-slot="field-description" class="text-caption text-muted-foreground">Lowercase letters, numbers and hyphens.</p>
</template>
                        <template x-if="slugInvalid"><p role="alert" class="text-caption text-nq-danger-text">Use lowercase letters, numbers and hyphens only.</p></template>
</div>
                    <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Search title</label>
                        <input data-slot="input" type="text"
                    x-model="page.seoTitle" dir="auto" 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">
                        <p class="text-body-sm text-muted-foreground" x-text="seoTitleCount"></p>
</div>
                    <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Search description</label>
                        <textarea data-slot="textarea"
                x-model="page.seoDescription" dir="auto" rows="3" class="w-full min-w-0 rounded-control border border-input bg-card px-3 text-body text-foreground 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] min-h-20 py-2"></textarea>
                        <p class="text-body-sm text-muted-foreground" x-text="seoDescriptionCount"></p>
</div>
                    <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Page direction</label>
                        <div data-slot="select" x-data="nqSelect(null, false)" x-modelable="value" x-id="['nq-select']" x-model="page.dir" class="contents">
    <button data-slot="select-trigger" x-ref="trigger" x-bind="trigger"
        class="flex h-control w-full min-w-0 items-center justify-between gap-2 rounded-control border border-input bg-card px-3 text-body text-foreground min-h-[var(--nq-touch-min,0px)] cursor-default select-none outline-none transition-colors duration-150 ease-nq focus-visible:border-nq-focus focus-visible:outline-1 focus-visible:outline-nq-focus data-popup-open:border-nq-focus data-invalid:border-nq-danger disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:text-[16px]">
    <span data-slot="select-value" x-text="label() ?? ''" :data-placeholder="empty() ? '' : undefined"
    class="min-w-0 flex-1 truncate text-start data-placeholder:text-muted-foreground"></span>
    <span class="flex shrink-0 text-muted-foreground [&_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="m7 15 5 5 5-5"/>
  <path d="m7 9 5-5 5 5"/>
</svg></span>
</button>
                            <template x-teleport="body">
    <div data-slot="select-content" x-ref="popup" x-bind="popup" x-nq-presence="open" x-anchor.bottom-start.offset.4="$refs.trigger"
        class="z-50 min-w-[var(--anchor-width)] max-h-[var(--available-height)] overflow-y-auto rounded-floating border border-border bg-popover p-1.5 text-popover-foreground shadow-floating outline-none transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0">
        <div data-slot="select-item" x-bind="item('ltr', false)"
    class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control ps-8 pe-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="isSelected('ltr')" x-cloak class="contents"><svg 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="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    <span data-slot="select-item-text" class="min-w-0 flex-1 truncate">Left to right</span>
</div>
                                <div data-slot="select-item" x-bind="item('rtl', false)"
    class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control ps-8 pe-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="isSelected('rtl')" x-cloak class="contents"><svg 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="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    <span data-slot="select-item-text" class="min-w-0 flex-1 truncate">Right to left</span>
</div>
    </div>
</template>
    </div>
</div>
                </div>
            </template>
            <template x-if="panel !== 'page' && selected">
                <div class="flex flex-col gap-4">
                    <h3 class="text-label text-foreground" x-text="typeName(selected.type)"></h3>
                    <template x-if="selected.type === 'hero'">
                        <div class="flex flex-col gap-4">
                                                            <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Small label above</label>
                                                                            <input data-slot="input" type="text"
                    x-model="selected.data.eyebrow" dir="auto" 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 data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Headline</label>
                                                                            <textarea data-slot="textarea"
                x-model="selected.data.headline" dir="auto" rows="3" class="w-full min-w-0 rounded-control border border-input bg-card px-3 text-body text-foreground 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] min-h-20 py-2"></textarea>
</div>
                                                            <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Subheadline</label>
                                                                            <textarea data-slot="textarea"
                x-model="selected.data.subheadline" dir="auto" rows="3" class="w-full min-w-0 rounded-control border border-input bg-card px-3 text-body text-foreground 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] min-h-20 py-2"></textarea>
</div>
                                                            <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Main button text</label>
                                                                            <input data-slot="input" type="text"
                    x-model="selected.data.primaryLabel" dir="auto" 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 data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Main button link</label>
                                                                            <input data-slot="input" type="text"
     dir="ltr"                 x-model="selected.data.primaryHref" 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 text-start">
                                        <template x-if="linkInvalid(selected.data.primaryHref)"><p role="alert" class="text-caption text-nq-danger-text">Use https://, a path starting with /, or #.</p></template>
</div>
                                                            <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Second button text</label>
                                                                            <input data-slot="input" type="text"
                    x-model="selected.data.secondaryLabel" dir="auto" 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 data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Second button link</label>
                                                                            <input data-slot="input" type="text"
     dir="ltr"                 x-model="selected.data.secondaryHref" 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 text-start">
                                        <template x-if="linkInvalid(selected.data.secondaryHref)"><p role="alert" class="text-caption text-nq-danger-text">Use https://, a path starting with /, or #.</p></template>
</div>
                                                        <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Alignment</label>
                                <div data-slot="select" x-data="nqSelect(null, false)" x-modelable="value" x-id="['nq-select']" x-model="selected.data.align" class="contents">
    <button data-slot="select-trigger" x-ref="trigger" x-bind="trigger"
        class="flex h-control w-full min-w-0 items-center justify-between gap-2 rounded-control border border-input bg-card px-3 text-body text-foreground min-h-[var(--nq-touch-min,0px)] cursor-default select-none outline-none transition-colors duration-150 ease-nq focus-visible:border-nq-focus focus-visible:outline-1 focus-visible:outline-nq-focus data-popup-open:border-nq-focus data-invalid:border-nq-danger disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:text-[16px]">
    <span data-slot="select-value" x-text="label() ?? ''" :data-placeholder="empty() ? '' : undefined"
    class="min-w-0 flex-1 truncate text-start data-placeholder:text-muted-foreground"></span>
    <span class="flex shrink-0 text-muted-foreground [&_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="m7 15 5 5 5-5"/>
  <path d="m7 9 5-5 5 5"/>
</svg></span>
</button>
                                    <template x-teleport="body">
    <div data-slot="select-content" x-ref="popup" x-bind="popup" x-nq-presence="open" x-anchor.bottom-start.offset.4="$refs.trigger"
        class="z-50 min-w-[var(--anchor-width)] max-h-[var(--available-height)] overflow-y-auto rounded-floating border border-border bg-popover p-1.5 text-popover-foreground shadow-floating outline-none transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0">
        <div data-slot="select-item" x-bind="item('start', false)"
    class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control ps-8 pe-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="isSelected('start')" x-cloak class="contents"><svg 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="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    <span data-slot="select-item-text" class="min-w-0 flex-1 truncate">Start</span>
</div>
                                        <div data-slot="select-item" x-bind="item('center', false)"
    class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control ps-8 pe-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="isSelected('center')" x-cloak class="contents"><svg 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="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    <span data-slot="select-item-text" class="min-w-0 flex-1 truncate">Center</span>
</div>
    </div>
</template>
    </div>
</div>
                        </div>
                    </template>
                    <template x-if="selected.type === 'cta'">
                        <div class="flex flex-col gap-4">
                                                            <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Title</label>
                                                                            <input data-slot="input" type="text"
                    x-model="selected.data.title" dir="auto" 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 data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Text</label>
                                                                            <textarea data-slot="textarea"
                x-model="selected.data.body" dir="auto" rows="3" class="w-full min-w-0 rounded-control border border-input bg-card px-3 text-body text-foreground 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] min-h-20 py-2"></textarea>
</div>
                                                            <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Button text</label>
                                                                            <input data-slot="input" type="text"
                    x-model="selected.data.buttonLabel" dir="auto" 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 data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Button link</label>
                                                                            <input data-slot="input" type="text"
     dir="ltr"                 x-model="selected.data.buttonHref" 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 text-start">
                                        <template x-if="linkInvalid(selected.data.buttonHref)"><p role="alert" class="text-caption text-nq-danger-text">Use https://, a path starting with /, or #.</p></template>
</div>
                                                    </div>
                    </template>
                    <template x-if="selected.type === 'text'">
                        <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Text</label>
                            <textarea data-slot="textarea"
                x-model="selected.data.html" dir="ltr" rows="8" class="w-full min-w-0 rounded-control border border-input bg-card px-3 text-foreground 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] min-h-20 py-2 font-mono text-code"></textarea>
</div>
                    </template>
                    <template x-if="selected.type === 'features' || selected.type === 'faq'">
                        <div class="flex flex-col gap-4">
                            <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Title</label>
                                <input data-slot="input" type="text"
                    x-model="selected.data.title" dir="auto" 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>
                            <template x-if="selected.type === 'features'">
                                <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Subtitle</label>
                                    <input data-slot="input" type="text"
                    x-model="selected.data.subtitle" dir="auto" 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>
                            </template>
                            <div data-slot="repeater" role="group" aria-label="Items" class="flex flex-col gap-2">
                                <span class="text-label text-foreground">Items</span>
                                <ul class="flex flex-col gap-2">
                                    <template x-for="(item, n) in selected.data.items" x-bind:key="item.id">
                                        <li data-slot="repeater-row" class="flex flex-col gap-3 rounded-card border border-border bg-card p-3">
                                            <div class="flex items-center gap-1">
                                                <span class="min-w-0 flex-1 truncate text-label text-foreground" x-text="itemTitle(selected, item, n)"></span>
                                                <button data-slot="button"
     type="button"                         x-bind:aria-label="labels.moveUp + &#039;: &#039; + itemTitle(selected, item, n)" x-bind:disabled="n === 0 ? &#039;&#039; : null" x-on:click="moveItem(n, -1)" 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 size-control-sm p-0">
        <svg data-slot="icon" 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="m5 12 7-7 7 7"/>
  <path d="M12 19V5"/>
</svg></button>
                                                <button data-slot="button"
     type="button"                         x-bind:aria-label="labels.moveDown + &#039;: &#039; + itemTitle(selected, item, n)" x-bind:disabled="n === selected.data.items.length - 1 ? &#039;&#039; : null" x-on:click="moveItem(n, 1)" 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 size-control-sm p-0">
        <svg data-slot="icon" 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 5v14"/>
  <path d="m19 12-7 7-7-7"/>
</svg></button>
                                                <button data-slot="button"
     type="button"                         x-bind:aria-label="labels.remove + &#039;: &#039; + itemTitle(selected, item, n)" x-bind:disabled="selected.data.items.length &lt;= itemMin ? &#039;&#039; : null" x-on:click="removeItem(n)" 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 size-control-sm p-0">
        <svg data-slot="icon" 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="M10 11v6"/>
  <path d="M14 11v6"/>
  <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/>
  <path d="M3 6h18"/>
  <path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
</svg></button>
                                            </div>
                                            <template x-if="selected.type === 'features'">
                                                <div class="flex flex-col gap-3">
                                                    <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Title</label>
                                                        <input data-slot="input" type="text"
                    x-model="item.title" dir="auto" 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 data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Description</label>
                                                        <textarea data-slot="textarea"
                x-model="item.description" dir="auto" rows="3" class="w-full min-w-0 rounded-control border border-input bg-card px-3 text-body text-foreground 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] min-h-20 py-2"></textarea>
</div>
                                                </div>
                                            </template>
                                            <template x-if="selected.type === 'faq'">
                                                <div class="flex flex-col gap-3">
                                                    <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Question</label>
                                                        <input data-slot="input" type="text"
                    x-model="item.question" dir="auto" 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 data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Answer</label>
                                                        <textarea data-slot="textarea"
                x-model="item.answer" dir="auto" rows="3" class="w-full min-w-0 rounded-control border border-input bg-card px-3 text-body text-foreground 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] min-h-20 py-2"></textarea>
</div>
                                                </div>
                                            </template>
                                        </li>
                                    </template>
                                </ul>
                                <div>
                                    <button data-slot="button"
     type="button"                         x-bind:disabled="selected.data.items.length &gt;= itemMax ? &#039;&#039; : null" x-on:click="addItem()" 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)]">
        <svg data-slot="icon" 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="M5 12h14"/>
  <path d="M12 5v14"/>
</svg>                                        <span x-text="selected.type === 'faq' ? labels.addQuestion : labels.addFeature"></span></button>
                                </div>
                            </div>
                        </div>
                    </template>
                </div>
            </template>
            <template x-if="panel !== 'page' && ! selected"><p class="text-body-sm text-muted-foreground">Select a section to edit it.</p></template>
        </section>
    </div>
</div>
```
