# Side rails - agent guide

> Normative extract of the EchoSistema template for the page
> `/componentes/sidebars`. Copy it verbatim: tag names, props, events and classes
> are contract.
>
> Full guide (rules, tokens and every family): `/agents/echosistema-ui.md`

## Rules that apply before any line of code

- Colour only through tokens (`text-fg1`, `bg-panel`, `border-line`, `.es-i--*`); never a hex, never a Tailwind colour.
- Two axes: the intent gives the colour, the variant consumes it. Never combine them by hand.
- Visible text through `t()`; tag names, props and classes stay literal.
- A component does not fetch: it takes props and emits events.
- An icon alone inside a button needs an `aria-label`.

Three lookalike rails that are not interchangeable.

```vue
<!-- "where can I go" -->
<sidebar-panel v-model:collapsed="collapsed" :groups="GROUPS" fixed />

<!-- "where am I": the active item follows the scroll -->
<sidebar-docs :groups="NAV" content-selector="#guide" initial="intro" />

<!-- "what do I want to see" -->
<sidebar-filters v-model="picked" :groups="FILTERS" :title="t('chrome.filters.label')" />
```

```ts
// app/data/chrome.ts
interface SidebarItem { label: string, to: string, icon?: Component, count?: number }
interface SidebarGroup { title?: string, items: readonly SidebarItem[] }
```

The icon comes in as a COMPONENT, not as a name: resolving a name against the
auto-import registry would pull every component of the site into the same chunk.

Collapsed, the counter becomes a dot positioned ABSOLUTELY over the icon. As a
sibling in the flex row it took width, and an item with a counter had its icon
pushed off the rail's centre while the ones without stayed put.

`sidebar-docs` observes `section[id]` inside `content-selector`; with no
selector it is still an index, it just stops saying where the reader is.

`sidebar-filters` returns `{ group: values[] }` - a map and not a flat list,
because two groups may offer the same value. An empty group leaves the object
(otherwise it would become `?colour=` in the URL).

---

Source: `app/components/sidebar/*.vue`
