<!-- source-hash: 6dd94b5db8fe43eb78a9a8032c387c0e -->
A platform-agnostic waitlist registration form component for OpenFrame/Flamingo, handling email capture, optional phone input with country detection, SMS consent, and submission state management.

## Key Components

### `WaitlistFormProps`
Configuration interface with the following notable props:

| Prop | Type | Description |
|------|------|-------------|
| `onRegister` | `(email, phone?) => Promise<void>` | Required submission handler; must throw on failure |
| `geoApiUrl` | `string \| null` | Geo-detection endpoint for auto-selecting country code (default: `"/api/geo"`) |
| `isSubmitting` | `boolean` | Controls loading state on the submit button |
| `isSuccess` | `boolean` | Switches button label to `successLabel` |
| `defaultEmail` / `defaultPhone` | `string` | Pre-filled values from auth context or user profile |
| `termsOfServiceUrl` / `privacyPolicyUrl` | `string` | Links rendered in SMS consent copy |

### `WaitlistForm`
The exported form component. Key internal behaviors:

- **Hydration-safe skeleton** — renders animated placeholder blocks until client-side mount
- **Geo-detection** — fetches `geoApiUrl` on mount to pre-select the user's country code via `libphonenumber-js`
- **Generic email warning** — surfaces a warning (not a block) when a personal domain is detected
- **SMS consent gate** — requires checkbox agreement before submitting a phone number
- **E.164 formatting** — converts raw phone input via `formatPhoneE164` before calling `onRegister`
- **Enter key support** — `handleKeyDown` triggers submission from any field

## Usage Example

```typescript
import { WaitlistForm } from './waitlist-form'

function WaitlistPage() {
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [isSuccess, setIsSuccess] = useState(false)

  const handleRegister = async (email: string, phone?: string) => {
    setIsSubmitting(true)
    try {
      await api.joinWaitlist({ email, phone })
      setIsSuccess(true)
    } finally {
      setIsSubmitting(false)
    }
  }

  return (
    <WaitlistForm
      onRegister={handleRegister}
      isSubmitting={isSubmitting}
      isSuccess={isSuccess}
      geoApiUrl="/api/geo"
      termsOfServiceUrl="/legal/terms"
      privacyPolicyUrl="/legal/privacy"
    />
  )
}
```

> **Note:** `onRegister` is responsible for its own error toasts. The form handles only email-empty and consent-missing validation client-side.