# T11 — Session Detail Side Panel Template
## Generates: `components/detail-panel/detail-panel.component.html` + `.scss`

---

## Step 1 — Reference Files (fill in before running)

```
"Read CLAUDE.md.
Read @[REF:SIDE_PANEL] — learn how we build slide-in side panels:
  open/close animation, backdrop, header with close button,
  scrollable body, section separators.
Read @[REF:DETAIL_PAGE] — learn how we display entity detail fields:
  label/value pairs, grid layout, status indicators.
Then implement the template described below."
```

**What to look for in your references:**
- Side panel or drawer component — is there a `<gb-side-panel>` wrapper?
- If no wrapper component, how is slide-in built (transform, transition)
- Panel header structure (title + close button)
- Scrollable body pattern
- How label/value detail rows are structured
- Status badge/pill component
- Avatar/user chip component if one exists
- Action buttons inside a panel
- Section divider/separator pattern
- How destructive actions are presented (color, confirmation)

---

## Step 2 — What This Component Is

A **slide-in side panel** from the right edge of the screen.
Shows session details and participant management for the active session.
Controlled by: `uiState.detailPanelOpen` signal.

---

## Step 3 — Content Specification

### Panel Visibility
```
Entire panel slides in/out based on: isOpen() signal
Use your project's side panel component or animation pattern.
Backdrop click: closePanel()
ESC key: closePanel() — via HostListener in TS (already done)
```

### Panel Header
```
Title: "Session Details"
Secondary text: sessionCode() in monospace style
Close button: top-right corner → closePanel()
Use your project's panel/drawer header pattern.
```

### Control Request Banner
```
Show ONLY when: hasControlRequest() === true
  hasControlRequest() = computed(() => uiState.controlRequest() !== null)

Content:
  "[controlRequest().displayName] is requesting control"
  Action: "Grant Control"  → acceptControlRequest()  [primary]
  Action: "Deny"           → uiState.clearControlRequest() [secondary]

This banner should visually stand out — use your project's
warning/alert component or a highlighted section at the top of panel body.
```

### Session Info Section
```
Section heading: "Session Info"

Display as label/value grid (use your project's detail field pattern):

  Session Code   → sessionCode()              monospace
  Status         → currentSession().status    use status badge/pill
  Mode           → currentSession().mode
  Module         → currentSession().contextModuleCode  or "—"
  Record         → currentSession().contextRecordLabel or "—"
  Started        → currentSession().startedAt formatted
  Duration       → elapsed()
  Max Seats      → currentSession().maxParticipants
```

### Participants Section
```
Section heading: "Participants" + count: participantCount()

For each participant in sortedParticipants():
  One row per participant containing:

  Avatar/initials:
    Show initials of displayName
    Background color: participant.cursorColor (at low opacity)
    Text color: participant.cursorColor

  Name:
    participant.displayName
    If participant.userId === myUserId(): append "(You)" label
    Use your project's "you" badge or muted label

  Role badge:
    participant.role
    Use your project's badge/pill component
    Style varies by role: Host=primary, CoEditor=info,
    Presenter=warning, Viewer=muted

  Control indicator:
    Show edit/pen icon when: participant.hasControl === true
    Use your project's icon in teal/active color

  Host actions (show row of actions ONLY when isHost() === true
  AND participant.userId !== myUserId()):
    "Give Control" → grantControl(participant.userId)
      show only when: participant.hasControl === false
      use compact/small secondary button
    "Remove"       → [destructive] removeParticipant(participant.userId)
      use compact/small danger button
      (add removeParticipant() to TS if not present)

@for sortedParticipants() track participantId
```

### Invite Section
```
Section heading: "Invite"
Button: "Add Participants"
  click: uiState.openInviteModal(currentSession().sessionId)
  use your project's secondary or outline button
  icon: your project's "add-user" or "plus" icon
```

### Audit Trail Section (collapsible)
```
Section heading: "Recent Activity"
Collapsed by default — use your project's collapsible pattern.

For each event in recentEvents() (last 5–10):
  Show: eventType + triggeredBy + eventDate (relative time)
  e.g. "Session Started · John · 4 minutes ago"

recentEvents() signal needs to be added to TS component —
  load via CollabSessionService.getRecentEvents(sessionId)
  on panel open using toSignal() or effect()
```

### Panel Footer
```
Only show when: isHost() === true

"End Session" button:
  Full-width in footer
  Destructive/danger variant
  click: endSession()
  label: "End Session for All"
  Use your project's danger button variant
```

---

## Step 4 — Angular Bindings Summary

```typescript
// Panel state
isOpen()                  Signal<boolean>   — from uiState
hasControlRequest()       Signal<boolean>   — computed

// Session data
session()                 Signal<CollabSession | null>
sessionCode()             Signal<string | null>
elapsed()                 computed string

// Participant data
sortedParticipants()      computed CollabParticipant[]
myUserId()                Signal<string | null>
isHost()                  Signal<boolean>   — computed

// Control request
controlRequest()          Signal<{userId, displayName} | null>

// Actions
closePanel()
grantControl(userId: string)
acceptControlRequest()
endSession()
```

---

## SCSS Instruction

```
Write component SCSS only for:
- The slide-in/out animation if not handled by a shared panel component
  transform: translateX(100%) → translateX(0)
  transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1)
- Avatar circle (size, initials centering)
  The color is dynamic (cursorColor) — bind via [style] in template
- Panel width: 480px on desktop, full-width on mobile
- Participant row hover state if not covered by your list pattern

Do NOT re-style anything your design system handles.
```

---

## Constraints
- Dynamic avatar color: use `[style.background-color]` and
  `[style.color]` bound to `participant.cursorColor`
  (cannot use CSS class for this since colors are runtime values)
- `@for sortedParticipants() track participant.participantId`
- All host action buttons should be visually compact — they appear
  inside a list row and should not dominate the layout
