# xpl-panel

`xpl-panel` is a stateless, composable container that defines a section on a page and can house any type of content. Panels are not dismissible and may show a colored top accent bar. Padding is applied evenly to **`.xpl-panel__content`** (all sides use the same spacing token).

## Accessibility

The panel is a generic layout container: it does not define a landmark role or trap focus. Place interactive controls in the default slot. For a named region, wrap the panel (or its content) in an element with `role="region"` and an accessible name (e.g. `aria-label`) when the panel represents a distinct section.

When an accent is present, the accent bar is a decorative `div` with `aria-hidden="true"` so assistive technologies ignore it; meaning comes from slot content.

## Token use

**Host (surface)**


| Property      | Token                                   |
| ------------- | --------------------------------------- |
| Background    | `var(--xpl-background-surface-default)` |
| Border color  | `var(--xpl-border-default)`             |
| Border width  | `var(--xpl-border-small)`               |
| Border radius | `var(--xpl-border-radius-default)`      |


**Accent bar** (`accent` ≠ `none`): height `var(--xpl-size-050)`; top radii `var(--xpl-border-radius-default)`, bottom `var(--xpl-border-radius-none)`.


| `accent`    | Background token                         |
| ----------- | ---------------------------------------- |
| `primary`   | `var(--xpl-background-brand-primary)`    |
| `secondary` | `var(--xpl-background-brand-secondary)`  |
| `positive`  | `var(--xpl-background-accent-positive)`  |
| `negative`  | `var(--xpl-background-accent-negative)`  |
| `highlight` | `var(--xpl-background-accent-highlight)` |


Light and dark mode follow Apollo Foundation purpose-specific tokens; the component does not use `.dark` overrides in its CSS.

## Content padding by viewport

The `padding` prop sets **content** padding via `var(--xpl-space-*)` on `.xpl-panel__content`. Two `max-width` media queries step values down on smaller viewports (`panel.css`).

### Matrix: `padding` × viewport


| Viewport   | Approx. width       | `padding="default"`          | `padding="tight"`            | `padding="loose"`            |
| ---------- | ------------------- | ---------------------------- | ---------------------------- | ---------------------------- |
| **Large**  | > 768px             | `var(--xpl-space-24)` · 24px | `var(--xpl-space-16)` · 16px | `var(--xpl-space-40)` · 40px |
| **Tablet** | ≤ 768px and > 480px | same as large                | same as large                | `var(--xpl-space-32)` · 32px |
| **Mobile** | ≤ 480px             | `var(--xpl-space-16)` · 16px | `var(--xpl-space-8)` · 8px   | `var(--xpl-space-24)` · 24px |


**How the breakpoints stack**

1. Base rules apply the **Large** row for all widths.
2. At `max-width: 768px`, only **loose** changes (tablet row for that column).
3. At `max-width: 480px`, **default**, **tight**, and **loose** all use the **Mobile** row.

Pixel values match the Foundation `space/`* scale; if tokens change in a future Foundation release, spacing updates without component code changes.

## Usage

### Web component

```html
<xpl-panel>
  <p>Any content goes here.</p>
</xpl-panel>
```

```html
<xpl-panel accent="primary">
  <p>Content with a primary accent bar.</p>
</xpl-panel>
```

Available accent values: `none` (default), `primary`, `secondary`, `positive`, `negative`, `highlight`.

### Padding density

```html
<xpl-panel padding="tight">
  <p>Tighter padding on small screens (see content padding matrix).</p>
</xpl-panel>
```

Use `padding="default"` | `"tight"` | `"loose"`. **default** and **tight** keep the same values from large screens through tablet; only at **≤480px** do they step down. **loose** steps down at **≤768px** (tablet) and again at **≤480px** (mobile).

### HTML/CSS (no Stencil)

Use the same BEM classes the component applies on the host. The accent bar must stay decorative (`aria-hidden="true"`).

```html
<div class="xpl-panel xpl-panel--accent-primary xpl-panel--padding-default">
  <div aria-hidden="true" class="xpl-panel__accent"></div>
  <div class="xpl-panel__content">
    <p>Panel body</p>
  </div>
</div>
```

Omit `xpl-panel--accent-*` when `accent` is `none`; do not render `.xpl-panel__accent`.

### Composing with other components

```html
<xpl-panel accent="secondary" padding="loose">
  <xpl-accordion header="Details">
    <div slot="content">Accordion inside a panel.</div>
  </xpl-accordion>
</xpl-panel>
```

### Content styling

The panel intentionally does **not** apply default typography or color styles to slotted content. It provides the surface (background, border, accent) and content padding — nothing more. This means text inside the panel inherits whatever styles the surrounding page defines.

To ensure consistent, theme-aware content you should use Apollo Foundation tokens on elements inside the slot:

```html
<xpl-panel>
  <h3 class="xpl-text-title-4" style="color: var(--xpl-text-strong)">Section title</h3>
  <p class="xpl-text-body" style="color: var(--xpl-text-default)">
    Body copy that adapts to light and dark mode automatically.
  </p>
  <p class="xpl-text-caption" style="color: var(--xpl-text-subdued)">
    Subdued helper text.
  </p>
</xpl-panel>
```

| Purpose | Recommended token |
| ------- | ----------------- |
| Primary text | `var(--xpl-text-default)` |
| Headings / emphasis | `var(--xpl-text-strong)` |
| Secondary / helper text | `var(--xpl-text-subdued)` |
| Disabled text | `var(--xpl-text-disabled)` |
| Links | `var(--xpl-text-link-default)` |

Using purpose-specific text tokens guarantees content switches correctly in dark mode. If slot content uses raw colors (e.g. `color: #333`) or relies on browser defaults, text will **not** adapt when the panel's ancestor has the `dark` class.

### Dark mode

Use an ancestor with the `dark` class — surface, border, and accent tokens update via Foundation.

## Design

- [Figma: xpl-panel](https://www.figma.com/design/MjjYek73MFnHmVNdm45Sd1/Apollo-Web?node-id=1546-136120&p=f)

<!-- Auto Generated Below -->


## Overview

A stateless container that defines a section on a page and can house any
type of content. Panels are not dismissible and may contain a top accent.

## Properties

| Property  | Attribute | Description                                                                                                                                                                                                                                                                            | Type                                                                            | Default     |
| --------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ----------- |
| `accent`  | `accent`  | Color accent bar displayed at the top of the panel.  - `none` – no accent (default) - `primary` – brand primary color - `secondary` – brand secondary color - `positive` – positive / success color - `negative` – negative / error color - `highlight` – highlight / warning color    | `"highlight" \| "negative" \| "none" \| "positive" \| "primary" \| "secondary"` | `'none'`    |
| `padding` | `padding` | Padding density applied to the content area. (default and tight keep desktop padding through tablet; mobile ≤480px).  - `default` – 24 px desktop & tablet / 16 px mobile - `tight`   – 16 px desktop & tablet / 8 px mobile - `loose`   – 40 px desktop / 32 px tablet / 24 px mobile | `"default" \| "loose" \| "tight"`                                               | `'default'` |


## Slots

| Slot | Description                                                                                                        |
| ---- | ------------------------------------------------------------------------------------------------------------------ |
|      | Default slot for panel content. Compose other Apollo components within the slot or build your own local component. |


----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*
