<div
  class="grid h-full min-h-0 overflow-hidden bg-background"
  [ngStyle]="layoutStyles()"
>
  <aside
    appThemeNode="dmConversationsPanel"
    class="flex min-h-0 overflow-hidden border-r border-border bg-card"
    [ngStyle]="listPanelStyles()"
  >
    <section class="flex h-full w-full min-w-0 flex-col">
      <header
        appThemeNode="dmConversationsHeader"
        class="flex h-14 shrink-0 items-center gap-2 border-b border-border px-3"
      >
        <div class="grid h-8 w-8 place-items-center rounded-lg bg-secondary text-muted-foreground">
          <ng-icon
            name="lucideMessageCircle"
            class="h-4 w-4"
          />
        </div>
        <div class="min-w-0">
          <h1 class="truncate text-sm font-semibold text-foreground">Direct Messages</h1>
          <p class="text-xs text-muted-foreground">{{ directMessages.conversations().length }} chats</p>
        </div>
      </header>

      <div
        appThemeNode="dmConversationList"
        class="min-h-0 flex-1 overflow-y-auto p-2"
      >
        @if (directMessages.conversations().length === 0) {
          <div class="flex h-full items-center justify-center px-4 text-center text-sm text-muted-foreground">No direct messages yet.</div>
        } @else {
          <div class="space-y-1">
            @for (conversation of directMessages.conversations(); track conversation.id) {
              <div
                appThemeNode="dmConversationItem"
                class="group flex w-full items-center gap-2 rounded-md px-2 py-2 text-left transition-colors hover:bg-secondary/60"
                [class.bg-primary/10]="isSelectedConversation(conversation)"
                [class.text-foreground]="isSelectedConversation(conversation)"
                [attr.aria-current]="isSelectedConversation(conversation) ? 'page' : null"
                (click)="openConversation(conversation)"
                (keydown.enter)="openConversation(conversation)"
                (keydown.space)="openConversation(conversation)"
                role="button"
                tabindex="0"
              >
                <app-user-avatar
                  [name]="peerName(conversation)"
                  [avatarUrl]="peerAvatarUrl(conversation)"
                  size="sm"
                />
                <div class="min-w-0 flex-1">
                  <div class="flex items-center justify-between gap-2">
                    <p class="truncate text-sm font-medium text-foreground">{{ peerName(conversation) }}</p>
                    @if (conversation.unreadCount > 0) {
                      <span class="rounded-full bg-amber-400 px-1.5 py-0.5 text-[10px] font-semibold text-black">
                        {{ formatUnreadCount(conversation.unreadCount) }}
                      </span>
                    }
                  </div>
                  <p class="truncate text-xs text-muted-foreground">{{ lastMessagePreview(conversation) }}</p>
                </div>
                <button
                  type="button"
                  class="grid h-7 w-7 shrink-0 place-items-center rounded-md text-muted-foreground opacity-0 transition hover:bg-destructive/10 hover:text-destructive focus:opacity-100 group-hover:opacity-100"
                  [attr.aria-label]="'Forget ' + peerName(conversation)"
                  [title]="'Forget ' + peerName(conversation)"
                  (click)="forgetConversation($event, conversation)"
                >
                  <ng-icon
                    name="lucideTrash2"
                    class="h-3.5 w-3.5"
                  />
                </button>
              </div>
            }
          </div>
        }
      </div>

      <div
        appThemeNode="dmVoiceControlsArea"
        class="border-t border-border px-2 py-3"
      >
        <app-voice-controls />
      </div>
    </section>
  </aside>

  <main
    appThemeNode="dmChatPanel"
    class="relative min-h-0 min-w-0 overflow-hidden bg-background"
    [ngStyle]="chatPanelStyles()"
  >
    <app-dm-chat />
  </main>
</div>
