# BPL DS — Agent Instructions
> Machine-readable contract for AI agents implementing UI with Be Partner DS v1.4.6.
> Canonical URL: https://ds.bepartnerlabs.com/AGENTS.md
> Full registry: https://ds.bepartnerlabs.com/registry/components.json

---

## Architecture

### CSS Layers (in cascade order)

`@layer bp-tokens, bp-reset, bp-grid, bp-components, bp-utilities;`

Tokens always lose to components. Utilities always win.

### Token Contract

Reference: https://www.giorgiosaud.io/notebook/custom-properties-with-defaults

Every component uses a 4-level variable chain:

```
Level 0  --figma-blue-500        Figma/Style Dictionary output. Never used directly in CSS.
Level 1  --bp-primary            DS base tokens on :root. Client remaps these to Figma values.
Level 2  --btn-background        Component public slot. Named after the CSS property it controls.
Level 3  --_background           Private resolver. Never override from outside.
```

```css
/* Inside the DS source */
.bp-btn {
  --_background: var(--btn-background, var(--bp-primary));
  background-color: var(--_background);
}
```

#### 5 Rules

**Rule 1 — Token names match the CSS property.**
`--btn-background` controls `background-color`. `--btn-border-radius` controls `border-radius`. Never use abbreviations (`--btn-bg` ❌).

**Rule 2 — No state tokens.**
`--btn-background-hover` is banned. Override hover by re-declaring the same Level 2 token in a state selector:
```css
.my-cta { --btn-background: var(--bp-cta); }
.my-cta:hover { --btn-background: var(--bp-cta-hover); }
```

**Rule 3 — Private vars use `--_` prefix.**
Short property-named suffixes: `--_background`, `--_color`, `--_border`, `--_radius`, `--_padding`. Private vars live only on the component root selector.

**Rule 4 — Component tokens never go on `:root`.**
Global brand theming flows through Level 1 (`--bp-*`) only. Component tokens (`--btn-*`) are for per-instance exceptions on scoped selectors.

**Rule 5 — Child element tokens only when documented.**
Child styling is private (`--_*`) by default. Expose a Level 2 token for a child element only when there is a consumer need: `--<component>-<element>-<property>` (e.g. `--card-link-color`).

#### Global Theming Pattern

Client maps Figma tokens → `--bp-*` at `:root`. Every component inherits the brand automatically:

```css
/* Client :root — only touch Level 1 */
:root {
  --bp-primary:    var(--figma-blue-500);
  --bp-primary-fg: var(--figma-white);
}

/* Per-instance exception — scoped Level 2 */
.hero__cta { --btn-background: var(--bp-color-accent); }
```

### Responsive: Container Queries

Every component root has `container-type: inline-size`. Use `@container` for breakpoints, not `@media`. Exception: full-viewport layouts (hero, header, footer) use `@media`.

### State: ARIA + Native Pseudo-classes

CSS reads DOM state. JS writes it. Never toggle style classes.

```css
/* ✅ CSS reads the DOM */
.bp-tabs__tab[aria-selected="true"] { color: var(--_accent); }
.bp-modal[open] { opacity: 1; }

/* ❌ Never */
.bp-tabs__tab.is-active { color: var(--_accent); }
```

---

## Grid System

**Root class:** `.bp-content-grid`

Named-line CSS grid layout. Root class: .bp-content-grid. Zone classes go on DIRECT CHILDREN of the grid, not on the grid root itself.

**Zones — add the class on the DIRECT CHILD, not on the grid root:**

- `content` — no class (default), width ~72rem. Default. No class needed. All direct children land here.
- `popout` — class `.popout`, width ~60rem. Add class .popout on the child. For quotes, CTAs, mid-size media.
- `breakout` — class `.breakout`, width ~90rem. Add class .breakout on the child. For grids, covers, video.
- `full-width` — class `.full-width`, width 100vw. Add class .full-width on the child. Sub-content still inherits grid columns.

**Public API tokens** (set on `.bp-content-grid` or a parent):
- `--padding-inline` — Horizontal gutter. Default: clamp(1.25rem, 1vw + 1rem, 2rem) (default: `clamp(1.25rem, 1vw + 1rem, 2rem`)
- `--content-max-width` — Max width of the content zone. Default: 72rem (1152px) (default: `72rem`)
- `--popout-max-width` — Max width of the popout zone.  Default: 60rem (960px) (default: `60rem`)
- `--breakout-max-width` — Max width of the breakout zone. Default: 90rem (1440px) (default: `90rem`)

**Canonical HTML:**
```html
<div class="bp-content-grid">
  <p>Default content zone — no class needed</p>
  <blockquote class="popout">Popout zone</blockquote>
  <figure class="breakout">Breakout zone</figure>
  <div class="full-width">Full-width zone</div>
</div>
```

---

## Theming: Prefix Override

Client implementations can replace the `--bp-` prefix with their own brand prefix on base tokens. This allows full white-labeling without touching any component CSS.

**What you can replace:**

| Scope | How |
|-------|-----|
| Base tokens on `:root` | Redefine `--bp-*` as `--<client>-*` in your own `:root` block, then map them back |
| Grid layout tokens | Override directly — grid tokens (`--padding-inline`, `--content-max-width`, etc.) have no prefix, they're already your surface |

**What you must NOT replace:**

| Scope | Why |
|-------|-----|
| Component public tokens (`--btn-*`, etc.) | These resolve via the 3-level chain; override them per-component, not globally |
| Private vars (`--_*`) | Internal — undefined behavior if overridden |

**Pattern — full prefix override:**

```css
/* Client maps their tokens to the bp- surface */
:root {
  --bp-primary:    var(--acme-brand-500);
  --bp-primary-fg: var(--acme-white);
  --bp-color-bg:   var(--acme-neutral-100);
  /* ... map every --bp-* you use */
}
```

Every component picks up the new values automatically through the 3-level chain — no component CSS changes needed.

---

## Rules

- Copy component HTML from `https://ds.bepartnerlabs.com/components/<name>/` verbatim
- Customize via `--<component>-*` properties on a CSS class. Never use `style=""`
- Never modify DS source CSS
- Use correct semantic elements: `<button>` for actions, `<a>` for navigation, `<dialog>` for modals

---

## Canonical Components

These three components demonstrate the full pattern set. An agent that understands these can construct any other component correctly.

### Accordion (`.bp-accordion`)
Native details/summary accordion — zero JavaScript required.
  - `--accordion-bg` — Background color (default: `transparent`)
  - `--accordion-radius` — Border radius (default: `0px`)
  - `--accordion-border` — Item border (default: `1px solid var(--bp-color-border`)
  - `--accordion-accent` — Left border color when open (default: `var(--bp-primary`)

**Base pattern:**
```html
<!-- Group A -->
<details class="bp-accordion__item" name="pricing-faq">…</details>
<details class="bp-accordion__item" name="pricing-faq">…</details>

<!-- Group B — independent -->
<details class="bp-accordion__item" name="support-faq">…</details>
<details class="bp-accordion__item" name="support-faq">…</details>
<!-- variants and states → https://ds.bepartnerlabs.com/components/accordion/ -->
```

---

### Button (`.bp-button`)
Interactive trigger element for actions and navigation.
  - `--btn-background` — Button background color (default: `var(--bp-primary`)
  - `--btn-color` — Button text color (default: `var(--bp-primary-fg`)
  - `--btn-border-radius` — Border radius (default: `var(--bp-radius-md`)
  - `--btn-padding` — Padding shorthand (default: `var(--bp-space-3`)
  - `--btn-border` — Border (default: none) (default: `none`)

**Base pattern:**
```html
<button class="bp-btn" type="button">Label</button>
<!-- variants and states → https://ds.bepartnerlabs.com/components/button/ -->
```

---

### Dropdown Menu (`.bp-dropdown`)
Accessible menu anchored to a trigger — CSS for appearance, a small Web Component for keyboard navigation and focus management.

**Base pattern:**
```html
<bp-dropdown class="bp-dropdown">
  <button class="bp-btn bp-dropdown__trigger">Options ▾</button>
  <ul class="bp-dropdown__panel" role="menu">
    <li><button class="bp-dropdown__item" role="menuitem">Edit</button></li>
    <li><button class="bp-dropdown__item" role="menuitem">Delete</button></li>
  </ul>
</bp-dropdown>
<!-- variants and states → https://ds.bepartnerlabs.com/components/dropdown/ -->
```

---

## Components

Reference-only. Use token count to judge whether a component is worth fetching before using it.

### Alert (`.bp-alert`) — [docs](https://ds.bepartnerlabs.com/components/alert/)
Inline feedback message for persistent contextual notices — four semantic variants, optional dismiss, and left-accent stripe.. 12 public tokens.

### Avatar (`.bp-avatar`) — [docs](https://ds.bepartnerlabs.com/components/avatar/)
Circular user image using a native img element — with CSS-only initials fallback, size variants, and composable avatar groups.. 11 public tokens.

### Badge (`.bp-badge`) — [docs](https://ds.bepartnerlabs.com/components/badge/)
Inline label for status, counts, and categories — semantic color variants with solid, subtle, and outline styles.. 4 public tokens.

### Breadcrumb (`.bp-breadcrumb`) — [docs](https://ds.bepartnerlabs.com/components/breadcrumb/)
Navigation trail showing the user's location in a hierarchy — semantic `<nav>` + `<ol>` with CSS-only separators.. 0 public tokens.

### Card (`.bp-card`) — [docs](https://ds.bepartnerlabs.com/components/card/)
Flexible content container with image, body, and footer slots.. 5 public tokens.

### Carousel (`.bp-carousel`) — [docs](https://ds.bepartnerlabs.com/components/carousel/)
CSS scroll-snap carousel — no JavaScript required for basic scrolling.. 4 public tokens.

### Checkbox (`.bp-checkbox`) — [docs](https://ds.bepartnerlabs.com/components/checkbox/)
Styled native checkbox with label wrapping, indeterminate support, error state, and group layout — built on the native `<input type="checkbox">` element.. 11 public tokens.

### Date Picker (`.bp-datepicker`) — [docs](https://ds.bepartnerlabs.com/components/datepicker/)
Styled native `<input type="date">` — browser calendar popup, zero JavaScript, full keyboard and screen reader support out of the box.. 0 public tokens.

### Footer (`.bp-footer`) — [docs](https://ds.bepartnerlabs.com/components/footer/)
Site footer with a responsive column grid, brand slot, and link groups.. 3 public tokens.

### Header (`.bp-header`) — [docs](https://ds.bepartnerlabs.com/components/header/)
Sticky site header with glassmorphism and scroll-state shadow.. 4 public tokens.

### Hero (`.bp-hero`) — [docs](https://ds.bepartnerlabs.com/components/hero/)
Page hero section with CSS-only entrance animation via @starting-style.. 3 public tokens.

### Input (`.bp-input`) — [docs](https://ds.bepartnerlabs.com/components/input/)
Text inputs, textarea, and select — with label, hint, and error states.. 5 public tokens.

### Modal (`.bp-modal`) — [docs](https://ds.bepartnerlabs.com/components/modal/)
Native dialog element modal with CSS-only entrance animation and a blurred backdrop.. 4 public tokens.

### Nav (`.bp-nav`) — [docs](https://ds.bepartnerlabs.com/components/nav/)
Horizontal navigation with simple links, dropdowns, and a megamenu panel.. 2 public tokens.

### Pagination (`.bp-pagination`) — [docs](https://ds.bepartnerlabs.com/components/pagination/)
Page navigation controls built with `<nav>` + `<ol>` — active state via `aria-current`, disabled via `aria-disabled`. No JavaScript required.. 0 public tokens.

### Popover (`.bp-popover`) — [docs](https://ds.bepartnerlabs.com/components/popover/)
Floating panel anchored to a trigger — built on the native Popover API. No JavaScript required for show/hide.. 0 public tokens.

### Radio (`.bp-radio`) — [docs](https://ds.bepartnerlabs.com/components/radio/)
Single-select control for mutually exclusive options — uses native `<input type="radio">` inside a wrapping `<label>`.. 10 public tokens.

### Skeleton / Spinner (`.bp-skeleton`) — [docs](https://ds.bepartnerlabs.com/components/skeleton/)
Loading state placeholders — `.bp-skeleton` for content shapes with shimmer animation, `.bp-spinner` for indeterminate progress. Both respect `prefers-reduced-motion`.. 0 public tokens.

### Table (`.bp-table`) — [docs](https://ds.bepartnerlabs.com/components/table/)
Data table with sortable columns — CSS for appearance, a small Web Component for client-side sort. Scrollable on small viewports.. 0 public tokens.

### Tabs (`.bp-tabs`) — [docs](https://ds.bepartnerlabs.com/components/tabs/)
Accessible tabs component — CSS-driven visuals, minimal JS for state and keyboard navigation.. 3 public tokens.

### theme (`.bp-theme`) — [docs](https://ds.bepartnerlabs.com/components/theme/)
. 0 public tokens.

### Toast (`.bp-toast`) — [docs](https://ds.bepartnerlabs.com/components/toast/)
Transient feedback notifications — semantic variants, auto-dismiss, optional action, WCAG AA.. 5 public tokens.

### Toggle (`.bp-toggle`) — [docs](https://ds.bepartnerlabs.com/components/toggle/)
On/off switch for boolean settings — a styled checkbox with role="switch" using native HTML and CSS only.. 12 public tokens.

### Tooltip (`.bp-tooltip`) — [docs](https://ds.bepartnerlabs.com/components/tooltip/)
Contextual label that appears on hover and focus — CSS-only, four placement variants, RTL-aware. No JavaScript required.. 0 public tokens.
