# MembersManager

> Members and roles of a workspace. A searchable table with an inline role select limited to the roles you can grant, an invite by email dialog, pending invites with resend and revoke, transfer of ownership and leave, with the last owner protected.

Source: https://docs.nasaqui.com/components/members-manager

## Install

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

The "Members" page of a workspace or team. People and their roles in a table, an invite dialog that takes
several email addresses and one role, the invites still waiting, and the two ownership moves: transfer to
someone else, or leave. The rules for the last owner live in pure functions, so the UI and your server agree.

## When to use

- A team or organisation settings page where owners and admins manage who is in.
- Any product with roles per workspace (owner, admin, member, viewer).

## When not to use

- Managing every user of the whole product as an operator: use [`AdminUsers`](https://docs.nasaqui.com/components/admin-users).
- Choosing which workspace you are in: use `WorkspaceSwitcher`.

## Import

```tsx
import { MembersManager } from "@fadymondy/nasaq/web";
```

## Quick start

```tsx
<MembersManager
  members={members}
  invites={invites}
  roles={[
    { id: "owner", label: "Owner" },
    { id: "admin", label: "Admin", description: "Manage members and settings" },
    { id: "member", label: "Member" },
  ]}
  currentUserId="u1"
  grantableRoles={["admin", "member"]}
  onInvite={({ emails, role }) => api.invite(emails, role)}
  onChangeRole={(m, role) => api.setRole(m.id, role)}
  onRemove={(m) => api.remove(m.id)}
  onResendInvite={(i) => api.resend(i.id)}
  onRevokeInvite={(i) => api.revoke(i.id)}
  onTransferOwnership={(m) => api.transfer(m.id)}
  onLeave={() => api.leave()}
/>
```

## Anatomy

```
MembersManager           data-slot="members-manager"
├─ Alert                    outcome of the last action
├─ Tabs                     Members / Pending invites (the tab shows only when `invites` is passed) + Invite button
│  ├─ DataTable             member, role select, last active, joined; row actions transfer / remove
│  └─ list                  pending invites: email, role, expiry, Resend, Revoke
├─ leave row                data-slot="members-leave"
├─ InviteMembersDialog      emails as chips (TagInput) + role
└─ AlertDialog              confirms remove, transfer and leave
```

## API

### MembersManager

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `members` | `TeamMember[]` | required | `{ id, name, email, avatar?, role, joinedAt, lastActive? }`. |
| `invites` | `PendingInvite[]` | none | `{ id, email, role, invitedBy?, sentAt, expiresAt? }`. Passing it shows the Pending invites tab. |
| `roles` | `MemberRoleOption[]` | required | `{ id, label, description? }` in display order. |
| `currentUserId` | `string` | none | Marks "You"; that row cannot be removed here. |
| `grantableRoles` | `string[]` | every role except the owner role | The role ids the signed-in person may give. The select shows only these plus the member's current role. |
| `ownerRole` | `string` | `"owner"` | The role id that means owner. |
| `canManage` | `boolean` | `true` | `false` hides invite and locks every control. |
| `loading` | `boolean` | `false` | Skeleton rows. |
| `pageSize` | `number` | `8` | |
| `onInvite` | `(values: { emails, role }) => Promise<void \| { error?, emailsError? }>` | none | Shows the Invite button. |
| `onChangeRole` | `(member, role) => Promise<void \| { error? }>` | none | Turns the role cell into a select. |
| `onRemove` | `(member) => Promise<void \| { error? }>` | none | Row action. |
| `onResendInvite` / `onRevokeInvite` | `(invite) => Promise<void \| { error? }>` | none | |
| `onTransferOwnership` | `(member) => Promise<void \| { error? }>` | none | Row action, only for owners. |
| `onLeave` | `() => Promise<void \| { error? }>` | none | Shows the leave row. |
| `profile` | `(member) => PersonProfile | null | undefined` | none | Gives each member cell a profile hover card (hover, focus and tap). |
| `profileActions` | `{ onMessage?, onMention?, onViewProfile?, viewerTimeZone? }` | none | Quick actions and your time zone for those cards. |
| `labels` | `MembersManagerLabels` | en / ar | |

Resolve `{ error }` (or throw) to show a failure; the dialog stays open. You send back new `members` and
`invites`; the component keeps no copy.

### Rules (pure, exported)

`ownerCount`, `isLastOwner`, `roleChoices`, `roleChangeBlock`, `removeBlock`, `canLeave`.
The last owner cannot be demoted, removed or leave; the owner role is reachable only through transfer.

## Examples

- **Read-only member view**: `canManage={false}`.
- **An admin who can only grant member and viewer**: `grantableRoles={["member", "viewer"]}`; owners and admins show a plain badge.

## Accessibility

The role select has an accessible name per member. A locked role shows a focusable badge with a tooltip that
says why. Destructive actions ask in an alert dialog; outcomes are announced in a status alert.

## RTL & i18n

Built-in English and Arabic. Emails stay left-to-right; dates and counts use the locale digits.

## Styling & tokens

Built from Nasaq parts (`DataTable`, `Select`, `Badge`, `Alert`), so it follows the tokens. Extend with `className`.

## Do / Don't

- Do enforce the same rules on your server; the UI only hides the options.
- Do not offer the owner role in the invite dialog: ownership moves by transfer.

## Related

- [AdminUsers](https://docs.nasaqui.com/components/admin-users)
- [WorkspaceSettings](https://docs.nasaqui.com/components/workspace-settings)
- [InviteAccept](https://docs.nasaqui.com/components/invite-accept)

## Lab

https://docs.nasaqui.com/?path=/docs/components-collaboration-members-manager--docs

## Code

### React

```tsx
<MembersManager
  members={members}
  invites={invites}
  roles={[
    { id: "owner", label: "Owner" },
    { id: "admin", label: "Admin", description: "Manage members and settings" },
    { id: "member", label: "Member" },
  ]}
  currentUserId="u1"
  grantableRoles={["admin", "member"]}
  onInvite={({ emails, role }) => api.invite(emails, role)}
  onChangeRole={(m, role) => api.setRole(m.id, role)}
  onRemove={(m) => api.remove(m.id)}
  onResendInvite={(i) => api.resend(i.id)}
  onRevokeInvite={(i) => api.revoke(i.id)}
  onTransferOwnership={(m) => api.transfer(m.id)}
  onLeave={() => api.leave()}
/>
```

### shadcn

```tsx
<MembersManager
  members={members}
  invites={invites}
  roles={[
    { id: "owner", label: "Owner" },
    { id: "admin", label: "Admin", description: "Manage members and settings" },
    { id: "member", label: "Member" },
  ]}
  currentUserId="u1"
  grantableRoles={["admin", "member"]}
  onInvite={({ emails, role }) => api.invite(emails, role)}
  onChangeRole={(m, role) => api.setRole(m.id, role)}
  onRemove={(m) => api.remove(m.id)}
  onResendInvite={(i) => api.resend(i.id)}
  onRevokeInvite={(i) => api.revoke(i.id)}
  onTransferOwnership={(m) => api.transfer(m.id)}
  onLeave={() => api.leave()}
/>
```

### Vue

```vue
<script setup lang="ts">
import { NqMembersManager, type InviteValues, type MemberRoleOption, type PendingInvite, type TeamMember } from "@fadymondy/nasaq/vue";
import { ref } from "vue";

const roles: MemberRoleOption[] = [
  { id: "owner", label: "Owner", description: "Full control, including billing" },
  { id: "admin", label: "Admin", description: "Manage members and settings" },
  { id: "member", label: "Member", description: "Work in the workspace" },
];
const members = ref<TeamMember[]>([
  { id: "m1", name: "Sara Alharbi", email: "sara@acme.test", role: "owner", joinedAt: "2025-01-12", lastActive: "2026-09-29T08:30:00Z" },
  { id: "m2", name: "Omar Nasser", email: "omar@acme.test", role: "admin", joinedAt: "2025-05-03", lastActive: "2026-09-28T10:00:00Z" },
  { id: "m3", name: "Lina Haddad", email: "lina@acme.test", role: "member", joinedAt: "2026-03-20", lastActive: null },
]);
const invites = ref<PendingInvite[]>([{ id: "i1", email: "new@acme.test", role: "member", invitedBy: "Sara Alharbi", sentAt: "2026-09-27T09:00:00Z", expiresAt: "2026-10-04T09:00:00Z" }]);

async function onInvite(v: InviteValues) {
  invites.value = [...invites.value, ...v.emails.map((email, i) => ({ id: `i${invites.value.length + i + 1}`, email, role: v.role, invitedBy: "Sara Alharbi", sentAt: "2026-09-29T09:00:00Z", expiresAt: "2026-10-06T09:00:00Z" }))];
}
async function onChangeRole(m: TeamMember, role: string) {
  members.value = members.value.map((x) => (x.id === m.id ? { ...x, role } : x));
}
async function onRemove(m: TeamMember) {
  members.value = members.value.filter((x) => x.id !== m.id);
}
async function onRevokeInvite(i: PendingInvite) {
  invites.value = invites.value.filter((x) => x.id !== i.id);
}
const noop = async () => undefined;
</script>

<template>
  <NqMembersManager
    :members="members"
    :invites="invites"
    :roles="roles"
    current-user-id="m1"
    :on-invite="onInvite"
    :on-change-role="onChangeRole"
    :on-remove="onRemove"
    :on-resend-invite="noop"
    :on-revoke-invite="onRevokeInvite"
    :on-transfer-ownership="noop"
    :on-leave="noop"
  />
</template>
```

### Blade

```blade
@php
    $roles = [
        ['id' => 'owner', 'label' => 'Owner', 'description' => 'Full control, including billing'],
        ['id' => 'admin', 'label' => 'Admin', 'description' => 'Manage members and settings'],
        ['id' => 'member', 'label' => 'Member', 'description' => 'Work in the workspace'],
    ];
    $members = [
        ['id' => 'm1', 'name' => 'Sara Alharbi', 'email' => 'sara@acme.test', 'role' => 'owner', 'joinedAt' => '2025-01-12', 'lastActive' => '2026-09-29'],
        ['id' => 'm2', 'name' => 'Omar Nasser', 'email' => 'omar@acme.test', 'role' => 'admin', 'joinedAt' => '2025-05-03', 'lastActive' => '2026-09-28'],
        ['id' => 'm3', 'name' => 'Lina Haddad', 'email' => 'lina@acme.test', 'role' => 'member', 'joinedAt' => '2026-03-20', 'lastActive' => null],
    ];
    $invites = [
        ['id' => 'i1', 'email' => 'new@acme.test', 'role' => 'member', 'invitedBy' => 'Sara Alharbi', 'sentAt' => '2026-09-27', 'expiresAt' => '2026-10-04'],
    ];
@endphp
<x-nq::members-manager :members="$members" :invites="$invites" :roles="$roles" current-user-id="m1" can-invite can-change-role can-remove can-resend can-revoke can-transfer can-leave />
```

### HTML + Alpine

```html
<div data-slot="members-manager" x-data="nqMembersManager(JSON.parse('{\u0022locale\u0022:\u0022en\u0022,\u0022currentUserId\u0022:\u0022m1\u0022,\u0022ownerRole\u0022:\u0022owner\u0022,\u0022grantable\u0022:[\u0022admin\u0022,\u0022member\u0022],\u0022members\u0022:{\u0022m1\u0022:{\u0022id\u0022:\u0022m1\u0022,\u0022name\u0022:\u0022Sara Alharbi\u0022,\u0022email\u0022:\u0022sara@acme.test\u0022,\u0022role\u0022:\u0022owner\u0022},\u0022m2\u0022:{\u0022id\u0022:\u0022m2\u0022,\u0022name\u0022:\u0022Omar Nasser\u0022,\u0022email\u0022:\u0022omar@acme.test\u0022,\u0022role\u0022:\u0022admin\u0022},\u0022m3\u0022:{\u0022id\u0022:\u0022m3\u0022,\u0022name\u0022:\u0022Lina Haddad\u0022,\u0022email\u0022:\u0022lina@acme.test\u0022,\u0022role\u0022:\u0022member\u0022}},\u0022invites\u0022:{\u0022i1\u0022:{\u0022id\u0022:\u0022i1\u0022,\u0022email\u0022:\u0022new@acme.test\u0022,\u0022role\u0022:\u0022member\u0022}},\u0022roles\u0022:{\u0022owner\u0022:{\u0022label\u0022:\u0022Owner\u0022,\u0022description\u0022:\u0022Full control, including billing\u0022},\u0022admin\u0022:{\u0022label\u0022:\u0022Admin\u0022,\u0022description\u0022:\u0022Manage members and settings\u0022},\u0022member\u0022:{\u0022label\u0022:\u0022Member\u0022,\u0022description\u0022:\u0022Work in the workspace\u0022}},\u0022defaultRole\u0022:\u0022member\u0022,\u0022labels\u0022:{\u0022failed\u0022:\u0022That did not work. Try again.\u0022,\u0022blockLastOwner\u0022:\u0022A workspace needs an owner. Transfer ownership first.\u0022,\u0022blockOwnerOnly\u0022:\u0022Only an owner can change another owner.\u0022,\u0022blockNotGrantable\u0022:\u0022You cannot change this role.\u0022,\u0022blockSelf\u0022:\u0022Use Leave workspace to remove yourself.\u0022,\u0022emailsRequired\u0022:\u0022Add at least one email address.\u0022,\u0022emailInvalid\u0022:\u0022{v} is not a valid email address.\u0022,\u0022emailDuplicate\u0022:\u0022{v} is already added.\u0022,\u0022invitedOne\u0022:\u00221 invite sent.\u0022,\u0022invitedMany\u0022:\u0022{n} invites sent.\u0022,\u0022roleOk\u0022:\u0022Role updated for {name}.\u0022,\u0022removedOk\u0022:\u0022{name} was removed.\u0022,\u0022resentOk\u0022:\u0022Invite sent again to {email}.\u0022,\u0022revokedOk\u0022:\u0022Invite to {email} was revoked.\u0022,\u0022transferredOk\u0022:\u0022{name} is now the owner.\u0022,\u0022removeTitle\u0022:\u0022Remove {name}?\u0022,\u0022removeBody\u0022:\u0022They lose access to this workspace at once. Their work stays here.\u0022,\u0022removeConfirm\u0022:\u0022Remove member\u0022,\u0022transferTitle\u0022:\u0022Make {name} the owner?\u0022,\u0022transferBody\u0022:\u0022They become the owner and you lose owner rights. Only they can give ownership back.\u0022,\u0022transferConfirm\u0022:\u0022Transfer ownership\u0022,\u0022leaveTitle\u0022:\u0022Leave this workspace?\u0022,\u0022leaveBody\u0022:\u0022You lose access until someone invites you again.\u0022,\u0022leaveConfirm\u0022:\u0022Leave workspace\u0022,\u0022roleTitle\u0022:\u0022Role of {name}\u0022}}'))" x-on:nq-data-table-action="onAction($event)" class="flex flex-col gap-5">
    <template x-if="notice !== null && notice.tone === 'success'">
        <div data-slot="alert" data-tone="success" role="status"
     x-data="nqAlert()" x-modelable="open" x-show="open"     x-on:nq:dismiss="notice = null" 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="notice.text"></span></div>
            </div>
            <div data-slot="alert-actions" class="ms-3 flex items-center gap-1">
                            <button data-slot="button"
     type="button"                         aria-label="Dismiss" x-on:click="dismiss()" 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]:shrink-0 hover:bg-nq-hover size-control-sm p-0 text-muted-foreground [&_svg]:size-3.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M18 6 6 18"/>
  <path d="m6 6 12 12"/>
</svg></button>
                    </div>
    </div>
    </template>
    <template x-if="notice !== null && notice.tone === 'danger'">
        <div data-slot="alert" data-tone="danger" role="alert"
     x-data="nqAlert()" x-modelable="open" x-show="open"     x-on:nq:dismiss="notice = null" 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="notice.text"></span></div>
            </div>
            <div data-slot="alert-actions" class="ms-3 flex items-center gap-1">
                            <button data-slot="button"
     type="button"                         aria-label="Dismiss" x-on:click="dismiss()" 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]:shrink-0 hover:bg-nq-hover size-control-sm p-0 text-muted-foreground [&_svg]:size-3.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M18 6 6 18"/>
  <path d="m6 6 12 12"/>
</svg></button>
                    </div>
    </div>
    </template>
    <div data-slot="tabs" data-orientation="horizontal" x-data="nqTabs('members')" x-modelable="value" x-id="['nq-tabs']" class="flex flex-col gap-4">
    <div class="flex flex-wrap items-center justify-between gap-3">
                            <div data-slot="tabs-list" data-variant="segmented" aria-orientation="horizontal" x-bind="list"
    aria-label="Members" class="relative z-0 flex max-w-full overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden w-fit gap-0.5 rounded-control bg-secondary p-0.5">
    <button type="button" data-slot="tabs-tab" x-bind="tab('members')"
     data-active aria-selected="true"         class="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground data-active:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 h-7 rounded-[calc(var(--radius-control)-2px)] px-3">Members <span class="text-muted-foreground">3</span></button>
                    <button type="button" data-slot="tabs-tab" x-bind="tab('pending')"
            class="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap text-label text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground data-active:text-foreground [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus data-disabled:pointer-events-none data-disabled:opacity-50 h-7 rounded-[calc(var(--radius-control)-2px)] px-3">Pending invites <span class="text-muted-foreground">1</span></button>
                    <span data-slot="tabs-indicator" aria-hidden="true"
    class="absolute -z-10 transition-[left,width] duration-200 ease-nq left-[var(--active-tab-left)] w-[var(--active-tab-width)] top-[var(--active-tab-top)] h-[var(--active-tab-height)] rounded-[calc(var(--radius-control)-2px)] bg-background shadow-xs"></span>
</div>
                                        <button data-slot="button"
     type="button"                         x-on:click="openInvite()" 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)]">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
  <circle cx="9" cy="7" r="4"/>
  <line x1="19" x2="19" y1="8" y2="14"/>
  <line x1="22" x2="16" y1="11" y2="11"/>
</svg>Invite people</button>
                    </div>
        <div data-slot="tabs-panel" x-bind="panel('members')"
        class="outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus mt-4"><div class="flex flex-col gap-4">
                <div data-slot="data-table" x-data="nqDataTable(JSON.parse('[{\u0022id\u0022:\u0022m1\u0022,\u0022name\u0022:\u0022Sara Alharbi\u0022,\u0022email\u0022:\u0022sara@acme.test\u0022,\u0022role\u0022:\u0022owner\u0022,\u0022self\u0022:true,\u0022lastActive\u0022:\u00222026-09-29\u0022,\u0022joinedAt\u0022:\u00222025-01-12\u0022},{\u0022id\u0022:\u0022m2\u0022,\u0022name\u0022:\u0022Omar Nasser\u0022,\u0022email\u0022:\u0022omar@acme.test\u0022,\u0022role\u0022:\u0022admin\u0022,\u0022self\u0022:false,\u0022lastActive\u0022:\u00222026-09-28\u0022,\u0022joinedAt\u0022:\u00222025-05-03\u0022},{\u0022id\u0022:\u0022m3\u0022,\u0022name\u0022:\u0022Lina Haddad\u0022,\u0022email\u0022:\u0022lina@acme.test\u0022,\u0022role\u0022:\u0022member\u0022,\u0022self\u0022:false,\u0022lastActive\u0022:null,\u0022joinedAt\u0022:\u00222026-03-20\u0022}]'), JSON.parse('[{\u0022id\u0022:\u0022name\u0022,\u0022header\u0022:\u0022Member\u0022,\u0022type\u0022:\u0022avatar\u0022,\u0022secondary\u0022:\u0022email\u0022,\u0022secondaryDir\u0022:\u0022ltr\u0022,\u0022badge\u0022:\u0022self\u0022,\u0022badgeLabel\u0022:\u0022You\u0022,\u0022sortable\u0022:true,\u0022searchable\u0022:true,\u0022hideable\u0022:false},{\u0022id\u0022:\u0022email\u0022,\u0022header\u0022:\u0022Email address\u0022,\u0022searchable\u0022:true,\u0022hidden\u0022:true,\u0022type\u0022:\u0022text\u0022},{\u0022id\u0022:\u0022role\u0022,\u0022header\u0022:\u0022Role\u0022,\u0022type\u0022:\u0022tag\u0022,\u0022sortable\u0022:true,\u0022filter\u0022:true,\u0022options\u0022:[{\u0022value\u0022:\u0022owner\u0022,\u0022label\u0022:\u0022Owner\u0022,\u0022hue\u0022:\u0022amber\u0022},{\u0022value\u0022:\u0022admin\u0022,\u0022label\u0022:\u0022Admin\u0022,\u0022hue\u0022:\u0022blue\u0022},{\u0022value\u0022:\u0022member\u0022,\u0022label\u0022:\u0022Member\u0022,\u0022hue\u0022:\u0022blue\u0022}]},{\u0022id\u0022:\u0022lastActive\u0022,\u0022header\u0022:\u0022Last active\u0022,\u0022type\u0022:\u0022date\u0022,\u0022sortable\u0022:true},{\u0022id\u0022:\u0022joinedAt\u0022,\u0022header\u0022:\u0022Joined\u0022,\u0022type\u0022:\u0022date\u0022,\u0022sortable\u0022:true,\u0022align\u0022:\u0022end\u0022}]'), JSON.parse('{\u0022nameKey\u0022:\u0022name\u0022,\u0022pageSize\u0022:8,\u0022locale\u0022:\u0022en\u0022,\u0022actions\u0022:[{\u0022id\u0022:\u0022role\u0022,\u0022group\u0022:\u0022manage\u0022},{\u0022id\u0022:\u0022transfer\u0022,\u0022group\u0022:\u0022ownership\u0022,\u0022visibleWhen\u0022:{\u0022field\u0022:\u0022role\u0022,\u0022ne\u0022:\u0022owner\u0022}},{\u0022id\u0022:\u0022remove\u0022,\u0022group\u0022:\u0022danger\u0022}],\u0022labels\u0022:{\u0022selectRow\u0022:\u0022Select {name}\u0022,\u0022rowActions\u0022:\u0022Actions for {name}\u0022,\u0022selected\u0022:\u0022{n} selected\u0022,\u0022range\u0022:\u0022{from}\\u2013{to} of {total}\u0022,\u0022editCell\u0022:\u0022{column}, {row}\u0022,\u0022invalidNumber\u0022:\u0022Enter a number\u0022,\u0022invalidDate\u0022:\u0022Enter a date\u0022,\u0022saving\u0022:\u0022Saving\\u2026\u0022,\u0022saved\u0022:\u0022Saved\u0022,\u0022saveFailed\u0022:\u0022Couldn\\u0027t save the change\u0022,\u0022saveFailedFor\u0022:\u0022Couldn\\u0027t save: {message}\u0022,\u0022expandRow\u0022:\u0022Show details for {name}\u0022,\u0022details\u0022:\u0022Details for {name}\u0022,\u0022ascending\u0022:\u0022ascending\u0022,\u0022descending\u0022:\u0022descending\u0022,\u0022rangeAtLeast\u0022:\u0022\\u2265 {v}\u0022,\u0022rangeAtMost\u0022:\u0022\\u2264 {v}\u0022,\u0022sortPriority\u0022:\u0022sort {n}, {dir}\u0022}}'))" x-modelable="rows"
    class="flex min-w-0 flex-col gap-3">
            <div data-slot="data-table-toolbar" class="flex flex-wrap items-center gap-2">
                            <div data-slot="data-table-search" class="relative w-full sm:w-64">
                    <svg aria-hidden="true" class="pointer-events-none absolute start-2.5 top-1/2 size-4 -translate-y-1/2 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="m21 21-4.34-4.34"/>
  <circle cx="11" cy="11" r="8"/>
</svg>                    <input data-slot="input" type="search"
                    x-model="query" x-on:keydown.escape="if (query) { $event.preventDefault(); query = &#039;&#039; }" placeholder="Search name or email…" aria-label="Search name or email…" class="w-full min-w-0 rounded-control border border-input bg-card px-3 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-sm ps-8 pe-8 text-body-sm [&::-webkit-search-cancel-button]:hidden">
                    <button type="button" x-show="query" aria-label="Clear search" x-on:click="query = ''" style="display: none"
                        class="absolute end-1.5 top-1/2 inline-flex size-5 -translate-y-1/2 items-center justify-center rounded-full text-muted-foreground outline-none hover:bg-nq-hover hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus">
                        <svg aria-hidden="true" class="size-3.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M18 6 6 18"/>
  <path d="m6 6 12 12"/>
</svg>                    </button>
                </div>
                            <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:class="facetCount(&#039;role&#039;) ? &#039;&#039; : &#039;border-dashed text-muted-foreground&#039;" data-facet="role" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border-border bg-card text-foreground hover:bg-nq-hover h-control-sm px-2.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M2 5h20"/>
  <path d="M6 12h12"/>
  <path d="M9 19h6"/>
</svg>                        Role
                        <span data-slot="badge" x-show="facetCount('role')" x-text="facetSummary('role')" style="display: none"
                            class="-me-1 inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-[4px] border border-border px-1.5 text-caption font-medium tabular-nums text-muted-foreground"></span></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-start.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-group" role="group" ><div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="facet[&#039;role|owner&#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 ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><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="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Owner
</div>
                                                            <div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="facet[&#039;role|admin&#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 ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><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="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Admin
</div>
                                                            <div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="facet[&#039;role|member&#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 ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><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="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Member
</div></div>
                        <div x-show="facetCount('role')" style="display: none">
                            <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="default" x-bind="item"
        x-on:click="resetFacet(&#039;role&#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">Reset</div>
                        </div></div>
</template></div>
                            <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-sm px-2.5 ms-auto">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M14 17H5"/>
  <path d="M19 7h-9"/>
  <circle cx="17" cy="17" r="3"/>
  <circle cx="7" cy="7" r="3"/>
</svg>                        View</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-group" role="group" ><div data-slot="dropdown-menu-label" role="presentation" class="px-2.5 pt-1.5 pb-1 text-caption font-medium text-muted-foreground">Columns</div>
                                                                    <div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="shown[&#039;email&#039;]" x-bind:disabled="shown[&#039;email&#039;] &amp;&amp; shownCount() === 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 ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><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="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Email address
</div>
                                                                    <div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="shown[&#039;role&#039;]" x-bind:disabled="shown[&#039;role&#039;] &amp;&amp; shownCount() === 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 ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><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="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Role
</div>
                                                                    <div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="shown[&#039;lastActive&#039;]" x-bind:disabled="shown[&#039;lastActive&#039;] &amp;&amp; shownCount() === 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 ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><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="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Last active
</div>
                                                                    <div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="shown[&#039;joinedAt&#039;]" x-bind:disabled="shown[&#039;joinedAt&#039;] &amp;&amp; shownCount() === 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 ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><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="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Joined
</div></div></div>
</template></div>
                    </div>
    <div data-slot="table-container" role="region" tabindex="0" aria-label="Workspace members"                 class="relative w-full overflow-x-auto outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-nq-focus">
        <div data-slot="table" role="table" aria-label="Workspace members"  x-bind:style="'grid-template-columns: repeat(' + (shownCount() + 1) + ', auto)'"  x-bind:data-density="density"               class="grid w-full min-w-max text-body-sm">
            <div data-slot="table-header" role="rowgroup" class="contents">
                <div role="row" data-slot="table-row" class="col-span-full grid grid-cols-subgrid border-b border-border">
                                                                                                            <div role="columnheader" data-slot="table-head" data-col="name" x-show="shown['name']"  x-bind:class="pad"  x-bind:aria-sort="ariaSort('name')"                             class="flex items-center h-row text-start align-middle text-caption font-medium whitespace-nowrap text-muted-foreground">
                                                            <button type="button"  x-on:click="toggleSort('name', $event.shiftKey)"
                                    x-bind:class="sortOf('name') ? 'text-foreground' : ''"
                                    class="-mx-1.5 inline-flex h-7 max-w-full items-center gap-1 rounded-control px-1.5 outline-none transition-colors duration-150 ease-nq hover:bg-nq-hover hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus ">
                                    <span >Member</span>
                                    <svg aria-hidden="true" x-show="! sortOf('name')" class="size-3.5 shrink-0 opacity-40" 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>                                    <x-lucide-arrow-up aria-hidden="true" class="size-3.5 shrink-0" x-show="sortOf('name') === 'asc'" style="display: none" />
                                    <x-lucide-arrow-down aria-hidden="true" class="size-3.5 shrink-0" x-show="sortOf('name') === 'desc'" style="display: none" />
                                                                    </button>
                                                                                </div>
                                                                    <div role="columnheader" data-slot="table-head" data-col="email" x-show="shown['email']"  x-bind:class="pad"                             class="flex items-center h-row text-start align-middle text-caption font-medium whitespace-nowrap text-muted-foreground">
                                                            Email address
                                                                                </div>
                                                                    <div role="columnheader" data-slot="table-head" data-col="role" x-show="shown['role']"  x-bind:class="pad"  x-bind:aria-sort="ariaSort('role')"                             class="flex items-center h-row text-start align-middle text-caption font-medium whitespace-nowrap text-muted-foreground">
                                                            <button type="button"  x-on:click="toggleSort('role', $event.shiftKey)"
                                    x-bind:class="sortOf('role') ? 'text-foreground' : ''"
                                    class="-mx-1.5 inline-flex h-7 max-w-full items-center gap-1 rounded-control px-1.5 outline-none transition-colors duration-150 ease-nq hover:bg-nq-hover hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus ">
                                    <span >Role</span>
                                    <svg aria-hidden="true" x-show="! sortOf('role')" class="size-3.5 shrink-0 opacity-40" 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>                                    <x-lucide-arrow-up aria-hidden="true" class="size-3.5 shrink-0" x-show="sortOf('role') === 'asc'" style="display: none" />
                                    <x-lucide-arrow-down aria-hidden="true" class="size-3.5 shrink-0" x-show="sortOf('role') === 'desc'" style="display: none" />
                                                                    </button>
                                                                                </div>
                                                                    <div role="columnheader" data-slot="table-head" data-col="lastActive" x-show="shown['lastActive']"  x-bind:class="pad"  x-bind:aria-sort="ariaSort('lastActive')"                             class="flex items-center h-row text-start align-middle text-caption font-medium whitespace-nowrap text-muted-foreground">
                                                            <button type="button"  x-on:click="toggleSort('lastActive', $event.shiftKey)"
                                    x-bind:class="sortOf('lastActive') ? 'text-foreground' : ''"
                                    class="-mx-1.5 inline-flex h-7 max-w-full items-center gap-1 rounded-control px-1.5 outline-none transition-colors duration-150 ease-nq hover:bg-nq-hover hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus ">
                                    <span >Last active</span>
                                    <svg aria-hidden="true" x-show="! sortOf('lastActive')" class="size-3.5 shrink-0 opacity-40" 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>                                    <x-lucide-arrow-up aria-hidden="true" class="size-3.5 shrink-0" x-show="sortOf('lastActive') === 'asc'" style="display: none" />
                                    <x-lucide-arrow-down aria-hidden="true" class="size-3.5 shrink-0" x-show="sortOf('lastActive') === 'desc'" style="display: none" />
                                                                    </button>
                                                                                </div>
                                                                    <div role="columnheader" data-slot="table-head" data-col="joinedAt" x-show="shown['joinedAt']"  x-bind:class="pad"  x-bind:aria-sort="ariaSort('joinedAt')"                             class="flex items-center h-row text-end justify-end align-middle text-caption font-medium whitespace-nowrap text-muted-foreground">
                                                            <button type="button"  x-on:click="toggleSort('joinedAt', $event.shiftKey)"
                                    x-bind:class="sortOf('joinedAt') ? 'text-foreground' : ''"
                                    class="-mx-1.5 inline-flex h-7 max-w-full items-center gap-1 rounded-control px-1.5 outline-none transition-colors duration-150 ease-nq hover:bg-nq-hover hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus flex-row-reverse">
                                    <span >Joined</span>
                                    <svg aria-hidden="true" x-show="! sortOf('joinedAt')" class="size-3.5 shrink-0 opacity-40" 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>                                    <x-lucide-arrow-up aria-hidden="true" class="size-3.5 shrink-0" x-show="sortOf('joinedAt') === 'asc'" style="display: none" />
                                    <x-lucide-arrow-down aria-hidden="true" class="size-3.5 shrink-0" x-show="sortOf('joinedAt') === 'desc'" style="display: none" />
                                                                    </button>
                                                                                </div>
                                                                <div role="columnheader" data-slot="table-head"  x-bind:class="pad" class="flex items-center h-row w-12 text-start align-middle text-caption font-medium whitespace-nowrap text-muted-foreground"><span class="sr-only">Actions</span></div>
                                    </div>
            </div>
                            <div role="rowgroup" class="contents" data-slot="table-body" x-show="rowCount === 0" style="display: none">
                    <div role="row" data-slot="table-row" class="col-span-full grid grid-cols-subgrid border-0">
                        <div role="cell" data-slot="table-cell" class="col-span-full h-auto p-0 whitespace-normal">
                            <div x-show="isFiltered" style="display: none">
                                <div data-slot="empty-state" class="flex flex-col items-center justify-center gap-3 border-dashed border-border px-6 py-12 text-center rounded-card border-0">
            <span data-slot="state-icon" class="inline-flex size-10 items-center justify-center rounded-control border border-border bg-card [&amp;_svg]:size-5 text-muted-foreground">
            <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="m21 21-4.34-4.34"/>
  <circle cx="11" cy="11" r="8"/>
</svg>        </span>
        <div class="flex max-w-sm flex-col gap-1">
        <p class="text-label text-foreground">No matching results</p>
                    <p class="text-body-sm text-muted-foreground">Try a different search or clear the filters.</p>
            </div>
    <button type="button" x-on:click="resetFilters()" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border border-border bg-card text-foreground font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none hover:bg-nq-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 h-control-sm px-2.5">Clear filters</button>
    </div>
                            </div>
                            <div x-show="! isFiltered" style="display: none">
                                <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">
  <polyline points="22 12 16 12 14 15 10 15 8 12 2 12"/>
  <path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/>
</svg>        </span>
        <div class="flex max-w-sm flex-col gap-1">
        <p class="text-label text-foreground">No members yet</p>
                    <p class="text-body-sm text-muted-foreground">Invite the first person to get started.</p>
            </div>
    </div>                            </div>
                        </div>
                    </div>
                </div>
                <template x-for="(row, index) in pageRows" x-bind:key="rid(row)">
                    <div role="rowgroup" class="contents" data-slot="table-body">
                        <div role="row" data-slot="table-row" data-row tabindex="-1" x-bind:tabindex="index === Math.min(active, pageRows.length - 1) ? 0 : -1"
                            x-bind:data-state="isSelected(row) ? 'selected' : null" x-bind:aria-selected="isSelected(row) ? 'true' : null"
                            x-bind:aria-expanded="canExpand(row) ? String(isOpen(row)) : null" x-on:focus="if ($event.target === $event.currentTarget) active = index"
                            x-on:keydown="rowKey($event, row, index, false)"
                             x-on:contextmenu="rowContext(row, $event)" x-on:touchstart.passive="rowTouch(row, $event)" x-on:touchmove.passive="rowTouchEnd()" x-on:touchend="rowTouchEnd()" x-on:touchcancel="rowTouchEnd()"                                                         x-bind:class="(isOpen(row) ? 'border-b-0 ' : '') + (ctxOpen && ctxRow === row ? 'bg-nq-hover' : '')"
                            class="col-span-full grid grid-cols-subgrid group/row border-b border-border outline-none transition-colors duration-150 ease-nq focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-nq-focus data-[state=selected]:bg-nq-selected hover:bg-nq-hover ">
                                                                                            <div role="cell" data-slot="table-cell" data-cell-col="name" x-show="shown['name']"  x-bind:class="pad"
                                                                        class="flex items-center relative h-row align-middle whitespace-nowrap  ">
                                                                                                                    <span  class="flex min-w-0 items-center gap-1.5 " >
                                                                                            <span data-slot="avatar" class="relative inline-flex size-8 shrink-0 select-none items-center justify-center overflow-hidden rounded-full bg-secondary align-middle text-caption font-medium text-secondary-foreground">
                                                    <span data-slot="avatar-fallback" aria-hidden="true" class="flex size-full items-center justify-center" x-text="initials(shownText(row, col(&#039;name&#039;)))"></span>
                                                    <template x-if="avatarSrc(row, col(&#039;name&#039;))"><img data-slot="avatar-image" alt="" x-bind:src="avatarSrc(row, col(&#039;name&#039;))" x-on:error="$el.remove()" class="absolute inset-0 size-full object-cover"></template>
                                                </span>
                                                <span class="flex min-w-0 flex-col">
                                                    <span class="flex items-center gap-1.5 truncate text-label text-foreground">
                                                        <span class="truncate" x-text="shownText(row, col(&#039;name&#039;))"></span>
                                                                                                                    <span data-slot="badge" x-show="row['self']" style="display: none" class="inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-[4px] border border-border px-1.5 text-caption font-medium text-muted-foreground">You</span>
                                                                                                            </span>
                                                    <bdi  dir="ltr"  class="truncate text-caption text-muted-foreground" x-show="secondary(row, col(&#039;name&#039;))" x-text="secondary(row, col(&#039;name&#039;))" style="display: none"></bdi>
                                                </span>
                                                                                                                                </span>
                                                                    </div>
                                                                                            <div role="cell" data-slot="table-cell" data-cell-col="email" x-show="shown['email']"  x-bind:class="pad"
                                                                        class="flex items-center relative h-row align-middle whitespace-nowrap  ">
                                                                                                                    <span  class="flex min-w-0 items-center gap-1.5 " >
                                                                                            <span class="min-w-0 flex-1  " x-text="shownText(row, col(&#039;email&#039;))"></span>
                                                                                                                                </span>
                                                                    </div>
                                                                                            <div role="cell" data-slot="table-cell" data-cell-col="role" x-show="shown['role']"  x-bind:class="pad"
                                                                        class="flex items-center relative h-row align-middle whitespace-nowrap  ">
                                                                                                                    <span  class="flex min-w-0 items-center gap-1.5 " >
                                                                                            <span data-slot="badge" x-show="shownText(row, col(&#039;role&#039;)) !== ''" x-bind:style="hueStyle(row, col(&#039;role&#039;))" style="display: none"
                                                    class="inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-[4px] border border-transparent bg-[var(--tag-soft)] px-1.5 text-caption font-medium text-[var(--tag-solid)]" x-text="shownText(row, col(&#039;role&#039;))"></span>
                                                                                                                                </span>
                                                                    </div>
                                                                                            <div role="cell" data-slot="table-cell" data-cell-col="lastActive" x-show="shown['lastActive']"  x-bind:class="pad"
                                                                        class="flex items-center relative h-row align-middle whitespace-nowrap  ">
                                                                                                                    <span  class="flex min-w-0 items-center gap-1.5 " >
                                                                                            <span class="min-w-0 flex-1  " x-text="shownText(row, col(&#039;lastActive&#039;))"></span>
                                                                                                                                </span>
                                                                    </div>
                                                                                            <div role="cell" data-slot="table-cell" data-cell-col="joinedAt" x-show="shown['joinedAt']"  x-bind:class="pad"
                                                                        class="flex items-center relative h-row align-middle whitespace-nowrap text-end justify-end ">
                                                                                                                    <span  class="flex min-w-0 items-center gap-1.5 justify-end" >
                                                                                            <span class="min-w-0 flex-1  " x-text="shownText(row, col(&#039;joinedAt&#039;))"></span>
                                                                                                                                </span>
                                                                    </div>
                                                            <div role="cell" data-slot="table-cell"  x-bind:class="pad" class="flex items-center h-row w-12 pe-2 text-end align-middle whitespace-nowrap">
                                    <div data-slot="dropdown-menu" x-data="nqDropdownMenu(false)" x-modelable="open" class="contents"><button data-slot="data-table-row-actions"
     type="button"                         x-bind="trigger" x-ref="trigger" x-bind:aria-label="say(&#039;rowActions&#039;, row)" x-show="hasActions(row)" x-bind:tabindex="index === Math.min(active, pageRows.length - 1) ? 0 : -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 hover:bg-nq-hover size-control-sm p-0 text-muted-foreground opacity-0 group-hover/row:opacity-100 group-focus-within/row:opacity-100 group-data-[state=selected]/row:opacity-100 data-popup-open:opacity-100 pointer-coarse:opacity-100">
        <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">
  <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-group" role="group" ><template x-if="actionOn(row, 0)">
                                                        <div role="none" class="contents">
                                                                                                                        <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="act(&#039;role&#039;, row)" x-bind:data-disabled="actionOff(row, 0) ? &#039;&#039; : null" x-bind:aria-disabled="actionOff(row, 0) ? &#039;true&#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 aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/>
  <path d="m9 12 2 2 4-4"/>
</svg>                                                                Change role…</div>
                                                        </div>
                                                    </template>
                                                                                                    <template x-if="actionOn(row, 1)">
                                                        <div role="none" class="contents">
                                                            <template x-if="sepBefore(row, 1)"><div data-slot="dropdown-menu-separator" role="separator" aria-orientation="horizontal" class="-mx-1.5 my-1.5 h-px bg-border"></div>
</template>                                                            <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="act(&#039;transfer&#039;, row)" x-bind:data-disabled="actionOff(row, 1) ? &#039;&#039; : null" x-bind:aria-disabled="actionOff(row, 1) ? &#039;true&#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 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.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z"/>
  <path d="M5 21h14"/>
</svg>                                                                Transfer ownership…</div>
                                                        </div>
                                                    </template>
                                                                                                    <template x-if="actionOn(row, 2)">
                                                        <div role="none" class="contents">
                                                            <template x-if="sepBefore(row, 2)"><div data-slot="dropdown-menu-separator" role="separator" aria-orientation="horizontal" class="-mx-1.5 my-1.5 h-px bg-border"></div>
</template>                                                            <div data-slot="dropdown-menu-item" role="menuitem" data-variant="danger" x-bind="item"
        x-on:click="act(&#039;remove&#039;, row)" x-bind:data-disabled="actionOff(row, 2) ? &#039;&#039; : null" x-bind:aria-disabled="actionOff(row, 2) ? &#039;true&#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 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 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="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
  <circle cx="9" cy="7" r="4"/>
  <line x1="22" x2="16" y1="11" y2="11"/>
</svg>                                                                Remove from workspace…</div>
                                                        </div>
                                                    </template></div></div>
</template></div>
                                </div>
                                                    </div>
                                            </div>
                </template>
                    </div>
    </div>
            <nav data-slot="data-table-pagination" aria-label="Pagination" x-show="paged" style="display: none" class="flex flex-wrap items-center justify-end gap-2">
                        <span class="text-caption tabular-nums text-muted-foreground" aria-live="polite" x-text="rangeText()"></span>
            <button type="button" aria-label="Previous page" x-bind:disabled="page === 0 ? '' : null" x-on:click="setPage(page - 1)"
                class="inline-flex size-control-sm shrink-0 items-center justify-center rounded-control text-foreground outline-none hover:bg-nq-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 [&_svg]:size-4"><svg aria-hidden="true" class="rtl:-scale-x-100" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="m15 18-6-6 6-6"/>
</svg></button>
            <button type="button" aria-label="Next page" x-bind:disabled="page >= pageCount - 1 ? '' : null" x-on:click="setPage(page + 1)"
                class="inline-flex size-control-sm shrink-0 items-center justify-center rounded-control text-foreground outline-none hover:bg-nq-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 [&_svg]:size-4"><svg aria-hidden="true" class="rtl:-scale-x-100" 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="m9 18 6-6-6-6"/>
</svg></button>
        </nav>
                <div data-slot="data-table-context-menu" x-data="nqContextMenu()" x-effect="menuClosed(open)" class="contents">
            <template x-teleport="body">
    <div data-slot="context-menu-content" x-bind="popup" x-init="popupEl = $el" x-nq-presence="open"
        class="fixed 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"><template x-if="ctxRow && actionOn(ctxRow, 0)">
                        <div role="none" class="contents">
                                                        <div data-slot="context-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="act(&#039;role&#039;, ctxRow)" x-bind:data-disabled="actionOff(ctxRow, 0) ? &#039;&#039; : null" x-bind:aria-disabled="actionOff(ctxRow, 0) ? &#039;true&#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 aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/>
  <path d="m9 12 2 2 4-4"/>
</svg>                                Change role…</div>
                        </div>
                    </template>
                                    <template x-if="ctxRow && actionOn(ctxRow, 1)">
                        <div role="none" class="contents">
                            <template x-if="sepBefore(ctxRow, 1)"><div data-slot="context-menu-separator" role="separator" aria-orientation="horizontal" class="-mx-1.5 my-1.5 h-px bg-border"></div>
</template>                            <div data-slot="context-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="act(&#039;transfer&#039;, ctxRow)" x-bind:data-disabled="actionOff(ctxRow, 1) ? &#039;&#039; : null" x-bind:aria-disabled="actionOff(ctxRow, 1) ? &#039;true&#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 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.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z"/>
  <path d="M5 21h14"/>
</svg>                                Transfer ownership…</div>
                        </div>
                    </template>
                                    <template x-if="ctxRow && actionOn(ctxRow, 2)">
                        <div role="none" class="contents">
                            <template x-if="sepBefore(ctxRow, 2)"><div data-slot="context-menu-separator" role="separator" aria-orientation="horizontal" class="-mx-1.5 my-1.5 h-px bg-border"></div>
</template>                            <div data-slot="context-menu-item" role="menuitem" data-variant="danger" x-bind="item"
        x-on:click="act(&#039;remove&#039;, ctxRow)" x-bind:data-disabled="actionOff(ctxRow, 2) ? &#039;&#039; : null" x-bind:aria-disabled="actionOff(ctxRow, 2) ? &#039;true&#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 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 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="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
  <circle cx="9" cy="7" r="4"/>
  <line x1="22" x2="16" y1="11" y2="11"/>
</svg>                                Remove from workspace…</div>
                        </div>
                    </template></div>
</template>
        </div>
        <span role="status" aria-live="polite" class="sr-only" x-text="announce"></span>
</div>
            </div></div>
                    <div data-slot="tabs-panel" x-bind="panel('pending')"
     hidden     class="outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus mt-4"><ul aria-label="Pending invites" class="flex flex-col divide-y divide-border rounded-card border border-border bg-card">
                                                                                <li class="flex flex-wrap items-center gap-x-4 gap-y-2 px-4 py-3">
                                <span aria-hidden="true" class="flex size-8 shrink-0 items-center justify-center rounded-full bg-secondary text-muted-foreground"><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="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7"/>
  <rect x="2" y="4" width="20" height="16" rx="2"/>
</svg></span>
                                <div class="flex min-w-0 flex-1 flex-col">
                                    <bdi dir="ltr" class="truncate text-label text-foreground">new@acme.test</bdi>
                                    <span class="text-caption text-muted-foreground">
                                        Invited by Sara Alharbi · Sent <time data-slot="date-time" datetime="2026-09-27T00:00:00+00:00" dir="auto"  title="Sep 27, 2026"     class="tabular-nums [unicode-bidi:isolate]">2 days ago</time>
                                    </span>
                                </div>
                                <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">Member</span>
                                                                    <span data-slot="status" data-tone="info" class="inline-flex min-w-0 items-center gap-1.5 text-foreground text-caption">
            <svg aria-hidden="true" class="size-3.5 shrink-0 text-nq-info-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"/>
  <circle cx="12" cy="12" r="1"/>
</svg>        <span class="truncate"  title="Expires 4 days from now" >Expires <time data-slot="date-time" datetime="2026-10-04T00:00:00+00:00" dir="auto"  title="Oct 4, 2026"     class="tabular-nums [unicode-bidi:isolate]">4 days from now</time></span>
</span>
                                                                                                    <div class="flex items-center gap-1">
                                                                                    <button data-slot="button"
     type="button"                         data-id="i1" x-on:click="resend($el.dataset.id)" x-bind:data-disabled="isBusy($el.dataset.id) ? &#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-sm px-2.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"/>
  <path d="M21 3v5h-5"/>
</svg>Resend</button>
                                                                                                                            <button data-slot="button"
     type="button"                         data-id="i1" x-on:click="revokeInvite($el.dataset.id)" x-bind:data-disabled="isBusy($el.dataset.id) ? &#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 text-foreground hover:bg-nq-hover h-control-sm px-2.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M18 6 6 18"/>
  <path d="m6 6 12 12"/>
</svg>Revoke</button>
                                                                            </div>
                                                            </li>
                                            </ul></div>
</div>
            <div data-slot="members-leave" class="flex flex-col gap-3 rounded-card border border-border p-4 sm:flex-row sm:items-center sm:justify-between">
            <div class="flex min-w-0 flex-col gap-0.5">
                <span class="text-label text-foreground">Leave workspace</span>
                <span class="text-body-sm text-muted-foreground">You are the only owner. Transfer ownership to another member before you leave.</span>
            </div>
            <button data-slot="button"
     type="button"                  disabled      data-disabled     x-on:click="openLeave()" class="inline-flex select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border border-transparent font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 bg-destructive text-destructive-foreground hover:bg-[color-mix(in_oklab,var(--nq-danger-solid)_88%,var(--nq-fg))] h-control px-[var(--nq-control-pad)] shrink-0">
        <svg aria-hidden="true" class="rtl:-scale-x-100" 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="m16 17 5-5-5-5"/>
  <path d="M21 12H9"/>
  <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
</svg>Leave workspace</button>
        </div>
            <div data-slot="dialog" x-data="nqDialog(false)" x-modelable="open" x-id="['nq-dialog']" x-model="inviteOpen" class="contents">
    <template x-teleport="body">
    <div data-slot="dialog-portal">
        <div data-slot="dialog-backdrop" x-nq-presence="open" x-on:click="close()" class="fixed inset-0 z-50 bg-nq-fg/15 dark:bg-nq-bg/60 transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0"></div>
        <div data-slot="dialog-content" x-bind="popup" x-nq-presence="open" x-trap.noscroll="open"
            class="fixed inset-0 z-50 m-auto grid h-fit w-[calc(100%-2rem)] gap-4 rounded-floating border border-border bg-popover p-6 text-popover-foreground outline-none max-h-[calc(100dvh-2rem)] overflow-y-auto transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0 max-w-lg">
            <form x-on:submit.prevent="submitInvite()" class="flex flex-col gap-5" novalidate>
                    <div data-slot="dialog-header" class="flex flex-col gap-1.5 pe-8 text-start"><h2 data-slot="dialog-title" :id="$id('nq-dialog', 'title')" class="text-h3 text-foreground">Invite people</h2>
                        <p data-slot="dialog-description" :id="$id('nq-dialog', 'description')" class="text-body-sm text-muted-foreground">They get an email with a link to join. Invites expire after a while.</p></div>
                    <div class="flex flex-col gap-4">
                        <div data-slot="field" x-data="nqField(false)" x-modelable="invalid" x-id="['nq-field']"
         data-valid     x-model="emailsBad" class="flex flex-col gap-1.5">
    <label data-slot="field-label"  class="text-label text-foreground data-disabled:opacity-50">Email addresses</label>
                            <div data-slot="tag-input" x-data="nqTagInput([], Object.assign({}, { validate: (tag, tags) => (validateEmail(tag, tags)) }))" x-modelable="tags" x-bind="root"
         x-model="draft.emails" class="relative w-full">
    <div data-slot="tag-input-box" x-bind="box"
        class="flex w-full min-w-0 flex-wrap items-center gap-1.5 rounded-control border border-input bg-card px-2 py-1 text-body text-foreground min-h-[max(var(--nq-control),var(--nq-touch-min,0px))] transition-colors duration-150 ease-nq focus-within:border-nq-focus focus-within:outline-1 focus-within:outline-nq-focus has-[[data-invalid]]:border-nq-danger has-[[aria-invalid=true]]:border-nq-danger">
        <template x-for="(tag, i) in tags" :key="tag">
            <span data-slot="tag-input-tag" data-variant="neutral" class="inline-flex w-fit shrink-0 items-center justify-center whitespace-nowrap rounded-control border border-transparent bg-muted px-2 py-0.5 font-medium text-foreground h-6 gap-0.5 ps-2 pe-0.5 text-body-sm">
                <bdi x-text="tag"></bdi>
                <button type="button"  :aria-label="'Remove' + ' ' + tag" @click.stop="removeAt(i)"
                    class="inline-flex size-5 items-center justify-center rounded-[3px] text-muted-foreground outline-none hover:bg-nq-hover hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus">
                    <span aria-hidden="true" class="flex [&_svg]:size-3"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M18 6 6 18"/>
  <path d="m6 6 12 12"/>
</svg></span>
                </button>
            </span>
        </template>
        <input data-slot="tag-input-field" x-ref="field" x-bind="field" autocomplete="off"             :placeholder="tags.length ? undefined : 'name@example.com'"
                        dir="ltr" aria-label="Email addresses" class="h-7 min-w-24 flex-1 border-0 bg-transparent px-1 text-body outline-none placeholder:text-muted-foreground pointer-coarse:text-[16px]">
    </div>
        <p x-show="error" x-cloak style="display: none" role="alert" data-slot="tag-input-error" x-text="error" class="mt-1.5 text-caption text-nq-danger-text"></p>
    <span role="status" aria-live="polite" class="sr-only" x-text="message"></span>
    </div>
                            <div data-slot="field-error" role="alert" x-show="invalid"  style="display: none"  class="text-caption text-nq-danger-text"><span x-text="emailsMsg"></span></div>
                            <p data-slot="field-description" class="text-caption text-muted-foreground">Press Enter or comma after each address.</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">Role</label>
                            <div data-slot="select" x-data="nqSelect('member', false)" x-modelable="value" x-id="['nq-select']" x-model="draft.role" 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('admin', 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('admin')" 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">Admin</span>
</div>
                                                                            <div data-slot="select-item" x-bind="item('member', 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('member')" 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">Member</span>
</div>
    </div>
</template>
    </div>
                            <p x-show="roleDescription !== ''" x-text="roleDescription" style="display: none" class="text-caption text-muted-foreground"></p>
</div>
                        <template x-if="formError !== null">
                            <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="formError"></span></div>
            </div>
    </div>
                        </template>
                    </div>
                    <div data-slot="dialog-footer" class="flex flex-col-reverse gap-2 sm:flex-row sm:justify-end"><button data-slot="button"
     type="button"                         x-on:click="inviteOpen = false" x-bind:disabled="busy ? &#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 text-foreground hover:bg-nq-hover h-control px-[var(--nq-control-pad)]">
        Cancel</button>
                        <button data-slot="button"
     type="submit"                         x-bind:aria-busy="busy ? &#039;true&#039; : null" x-bind:data-disabled="busy ? &#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)]">
        <svg data-slot="spinner" aria-hidden="true" style="display: none;" x-show="busy" 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>                            Send invites</button></div>
                </form>
                            <button type="button" data-slot="dialog-close" x-on:click="close()" aria-label="Close"
                    class="absolute end-3 top-3 inline-flex size-8 items-center justify-center rounded-control text-muted-foreground transition-colors duration-150 hover:bg-nq-hover hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus [&_svg]:size-4"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M18 6 6 18"/>
  <path d="m6 6 12 12"/>
</svg></button>
                    </div>
    </div>
</template>
</div>
            <div data-slot="dialog" x-data="nqDialog(false)" x-modelable="open" x-id="['nq-dialog']" x-model="roleOpen" class="contents">
    <template x-teleport="body">
    <div data-slot="dialog-portal">
        <div data-slot="dialog-backdrop" x-nq-presence="open" x-on:click="close()" class="fixed inset-0 z-50 bg-nq-fg/15 dark:bg-nq-bg/60 transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0"></div>
        <div data-slot="dialog-content" x-bind="popup" x-nq-presence="open" x-trap.noscroll="open"
            class="fixed inset-0 z-50 m-auto grid h-fit w-[calc(100%-2rem)] gap-4 rounded-floating border border-border bg-popover p-6 text-popover-foreground outline-none max-h-[calc(100dvh-2rem)] overflow-y-auto transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0 max-w-md">
            <div data-slot="dialog-header" class="flex flex-col gap-1.5 pe-8 text-start"><h2 data-slot="dialog-title" :id="$id('nq-dialog', 'title')" class="text-h3 text-foreground"><span x-text="roleDialogTitle"></span></h2>
                    <p data-slot="dialog-description" :id="$id('nq-dialog', 'description')" class="text-body-sm text-muted-foreground">The new role applies on their next request.</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">Role</label>
                    <div data-slot="select" x-data="nqSelect('admin', false)" x-modelable="value" x-id="['nq-select']" x-model="roleDraft" 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('admin', 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('admin')" 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">Admin</span>
</div>
                                                            <div data-slot="select-item" x-bind="item('member', 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('member')" 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">Member</span>
</div>
    </div>
</template>
    </div>
</div>
                <template x-if="roleError !== null">
                    <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="roleError"></span></div>
            </div>
    </div>
                </template>
                <div data-slot="dialog-footer" class="flex flex-col-reverse gap-2 sm:flex-row sm:justify-end"><button data-slot="button"
     type="button"                         x-on:click="roleOpen = false" x-bind:disabled="busy ? &#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 text-foreground hover:bg-nq-hover h-control px-[var(--nq-control-pad)]">
        Cancel</button>
                    <button data-slot="button"
     type="button"                         x-on:click="saveRole()" x-bind:aria-busy="busy ? &#039;true&#039; : null" x-bind:data-disabled="busy ? &#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)]">
        <svg data-slot="spinner" aria-hidden="true" style="display: none;" x-show="busy" 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>                        Save role</button></div>
                            <button type="button" data-slot="dialog-close" x-on:click="close()" aria-label="Close"
                    class="absolute end-3 top-3 inline-flex size-8 items-center justify-center rounded-control text-muted-foreground transition-colors duration-150 hover:bg-nq-hover hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus [&_svg]:size-4"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M18 6 6 18"/>
  <path d="m6 6 12 12"/>
</svg></button>
                    </div>
    </div>
</template>
</div>
            <div data-slot="alert-dialog" x-data="nqAlertDialog(false)" x-modelable="open" x-id="['nq-alert-dialog']" x-model="confirmOpen" class="contents">
    <template x-teleport="body">
    <div data-slot="alert-dialog-portal">
        <div data-slot="alert-dialog-backdrop" x-nq-presence="open" class="fixed inset-0 z-50 bg-nq-fg/15 dark:bg-nq-bg/60 transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0"></div>
        <div data-slot="alert-dialog-content" x-bind="popup" x-nq-presence="open" x-trap.noscroll="open"
            class="fixed inset-0 z-50 m-auto grid h-fit w-[calc(100%-2rem)] max-w-md gap-4 rounded-floating border border-border bg-popover p-6 text-popover-foreground outline-none max-h-[calc(100dvh-2rem)] overflow-y-auto transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0">
            <div data-slot="alert-dialog-header" class="flex flex-col gap-1.5 text-start"><h2 data-slot="alert-dialog-title" :id="$id('nq-alert-dialog', 'title')" class="text-h3 text-foreground"><span x-text="confirmTitle"></span></h2>
                    <p data-slot="alert-dialog-description" :id="$id('nq-alert-dialog', 'description')" class="text-body-sm text-muted-foreground"><span x-text="confirmBody"></span></p></div>
                <template x-if="confirmError !== null">
                    <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="confirmError"></span></div>
            </div>
    </div>
                </template>
                <div data-slot="alert-dialog-footer" class="flex flex-col-reverse gap-2 sm:flex-row sm:justify-end"><button data-slot="button"
     type="button"                         x-on:click="closeConfirm()" x-bind:disabled="busy ? &#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 text-foreground hover:bg-nq-hover h-control px-[var(--nq-control-pad)]">
        Cancel</button>
                    <button data-slot="button"
     type="button"                         x-on:click="runConfirm()" x-bind:aria-busy="busy ? &#039;true&#039; : null" x-bind:data-disabled="busy ? &#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)]">
        <svg data-slot="spinner" aria-hidden="true" style="display: none;" x-show="busy" 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 x-text="confirmAction"></span></button></div>
        </div>
    </div>
</template>
</div>
    </div>
```
