diff --git a/.specs/pick-list.md b/.specs/pick-list.md
new file mode 100644
index 00000000..4adc5291
--- /dev/null
+++ b/.specs/pick-list.md
@@ -0,0 +1,149 @@
+---
+name: pick-list
+category: data
+structure: monolithic
+status: approved
+spec_version: 1
+checksum: 99e777f34e83355b73625e5cecba7c8ac182a1b3e972993e812cf3052a906117
+created: 2026-06-25
+last_updated: 2026-06-25
+---
+
+# Pick List — Component Spec
+
+## Purpose
+
+Dual-list transfer control: a labelled **source** listbox and a labelled **target** listbox with controls to move items between them and (optionally) reorder items within a list. Use it when the consumer needs to build an ordered subset from a pool of options where both the chosen set and the remaining pool stay visible. Derived from the PrimeVue PickList behavior but rewritten to our conventions (no Figma); the visual surface is a best-effort first draft to validate.
+
+## Usage
+
+```vue
+
+
+
+
+ {{ item.label }}
+
+
+```
+
+## Props
+
+| Prop | Type | Default | Required | JSDoc |
+|---|---|---|---|---|
+| `modelValue` | `[unknown[], unknown[]]` | `() => [[], []]` | no | Bound pair of lists as `[sourceItems, targetItems]` (v-model). |
+| `dataKey` | `string` | `''` | no | Item field that uniquely identifies a record; enables selection tracking and stable keys. |
+| `sourceHeader` | `string` | `''` | no | Heading text for the source list; also its accessible name. |
+| `targetHeader` | `string` | `''` | no | Heading text for the target list; also its accessible name. |
+| `disabled` | `boolean` | `false` | no | Disables all selection and move controls and applies disabled tokens. |
+| `reorderable` | `boolean` | `false` | no | Shows up/down reorder controls that move selected items within their own list. |
+
+## Events
+
+| Event | Payload | Notes |
+|---|---|---|
+| `update:modelValue` | `[unknown[], unknown[]]` | v-model update with the new `[sourceItems, targetItems]` pair. |
+| `move` | `{ direction: 'to-target' \| 'to-source'; items: unknown[] }` | Fired after items move between lists, with the moved items. |
+| `reorder` | `{ list: 'source' \| 'target'; items: unknown[] }` | Fired after a reorder, with the items in the affected list. |
+
+## Slots
+
+| Slot | Scope | Notes |
+|---|---|---|
+| `item` | `{ item: unknown; index: number; list: 'source' \| 'target' }` | Renders a single row; receives the item, its index, and which list it belongs to. |
+| `sourceHeader` | `—` | Overrides the source heading content. |
+| `targetHeader` | `—` | Overrides the target heading content. |
+
+## States
+
+- Visual states: `default`, `hover` (option), `focus-visible` (option / control), `selected` (option), `disabled`
+- `data-disabled` mirrors the `disabled` prop
+- `data-reorderable` mirrors the `reorderable` prop
+- Each option carries `data-selected` mirroring its selection and `aria-selected`
+
+## Motion & Animations
+
+_none_
+
+## Tokens
+
+| Region | Token (DESIGN.md) |
+|---|---|
+| typography (header) | `.text-label-lg` |
+| typography (option) | `.text-body-md` |
+| surface (list) | `var(--bg-surface)` |
+| surface (option hover) | `var(--bg-hover)` |
+| surface (option selected) | `var(--bg-selected)` |
+| text | `var(--text-default)` |
+| text (header) | `var(--text-muted)` |
+| text (disabled) | `var(--text-disabled)` |
+| surface (disabled) | `var(--bg-disabled)` |
+| border | `var(--border-default)` |
+| ring | `var(--ring-color)` |
+| spacing (list padding) | `var(--spacing-xs)` |
+| spacing (option padding) | `var(--spacing-sm)` |
+| gap (lists + controls) | `var(--spacing-sm)` |
+| shape (list) | `var(--shape-card)` |
+| shape (option) | `var(--shape-elements)` |
+
+## Theme gaps
+
+| Figma variable | Temporary primitive | Follow-up |
+|---|---|---|
+| _none_ | — | — |
+
+## Accessibility (WCAG 2.1 AA)
+
+- Visible focus: `focus-visible:ring-2 focus-visible:ring-[var(--ring-color)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-canvas)]` on each option and on every move/reorder control.
+- Keyboard map: `Tab` moves between the two listboxes and the control column; within a listbox `ArrowUp`/`ArrowDown` move the active option, `Space`/`Enter` toggle its selection; move and reorder controls are activated with `Enter`/`Space`.
+- ARIA: each list is `role="listbox"` with `aria-label` from its header text; options are `role="option"` with `aria-selected`; the source/target listboxes set `aria-multiselectable="true"`; every move/reorder control is an icon-only button with an explicit `aria-label`; `aria-disabled` mirrors `disabled`.
+- Contrast ≥4.5:1 (text) / ≥3:1 (borders + icons), including the disabled state.
+- No motion in this component, so no `motion-reduce:*` is required.
+- Touch target ≥40×40 px for every move/reorder control (medium icon-button height).
+
+## Stories (Storybook)
+
+- Default
+- Disabled
+- WithReorder — justified: the `reorderable` prop adds an extra control column (up/down) that is hidden by default; the story documents the reorder controls and within-list ordering behavior in isolation.
+
+## Constraints — DO NOT
+
+
+
+- Do not add props beyond the Props table above. If you need a prop that is not listed, emit `BLOCKED: missing prop ` and stop — do not invent.
+- Do not add events beyond the Events table above. Same rule for slots and sub-components.
+- Do not invent imports. Every `@aziontech/webkit/*` path must exist in `packages/webkit/package.json#exports`. Every relative import must resolve to a real file. Every npm package must be installed.
+- Do not use HEX/RGB/HSL colors, Tailwind palette names (e.g. `bg-blue-500`), raw typography classes (e.g. `text-sm`), `any`, `@ts-ignore`, or `class` inside `defineProps`.
+- Do not install or import positioning/animation libraries (`@floating-ui/*`, `popper.js`, `tippy.js`, `gsap`, `framer-motion`, `motion`, `@vueuse/motion`, `@formkit/auto-animate`, drag-drop runtimes, scroll virtualization libs). Use CSS + Vue primitives (``, ``). See `.claude/rules/dependencies.md`.
+- Do not improvise animations. Every `animate-*` / `transition-*` class must come from `packages/theme/src/tokens/semantic/animations.js`; every motion-bearing class pairs with `motion-reduce:*` on the same class string; no component-local `@keyframes`.
+- Do not create class presets in JavaScript (`const kindClasses = {...}`, `const sharedClasses = [...]`, `const sizeClasses = {...}`, `const rootClasses = computed(...)`). Variants live on `data-*` attributes consumed by Tailwind `data-[attr=value]:`. All utilities live inline on the root element's `class` attribute. No `