> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbitforms.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Embed Script

> Add OrbitForms forms to any website. Iframe for the most reliable inline embeds; the embed script for popup, slider, sidetab, and auto-resize.

## Iframe Embed

<Note>
  **Recommended for inline forms** — Pure HTML, no third-party script. Renders even when ad blockers, corporate firewalls, or strict CSPs would block scripts.
</Note>

```html theme={null}
<iframe
  id="orbit-form-inline-your-form-slug"
  src="https://orbitforms.ai/r/your-team-id/your-form-slug?embed=true"
  width="100%"
  height="600"
  frameborder="0"
  sandbox="allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-top-navigation"
  referrerpolicy="strict-origin-when-cross-origin"
  style="border:0;border-radius:12px"
></iframe>
<script>
  (function() {
    var iframe = document.getElementById('orbit-form-inline-your-form-slug');
    if (!iframe) return;
    var origin;
    try { origin = new URL(iframe.src).origin; } catch (e) { return; }
    var loaded = false, fallback = null;
    window.addEventListener('message', function(e) {
      if (e.origin !== origin) return;
      var d;
      try { d = typeof e.data === 'string' ? JSON.parse(e.data) : e.data; } catch (_) { return; }
      if (!d || typeof d.type !== 'string' || d.type.indexOf('orbit-') !== 0) return;
      loaded = true;
      if (fallback) {
        if (fallback.parentNode) fallback.parentNode.removeChild(fallback);
        fallback = null;
        iframe.style.display = '';
      }
      if (d.type === 'orbit-form-redirect') {
        var url = d.redirectUrl;
        if (typeof url === 'string' && url.length > 0 && url.length <= 2048) {
          var isHttp = url.indexOf('https://') === 0 || url.indexOf('http://') === 0;
          var isRelative = url.charAt(0) === '/' && url.charAt(1) !== '/';
          if (isHttp || isRelative) window.location.assign(url);
        }
        return;
      }
      if (d.type === 'orbit-form-resize') {
        var h = Number(d.height);
        if (isFinite(h) && h >= 200 && h <= 5000) iframe.style.height = h + 'px';
        return;
      }
      if (d.type === 'orbit-form-wheel') {
        var dy = Number(d.deltaY) || 0, dx = Number(d.deltaX) || 0;
        if (!isFinite(dy) || !isFinite(dx)) return;
        if (d.deltaMode === 1) { dy *= 16; dx *= 16; }
        else if (d.deltaMode === 2) { dy *= window.innerHeight; dx *= window.innerWidth; }
        dy = Math.max(-2000, Math.min(2000, dy));
        dx = Math.max(-2000, Math.min(2000, dx));
        window.scrollBy({ left: dx, top: dy, behavior: 'instant' });
      }
    });
    // If the form never responds, its origin may be blocked on this visitor's
    // network (web filter or browser extension) — show a fallback link
    // instead of a silent blank space.
    function arm() {
      setTimeout(function() {
        if (loaded || fallback) return;
        fallback = document.createElement('div');
        fallback.style.cssText = 'box-sizing:border-box;width:100%;min-height:200px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:32px 24px;border:1px solid rgba(0,0,0,0.08);border-radius:12px;background:#fafafa;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;text-align:center';
        fallback.innerHTML = '<p style="font-size:15px;font-weight:600;color:#26251E;margin:0">This form couldn&#39;t be displayed</p><p style="font-size:13px;color:#6b7280;margin:0;max-width:380px;line-height:1.5">Your network or a browser extension may be blocking embedded content. You can still open it directly.</p><a href="' + iframe.src.split('?')[0] + '" target="_blank" rel="noopener noreferrer" style="display:inline-flex;align-items:center;margin-top:10px;padding:9px 18px;border-radius:8px;background:#26251E;color:#fff;font-size:13px;font-weight:600;text-decoration:none;cursor:pointer">Open form in a new tab</a>';
        iframe.style.display = 'none';
        iframe.parentNode.insertBefore(fallback, iframe.nextSibling);
        try { console.warn('OrbitForms: embedded form did not load \u2014 ' + origin + ' may be blocked on this network.'); } catch (_) {}
      }, 8000);
    }
    if ('IntersectionObserver' in window) {
      var io = new IntersectionObserver(function(entries) {
        for (var i = 0; i < entries.length; i++) {
          if (entries[i].isIntersecting) { io.disconnect(); arm(); return; }
        }
      });
      io.observe(iframe);
    } else { arm(); }
  })();
</script>
```

The small `<script>` does two things: auto-resizes the iframe to match the form's content height, and forwards mouse-wheel events from inside the iframe so the host page keeps scrolling when the cursor is over a short form.

Trade-offs: fixed height (no auto-resize), and no popup / slider / sidetab modes. Use the script embed below if you need those.

## Script Embed (Inline)

The script embed is required for popup, slider, sidetab, and auto-resize. For inline use it adds pre-fill, event callbacks, and `comet_token` forwarding.

```html theme={null}
<div data-orbit-form="your-form-slug" data-orbit-team="your-team-id"></div>
<script src="https://orbitforms.ai/embed.js"></script>
```

Or use the JavaScript API for more control:

```html theme={null}
<div id="orbit-form"></div>
<script src="https://orbitforms.ai/embed.js"></script>
<script>
  OrbitForms.inline('your-form-slug', '#orbit-form', { team: 'your-team-id' });
</script>
```

## Popup Modal

Open the form in a modal overlay when a button is clicked. There are two approaches.

### Option 1: Native dialog + iframe (recommended)

<Note>
  Uses the native browser `<dialog>` element with inline JavaScript. No third-party script, so it can't be blocked by ad blockers or strict CSPs. Universal browser support since 2022.
</Note>

```html theme={null}
<!-- Use this button, or add class="orbit-popup-trigger-your-form-slug" to your own button/link -->
<button class="orbit-popup-trigger-your-form-slug">Open Form</button>

<!-- Paste this once on your page (anywhere in the body) -->
<dialog id="orbit-form-your-form-slug" style="border:0;border-radius:16px;padding:0;width:540px;max-width:95vw;height:720px;max-height:90dvh;background:#fff;overflow:hidden;margin:auto;inset:0">
  <button type="button" onclick="this.closest('dialog').close()" ontouchstart="event.preventDefault();event.stopPropagation();this.closest('dialog').close()" ontouchend="event.preventDefault();event.stopPropagation()" aria-label="Close" style="position:absolute;top:12px;right:12px;width:36px;height:36px;border:0;border-radius:50%;background:rgba(0,0,0,0.06);cursor:pointer;z-index:20;font-size:20px;line-height:1;display:flex;align-items:center;justify-content:center;pointer-events:auto;touch-action:manipulation;-webkit-tap-highlight-color:transparent">&times;</button>
  <iframe src="https://orbitforms.ai/r/your-team-id/your-form-slug?embed=true" sandbox="allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-top-navigation" referrerpolicy="strict-origin-when-cross-origin" style="width:100%;height:100%;border:0;display:block"></iframe>
</dialog>
<style>#orbit-form-your-form-slug::backdrop{background:rgba(0,0,0,0.5);backdrop-filter:blur(4px)}</style>
<script>
  (function() {
    var dialog = document.getElementById('orbit-form-your-form-slug');
    if (!dialog) return;
    document.addEventListener('click', function(e) {
      var trigger = e.target.closest && e.target.closest('.orbit-popup-trigger-your-form-slug');
      if (!trigger) return;
      e.preventDefault();
      if (dialog.open) return;
      dialog.showModal();
    });
    dialog.addEventListener('click', function(e) {
      if (e.target === dialog) dialog.close();
    });
  })();
</script>
```

The native `<dialog>` element handles the backdrop dimming, escape-to-close, focus trap, and ARIA roles automatically. Add the generated trigger class to as many buttons as you want — they'll all open the same form. Use a unique class per form if you have multiple popup embeds on the same page.

Adjust the `width` and `height` inline styles on the `<dialog>` to fit your form.

### Option 2: Script embed

Use the embed script if you want auto-resize, event callbacks, or slider/sidetab/popover modes. This loads `embed.js` from `orbitforms.ai`, which can be blocked by aggressive ad blockers or corporate firewalls — use Option 1 above for maximum reliability.

#### Auto-generated trigger button

The embed script creates a styled button for you:

```html theme={null}
<div
  data-orbit-form="your-form-slug"
  data-orbit-team="your-team-id"
  data-orbit-embed="popup"
  data-orbit-button-text="Open Form"
  data-orbit-size="medium"
></div>
<script src="https://orbitforms.ai/embed.js"></script>
```

#### Trigger from your own buttons

Use the JavaScript API to open a popup from any button or element on your page:

<Steps>
  <Step title="Add the embed script">
    Add the script tag and popup setup code to your site's footer or a custom code block. This only needs to appear once on the page.

    ```html theme={null}
    <script src="https://orbitforms.ai/embed.js"></script>
    <script>
      document.addEventListener('DOMContentLoaded', function() {
        var popup = OrbitForms.popup('your-form-slug', {
          team: 'your-team-id',
          size: 'medium'
        });

        document.querySelectorAll('.orbit-popup-trigger').forEach(function(btn) {
          btn.addEventListener('click', function(e) {
            e.preventDefault();
            popup.open();
          });
        });
      });
    </script>
    ```
  </Step>

  <Step title="Add the class to your buttons">
    Add the CSS class `orbit-popup-trigger` to every button that should open the popup. You can have as many buttons as you want across the page — they'll all trigger the same popup.
  </Step>

  <Step title="Publish your site">
    Publish or deploy your site. The popup will only work on the live/published site — most website builders don't execute custom JavaScript in their preview or designer mode.
  </Step>
</Steps>

<Note>
  **Why use a class instead of an ID?** HTML IDs must be unique — only one element per page can have a given ID. If you have multiple "Get Started" buttons, `document.getElementById` only finds the first one. Using a class with `querySelectorAll` attaches the popup trigger to every matching button.
</Note>

<Warning>
  **Important:** `OrbitForms.popup()` does not open the popup immediately. It creates an instance and returns an object with `open()`, `close()`, and `toggle()` methods. You must call `.open()` to show the popup.
</Warning>

### Popup sizes (script embed only)

The script-based popup automatically fits the form content and never overflows the viewport. On mobile, it goes full-screen. You can control the max width:

| Size     | Width | Best for                     |
| -------- | ----- | ---------------------------- |
| `small`  | 440px | Short forms (1-3 fields)     |
| `medium` | 540px | Standard forms (4-8 fields)  |
| `large`  | 700px | Long forms, multi-step flows |

### Platform-specific setup

<AccordionGroup>
  <Accordion title="Webflow">
    1. In Webflow, select each button that should open the popup
    2. In the Styles panel, add a class called `orbit-popup-trigger`
    3. Go to **Project Settings → Custom Code → Footer Code**
    4. Paste the embed script code from Step 1 above
    5. **Publish** your site (custom code does not run in the Webflow Designer or preview mode)
  </Accordion>

  <Accordion title="WordPress">
    1. Add the class `orbit-popup-trigger` to your button block (under "Additional CSS class(es)" in the block settings)
    2. Add the embed script to your theme's footer, or use a plugin like "Insert Headers and Footers"
    3. Save and preview
  </Accordion>

  <Accordion title="Squarespace">
    1. Add the class `orbit-popup-trigger` to your button via the button's settings
    2. Go to **Settings → Advanced → Code Injection → Footer**
    3. Paste the embed script code
    4. Save
  </Accordion>

  <Accordion title="Custom HTML / React / Next.js">
    1. Add `class="orbit-popup-trigger"` to any button or clickable element
    2. Include the embed script before `</body>` or in your layout component
  </Accordion>
</AccordionGroup>

## Slider

Slide the form in from the right edge of the screen. Use the native dialog + iframe option for maximum reliability.

```html theme={null}
<!-- Use this button, or add class="orbit-slider-trigger-your-form-slug" to your own button/link -->
<button class="orbit-slider-trigger-your-form-slug">Open Form</button>

<!-- Paste this once on your page (anywhere in the body) -->
<dialog id="orbit-form-slider-your-form-slug" style="position:fixed;top:0;right:0;left:auto;bottom:0;margin:0;border:0;padding:0;width:480px;max-width:100vw;height:100dvh;max-height:100dvh;background:#fff;box-shadow:-8px 0 32px rgba(0,0,0,0.15);overflow:hidden">
  <button type="button" onclick="this.closest('dialog').close()" ontouchstart="event.preventDefault();event.stopPropagation();this.closest('dialog').close()" ontouchend="event.preventDefault();event.stopPropagation()" aria-label="Close" style="position:absolute;top:12px;left:12px;width:36px;height:36px;border:0;border-radius:50%;background:rgba(0,0,0,0.06);cursor:pointer;z-index:20;font-size:20px;line-height:1;display:flex;align-items:center;justify-content:center;pointer-events:auto;touch-action:manipulation;-webkit-tap-highlight-color:transparent">&times;</button>
  <iframe src="https://orbitforms.ai/r/your-team-id/your-form-slug?embed=true" sandbox="allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-top-navigation" referrerpolicy="strict-origin-when-cross-origin" style="width:100%;height:100%;border:0;display:block"></iframe>
</dialog>
<style>#orbit-form-slider-your-form-slug{transform:translateX(100%);transition:transform 0.4s cubic-bezier(0.16,1,0.3,1)}#orbit-form-slider-your-form-slug.orbit-slider-open{transform:translateX(0)}#orbit-form-slider-your-form-slug::backdrop{background:rgba(0,0,0,0.5);backdrop-filter:blur(4px)}</style>
<script>
  (function() {
    var dialog = document.getElementById('orbit-form-slider-your-form-slug');
    if (!dialog) return;
    document.addEventListener('click', function(e) {
      var trigger = e.target.closest && e.target.closest('.orbit-slider-trigger-your-form-slug');
      if (!trigger) return;
      e.preventDefault();
      if (dialog.open) return;
      dialog.showModal();
      requestAnimationFrame(function() { dialog.classList.add('orbit-slider-open'); });
    });
    dialog.addEventListener('click', function(e) {
      if (e.target === dialog) dialog.close();
    });
    dialog.addEventListener('close', function() {
      dialog.classList.remove('orbit-slider-open');
    });
  })();
</script>
```

To slide in from the left, swap `right:0;left:auto` to `left:0;right:auto` and change the transform to `translateX(-100%)`.

### Script-based slider

Use the script embed if you need the `OrbitForms.slider()` JavaScript API:

```html theme={null}
<script src="https://orbitforms.ai/embed.js"></script>
<script>
  document.addEventListener('DOMContentLoaded', function() {
    var slider = OrbitForms.slider('your-form-slug', {
      team: 'your-team-id',
      position: 'right'
    });

    document.querySelectorAll('.orbit-slider-trigger').forEach(function(btn) {
      btn.addEventListener('click', function(e) {
        e.preventDefault();
        slider.open();
      });
    });
  });
</script>
```

## Scheduling Popup

Open a scheduling page in a popup modal. Use the native dialog + iframe option for maximum reliability.

```html theme={null}
<!-- Use this button, or add class="orbit-schedule-popup-trigger-your-schedule-slug" to your own button/link -->
<button class="orbit-schedule-popup-trigger-your-schedule-slug">Book a Meeting</button>

<!-- Paste this once on your page (anywhere in the body) -->
<dialog id="orbit-schedule-your-schedule-slug" style="border:0;border-radius:16px;padding:0;width:700px;max-width:95vw;height:720px;max-height:90dvh;background:#fff;overflow:hidden;margin:auto;inset:0">
  <button type="button" onclick="this.closest('dialog').close()" ontouchstart="event.preventDefault();event.stopPropagation();this.closest('dialog').close()" ontouchend="event.preventDefault();event.stopPropagation()" aria-label="Close" style="position:absolute;top:12px;right:12px;width:36px;height:36px;border:0;border-radius:50%;background:rgba(0,0,0,0.06);cursor:pointer;z-index:20;font-size:20px;line-height:1;display:flex;align-items:center;justify-content:center;pointer-events:auto;touch-action:manipulation;-webkit-tap-highlight-color:transparent">&times;</button>
  <iframe src="https://orbitforms.ai/s/your-team-id/your-schedule-slug?embed=true" sandbox="allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-top-navigation" referrerpolicy="strict-origin-when-cross-origin" style="width:100%;height:100%;border:0;display:block"></iframe>
</dialog>
<style>#orbit-schedule-your-schedule-slug::backdrop{background:rgba(0,0,0,0.5);backdrop-filter:blur(4px)}</style>
<script>
  (function() {
    var dialog = document.getElementById('orbit-schedule-your-schedule-slug');
    if (!dialog) return;
    document.addEventListener('click', function(e) {
      var trigger = e.target.closest && e.target.closest('.orbit-schedule-popup-trigger-your-schedule-slug');
      if (!trigger) return;
      e.preventDefault();
      if (dialog.open) return;
      dialog.showModal();
    });
    dialog.addEventListener('click', function(e) {
      if (e.target === dialog) dialog.close();
    });
  })();
</script>
```

Add the generated trigger class to any button that should open the scheduling popup.

### Script-based scheduling popup

Use the script embed if you need the `OrbitSchedule.popup()` JavaScript API:

```html theme={null}
<script src="https://orbitforms.ai/embed.js"></script>
<script>
  document.addEventListener('DOMContentLoaded', function() {
    var scheduler = OrbitSchedule.popup('your-schedule-slug', {
      team: 'your-team-id',
      size: 'large'
    });

    document.querySelectorAll('.orbit-schedule-trigger').forEach(function(btn) {
      btn.addEventListener('click', function(e) {
        e.preventDefault();
        scheduler.open();
      });
    });
  });
</script>
```

## Scheduling Slider

Slide a scheduling page in from the right edge of the screen. Use the native dialog + iframe option for maximum reliability.

```html theme={null}
<!-- Use this button, or add class="orbit-schedule-slider-trigger-your-schedule-slug" to your own button/link -->
<button class="orbit-schedule-slider-trigger-your-schedule-slug">Book a Meeting</button>

<!-- Paste this once on your page (anywhere in the body) -->
<dialog id="orbit-schedule-slider-your-schedule-slug" style="position:fixed;top:0;right:0;left:auto;bottom:0;margin:0;border:0;padding:0;width:520px;max-width:100vw;height:100dvh;max-height:100dvh;background:#fff;box-shadow:-8px 0 32px rgba(0,0,0,0.15);overflow:hidden">
  <button type="button" onclick="this.closest('dialog').close()" ontouchstart="event.preventDefault();event.stopPropagation();this.closest('dialog').close()" ontouchend="event.preventDefault();event.stopPropagation()" aria-label="Close" style="position:absolute;top:12px;left:12px;width:36px;height:36px;border:0;border-radius:50%;background:rgba(0,0,0,0.06);cursor:pointer;z-index:20;font-size:20px;line-height:1;display:flex;align-items:center;justify-content:center;pointer-events:auto;touch-action:manipulation;-webkit-tap-highlight-color:transparent">&times;</button>
  <iframe src="https://orbitforms.ai/s/your-team-id/your-schedule-slug?embed=true" sandbox="allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-top-navigation" referrerpolicy="strict-origin-when-cross-origin" style="width:100%;height:100%;border:0;display:block"></iframe>
</dialog>
<style>#orbit-schedule-slider-your-schedule-slug{transform:translateX(100%);transition:transform 0.4s cubic-bezier(0.16,1,0.3,1)}#orbit-schedule-slider-your-schedule-slug.orbit-slider-open{transform:translateX(0)}#orbit-schedule-slider-your-schedule-slug::backdrop{background:rgba(0,0,0,0.5);backdrop-filter:blur(4px)}</style>
<script>
  (function() {
    var dialog = document.getElementById('orbit-schedule-slider-your-schedule-slug');
    if (!dialog) return;
    document.addEventListener('click', function(e) {
      var trigger = e.target.closest && e.target.closest('.orbit-schedule-slider-trigger-your-schedule-slug');
      if (!trigger) return;
      e.preventDefault();
      if (dialog.open) return;
      dialog.showModal();
      requestAnimationFrame(function() { dialog.classList.add('orbit-slider-open'); });
    });
    dialog.addEventListener('click', function(e) {
      if (e.target === dialog) dialog.close();
    });
    dialog.addEventListener('close', function() {
      dialog.classList.remove('orbit-slider-open');
    });
  })();
</script>
```

### Script-based scheduling slider

Use the script embed if you need the `OrbitSchedule.slider()` JavaScript API:

```html theme={null}
<script src="https://orbitforms.ai/embed.js"></script>
<script>
  document.addEventListener('DOMContentLoaded', function() {
    var slider = OrbitSchedule.slider('your-schedule-slug', {
      team: 'your-team-id',
      position: 'right'
    });

    document.querySelectorAll('.orbit-schedule-slider-trigger').forEach(function(btn) {
      btn.addEventListener('click', function(e) {
        e.preventDefault();
        slider.open();
      });
    });
  });
</script>
```

## JavaScript API

All embed types are available via the `OrbitForms` and `OrbitSchedule` globals:

```javascript theme={null}
// Inline — render inside a target element
OrbitForms.inline('form-slug', '#container', { team: 'your-team-id' });

// Popup — centered modal
var popup = OrbitForms.popup('form-slug', { team: 'your-team-id', size: 'medium' });
popup.open();

// Slider — slides in from the side
var slider = OrbitForms.slider('form-slug', { team: 'your-team-id', position: 'right' });
slider.open();

// Sidetab — persistent tab on the edge of the screen
var sidetab = OrbitForms.sidetab('form-slug', { team: 'your-team-id', position: 'right' });

// Popover — floating button with popover form
var popover = OrbitForms.popover('form-slug', { team: 'your-team-id' });

// Scheduling — popup or slider
var scheduler = OrbitSchedule.popup('schedule-slug', { team: 'your-team-id', size: 'large' });
scheduler.open();
```

### Options

| Option            | Description                                               |
| ----------------- | --------------------------------------------------------- |
| `team`            | Team ID — first 8 characters of your team UUID (required) |
| `size`            | Popup size: `small`, `medium`, `large`                    |
| `position`        | Slider/sidetab position: `left`, `right`                  |
| `type`            | Form type: `standard`, `flow`                             |
| `buttonText`      | Text on the auto-generated trigger button                 |
| `buttonColor`     | Background color of the trigger button                    |
| `buttonTextColor` | Text color of the trigger button                          |
| `openOnLoad`      | Open the modal automatically on page load                 |
| `keepSession`     | Keep form state when closing and reopening                |
| `autoClose`       | Auto-close delay in ms after form submission              |
| `hiddenFields`    | Object of field values to pre-fill                        |

### Instance Methods

Every popup, slider, sidetab, and popover call returns an instance with these methods:

| Method      | Description               |
| ----------- | ------------------------- |
| `open()`    | Open the modal            |
| `close()`   | Close the modal           |
| `toggle()`  | Toggle open/close         |
| `refresh()` | Reload the form           |
| `unmount()` | Remove the embed entirely |

### Closing behavior

Popups can be closed in multiple ways:

* Clicking the **X button** in the top-right corner
* Clicking the **overlay** (dark area outside the popup)
* Pressing the **Escape** key
* Calling `popup.close()` programmatically

## Data Attributes

| Attribute                 | Description                                           |
| ------------------------- | ----------------------------------------------------- |
| `data-orbit-form`         | Form slug (required)                                  |
| `data-orbit-team`         | Team ID (required)                                    |
| `data-orbit-embed`        | Embed type: standard, popup, slider, sidetab, popover |
| `data-orbit-type`         | Form type: standard, flow                             |
| `data-orbit-button-text`  | Button text for interactive embeds                    |
| `data-orbit-button-color` | Button background color                               |
| `data-orbit-size`         | Popup size: small, medium, large                      |
| `data-orbit-position`     | Slider/sidetab position: left, right                  |
| `data-orbit-height`       | Explicit height for inline embeds                     |

## Events

Listen for form events using CustomEvents:

```javascript theme={null}
document.addEventListener('orbitFormLoaded', function(e) {
  console.log('Form loaded:', e.detail.slug);
});

document.addEventListener('orbitFormSubmitted', function(e) {
  console.log('Form submitted:', e.detail);
  // e.detail contains: { slug, formId, embedId }
});

document.addEventListener('orbitFormError', function(e) {
  console.error('Form error:', e.detail.message);
});

document.addEventListener('orbitFormResize', function(e) {
  console.log('Form resized to:', e.detail.height);
});

document.addEventListener('orbitPopupClosed', function(e) {
  console.log('Popup closed:', e.detail);
  // e.detail contains: { slug, type } where type is popup/slider/sidetab/popover
});
```

## Embed Types

<CardGroup cols={2}>
  <Card title="Inline (standard)">
    Embed directly in page content
  </Card>

  <Card title="Popup">
    Centered modal overlay
  </Card>

  <Card title="Slider">
    Slides in from the side
  </Card>

  <Card title="Sidetab">
    Floating tab that expands to form
  </Card>

  <Card title="Popover">
    Anchored popover near trigger
  </Card>
</CardGroup>
