> ## Oymyakon DS index
> Fetch the full index at: https://super-dollop-pzmo65r.pages.github.io/llms.txt
> HTML preview: https://super-dollop-pzmo65r.pages.github.io/stack-container.html
> Source: specs/primitives/stack-container.md

---

# StackContainer · Oymyakon DS 3

> A horizontal stack whose items overlap by a fixed amount, the last item on top — or the first,
> on request. Any content; by default Mini squircles with portraits — an avatar stack.

**Version:** 3.0.2 · **Status:** Ready
**Figma:** the `Avatars` set (`35998:4086`, key `81d2239c…`, `Number = 3 | 2 | 1`, default 3) — a
building block on the `[Notch] 3.0` page of the main components file (merged from the Notch branch
`WiWGOeTcDPnBYRPnMnAG73`, node-ids unchanged); no page or Specification frame of its own

---

## 1. Description

StackContainer lays its items in one row and pulls each next item back over the previous one, so a
group reads as a single compact cluster — the drivers viewing your order, the people sharing a
trip. The container owns only the row, the overlap and the paint order; what it holds keeps its
own contract.

The Figma staging is the `Avatars` set (owner, 2026-10-09): an auto-layout row with a negative
item spacing (−8) and canvas stacking **last on top**, holding `Mini-Avatar` instances from
`[Avatar] 3.4`. The DS ships it as a container, not as an avatar component: any content goes in,
and the default content is the Mini squircle (Img type, border on) — the Squircle Mini geometry is
the Mini-Avatar's own (24, radius 8, 1dp `Border/Default` inside).

| Slot | Role |
|---|---|
| **Items** | One or more hosted components, laid out in a row; each after the first overlaps the previous one |

---

## 2. Anatomy

```
StackContainer        .stack-container — hug row, no fill, no padding
├── Item 1            any component — the bottom of the stack (last on top)
├── Item 2            overlaps Item 1 by --stack-container-overlap
└── Item 3            overlaps Item 2 — the top of the stack (first on top flips it)
```

| Element | Required | Description |
|---|---|---|
| **Container** | Required | Hugs its items; `s0` paddings, no fill, no radius |
| **Items** | One or more | Direct children. Each item after the first is pulled back by the overlap; the items keep their own size, colours and states |

---

## 3. Properties

| Property | Values | Default | Web mechanism |
|---|---|---|---|
| **Overlap** | any SP token | `var(--sp-s8)` | `--stack-container-overlap` on the instance — the Figma item spacing −8, expressed as a positive overlap |
| **Paint order** | `last on top` · `first on top` | `last on top` | Figma's auto-layout **Canvas stacking**. Last on top = the DOM order, a later item paints over the earlier one; first on top = `.stack-container--first-on-top` — the stack isolates and the z-order runs from the end, the row order unchanged |
| **Items** | any number | 3 (the Figma `Number` default; the set stages 1 · 2 · 3) | The children; the container sets no cap — `first on top` orders up to 10 items (its z-index ladder), far past where a stack still reads |

**Default content** — the Mini squircle with a portrait:

```html
<span class="squircle squircle--mini squircle--img squircle--border" data-ds-component="squircle"
      data-ds-preset="mini" data-ds-variant="img" data-ds-state="standard">
  <span class="squircle__slot"><img src="/illu/photo/avatar/ava-male-1.png" alt=""></span>
</span>
```

The 1dp `Border/Default` ring is what keeps overlapped portraits apart — the default content keeps
the Squircle border on. Any other component (an IconContainer, a Tag, a custom tile) may stand in
its place.

---

## 4. States

StackContainer has no states of its own. Standard is its only form; the items' states stay theirs.

---

## 5. RTL

The row follows the reading direction: under `dir="rtl"` the first item sits at the right edge and
each next item tucks over it towards the left. The paint order holds — last or first on top. The overlap is a
logical (`inline-start`) margin, so the mirror needs no extra class.

---

## 6. Animation

None. The container never animates; its items keep their own motion.

---

## 7. CSS implementation

```css
.stack-container {
  --stack-container-overlap: var(--sp-s8);
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}
.stack-container > * + * { margin-inline-start: calc(-1 * var(--stack-container-overlap)); }
```

CSS `gap` cannot be negative, so the overlap is a negative logical margin on every item after the
first; the items stay in normal flow, so the later sibling paints on top without a `z-index`.

```css
/* First on top — Figma's Canvas stacking = First on top */
.stack-container--first-on-top { isolation: isolate; }
.stack-container--first-on-top > * { position: relative; }
.stack-container--first-on-top > :nth-last-child(1) { z-index: 1; }
.stack-container--first-on-top > :nth-last-child(2) { z-index: 2; }  /* … to 10 */
```

---

## 8. Usage context

**Use it** for a small group whose members matter as a cluster, not one by one: the avatar stack in
the [Notch](https://super-dollop-pzmo65r.pages.github.io/notch.md) EndSlot, the people sharing a ride.

**Do not use it for:**

- Items that need their own tap targets — overlapped items have no room for one each; the stack
  is one visual unit.
- Long lists — past three or four items the cluster stops reading; say the count in text instead.
- Mixed sizes — the overlap is one value, so items of different sizes tuck unevenly.

Related: [Squircle](https://super-dollop-pzmo65r.pages.github.io/squircle.md) (the default content),
[DecorateContainer](https://super-dollop-pzmo65r.pages.github.io/decorate-container.md) (floats a decoration over one component — a different
job), [Notch](https://super-dollop-pzmo65r.pages.github.io/notch.md) (the first consumer).

---

## 9. Rules

1. The container never alters its items — no colour, size or state bleed.
2. One overlap value for the whole stack; equal-sized items.
3. Last on top by default — the paint order is the DOM order; first on top reverses only the
   paint order, never the row.
4. The default content keeps the Squircle border on — it separates the overlapped portraits.

---

## 10. Accessibility

The stack is decorative by default: the container is `aria-hidden="true"` on the web and hidden
from VoiceOver / TalkBack in the apps, and the portraits carry empty alternatives. Whatever the
cluster means is said by the host's text ("3 drivers are viewing your order") — a screen reader
never hears "image, image, image". A stack whose members must be identified individually is not a
stack: list them.

---

## 11. Analytics and coverage contract

Not a coverage unit. The container is structural: no `data-ds-component`, no targets, no actions.
The items keep their own contracts (a Squircle keeps `data-ds-component="squircle"`). See
`docs/prototype-analytics-and-coverage.md` for the structural-node policy.

---

## Changelog

| Version | Date | Change |
|---|---|---|
| 3.0.2 | 2026-11-12 | Status Draft → Ready (owner, 2026-11-12) — the backlog sweep: merged on main, web build shipped, no owner decision open. No contract change; Figma-side flags recorded above stay open on the Figma side. |
| 3.0.1 | 2026-10-19 | The Notch branch merged into the main components file: the header points at the main file — the `Avatars` set keeps its node-id `35998:4086`, its key is now `81d2239c…`. No contract change. |
| 3.0.0 | 2026-10-09 | First repo spec (owner, 2026-10-09), from the Figma `Avatars` set (`35998:4086`) on the `[Notch] 3.0` branch page: a row with item spacing −8 (expressed as the `--stack-container-overlap` re-point, default `var(--sp-s8)`), canvas stacking last on top (the auto-layout **Canvas stacking** setting; first on top is the other value — the web ships both: the default and `.stack-container--first-on-top`, owner 2026-10-09), `Number` 1–3 (default 3) of `Mini-Avatar` instances from `[Avatar] 3.4`. Shipped as a generic container: any content; the default content is the Squircle Mini (Img, border on) — the same 24 / radius 8 / 1dp `Border/Default` geometry. RTL follows the reading direction (logical margin). Decorative to assistive tech; not a coverage unit. First consumer: Notch 3.0.0. |
