U0 · the one shell · SISO CRM GroupedRail, copied

The rail on the left is the deliverable

The SISO CRM GroupedRail (product-app GroupedRail.tsx + GroupedRail.css + tokens.css) as plain HTML, CSS and JS. Sizes, fonts, spacing, gradients, shadows and transitions are the CRM's values through the CRM's token names. Press [ to collapse it to icons with tooltips, ⌘K to search; click a group heading and nothing disappears.

tokens.css verbatimGroupedRail.css verbatim + 1 additive sectionlucide icons · ISC232 → 52 px
01

Why one shell

his words · the reading
  1. His words 1

    verbatim, from 00_AGENT_ZERO/source/ — never paraphrased

    look at the size of crm one it's just so much nicer okay look at the size of crm and you'll understand that's the exact side map that i want like sizing fonts everything spacing the way it all fits together. And I click on certain shit and it disappears now. Templated page on the side now doesn't fully wire up.Shaan · 6 Sep 18:41
  2. Reading authored by the seat

    His 13:09 to LIBRARY-ZERO: 'you're not using our size of crm side nav, which is Specifically what I told you to do'; 16:50: 'not all of them have side nav so they're connected'; 18:19: 'the side nav is a bit shit'. One shell is what makes 60+ pages across 10 repos and 6 pages.dev sites feel like one place.

    Readers. Human: orient, jump between families, collapse it and read. Agent: the rail's link data is the site map; Cmd-K search is the same map as text.

    1. Where am I in the ecosystem?
    2. What are the sibling pages?
    3. Which section of this page do I want?
  3. What this page may claim

    Claim ceilingMay assert only what the link data says exists; every destination must return 200 or be marked private.
    Data it rendersA link JSON per site (groups → destinations → status chip); built at publish; the rail reads it, never hand-edited HTML.
    PrivacyPublic; private destinations show a lock chip, never a payload.
    Empty stateNo JS: the page still reads; the rail is absent, nav.top remains.
    Agent entrysiso-shell/shell.mjs rail({title, groups, page, current}) · shell/rail.js · shell/rail.css · shell/tokens.css
02

Every value, and where the CRM sets it

if a number was chosen here it is wrong; these are read from tokens.css
ThingCRM tokenValueWhere the CRM sets it
Expanded width--crm-rail-width232pxtokens.css · Component sizing
Collapsed width--crm-rail-collapsed-width52pxtokens.css
Screen inset (top/left/bottom)--crm-rail-screen-inset16px (space-4)GroupedRail.css .siso-sidebar
Rail padding--crm-rail-padding16pxtokens.css
Rail gap--crm-rail-gap10pxtokens.css
Rail radius / inner--crm-radius-rail / -inner27px / 26pxtokens.css · Radius roles
Shell background--crm-gradient-rail-shell2 radial + 1 linear, rail-top/mid/bottom rgbtokens.css · Effects
Shell border--crm-gradient-rail-borderconic-gradient 0→360°tokens.css
Glass--crm-blur-glassblur(32px) saturate(124%)GroupedRail.css
Shell shadow--crm-shadow-rail-shell7 layerstokens.css
Header grid.siso-sidebar__header40px 1fr 36px · min-height 48px · gap 6pxGroupedRail.css
Brand tile.siso-sidebar__brand40×40 · radius 12px · rail-brand-tile gradientGroupedRail.css
Product name--crm-text-sm12px · weight 660 · -0.01em · lh 1.08GroupedRail.css
Toggle.siso-sidebar__toggle36×36 · radius 11px · svg 17pxGroupedRail.css
Search row--crm-control-touch / --crm-radius-control-lg44px high · radius 13px · gap 10px · pad 0 12pxGroupedRail.css
Search label--crm-text-sm12px · -0.005emGroupedRail.css
Search kbd--crm-text-2xs9px mono · 31×24 · radius 7pxGroupedRail.css
Group heading--crm-text-2xs / --crm-tracking-label9px · weight 650 · 0.17em · uppercase · 17px high · white/0.47GroupedRail.css .siso-sidebar__group-heading
Group gap--crm-nav-section-gap16pxtokens.css
Heading inset--crm-nav-button-gutter + --crm-nav-inline-inset4px + 12pxtokens.css
Nav row--crm-nav-row-height44px (control-touch)tokens.css
Nav label--crm-text-md13.5px · weight 510 · white/0.7GroupedRail.css .siso-sidebar__nav-link
Nav icon--crm-icon-md / --crm-icon-stroke17px · stroke 1.7 · white/0.56GroupedRail.css
Icon–label gap--crm-nav-icon-label-gap12pxtokens.css
Row gap--crm-space-0-52pxGroupedRail.css .siso-sidebar__nav-items
Row radius--crm-radius-control11pxtokens.css
Active row--crm-gradient-rail-active / --crm-shadow-activebrand-hover text · radial+linear brand/0.13 · 4-layer shadowGroupedRail.css .is-active
Hover rowrgb(white/0.035)text → crm-color-textGroupedRail.css
Compact strip.siso-sidebar__compact-navigation44px wide · radius 13px · capsule gradient · gap 2pxGroupedRail.css
Compact link.siso-sidebar__compact-link44×44 · radius 11px · active-icon gradientGroupedRail.css
Collapsed shell.siso-sidebar.is-collapsedwidth 52px · pad 4px · gap 8px · radius 20px · brand/toggle/search 42pxGroupedRail.css
Transitionswidth 200ms ease · colour/background 160ms easeGroupedRail.css
Font--crm-font-sans'Geist', ui-sans-serif, system-ui, -apple-system, …tokens.css · Typography
Workspace offsetapp.css .crm-workspacemargin-left = inset×2 + rail widthSISOCRM src/styles/app.css:17-18
Preference keyApp.tsx RAIL_STORAGE_KEY'siso.crm.rail.collapsed'SISOCRM src/App.tsx:14

Rule: every pixel, font-size, letter-spacing, gap, radius, gradient and transition in shell/rail.css is the CRM's value, resolved through the same token names. Section 1 of that file is GroupedRail.css unchanged; section 2 adds only what a static page needs, from the same tokens.

03

Behaviour, from GroupedRail.tsx and App.tsx

Expanded

Grouped labels: a heading per group (<h2>), the destinations under it with icon + label. Headings are headings; a click does nothing and nothing disappears.

GroupedRail.tsx LabeledNavigation

Compact

The same destinations as 44px icon links with title tooltips, in the capsule strip. Collapsing never changes what the navigation means.

GroupedRail.tsx CompactNavigation

Toggle

The 36px header button (PanelLeftClose / PanelLeftOpen) flips is-collapsed on the rail and rail-collapsed on body; the workspace margin follows.

GroupedRail.tsx · App.tsx useRailState

[ toggles

Outside editable fields, [ collapses/expands.

Library adaptation (briefs/LIBRARY-UI-FABLE.md)

Cmd/Ctrl-K

Focuses the search row (expanding the rail if needed). Typing filters destinations by label; Esc clears; Enter opens the first match.

App.tsx onSearchShortcut · SidebarSearch

Preference

Collapsed state persists in localStorage["siso.crm.rail.collapsed"], the CRM's key. Below 980px it starts collapsed.

App.tsx:14,44-56 · app.css:101

On this page

The one folding group: a <details> (Action Model lanebox) listing the page's sections, built by bin/compose from <section class="siso-section" id>; the current section is marked as you scroll.

blueprint/index.html:185-190 · compose.mjs sectionsOf

No JavaScript

The rail renders expanded with every group; toggle and search are inert. Navigation never depends on JS.

shell/rail.css .no-js

04

The two bugs this port does not repeat

v1/v2 atlas ports, superseded
fact · has a receiptproposal · not yet
v1 bug: a display rule beat [hidden], so the search trigger and the search box rendered at once. Fixed here: .siso-sidebar [hidden] { display: none !important } in section 2 of rail.css, and one search row (a real input) instead of two.OWNERS.md 2026-09-06T17:13 · atlas/crm-rail.css:10,83
v2 bug: groups were <details>, so clicking a heading collapsed the group. Fixed here: groups are <section> + <h2> like the CRM; only "On this page" folds.his 18:41 'I click on certain shit and it disappears now' · atlas/crm-rail.js:103-116
Section 1 of shell/rail.css is byte-for-byte GroupedRail.css.sha256 87c0c20e…62f5b · shell/rail.css header
shell/tokens.css is byte-for-byte the CRM tokens.css.sha256 1fb51616…5115b9
Compare against the built CRM at the same viewport (dist CSS values match the token values listed above).CRM dist served read-only on 127.0.0.1:7677 (laptop only)
Limits
  • The CRM brand tile and profile orb show an <img>; the static shell shows letters in the same tile.
  • The CRM search button dispatches a global palette; here the row is the search input itself.
05

Use it on your page

shell.mjs
  1. import { rail, head } from "siso-shell/shell.mjs";
  2. const html = `<!doctype html><html class="no-js"><head>${head("https://siso-shell.pages.dev/shell")}</head>
  3. <body class="rail-expanded">${rail({ title: "My site", groups, current: "/x/", page: [{label:"Why", href:"#why"}] })}
  4. <div class="siso-shell-page">…</div></body></html>`;
  5. // or, without node: copy shell/ next to your HTML and paste the <nav> from any published page
Agent entry
Read first
shell.mjs
Owner
TEMPLATE-BANK-ZERO
Machine
https://siso-shell.pages.dev/nav.json
Done when
Open your page: the rail at the left has the CRM's sizes; [ collapses to icons with tooltips; ⌘K focuses search; "On this page" lists your sections.
06

Sources

SISO_Agency/apps/SISOCRM/product-app
no public locator
private
main branch
The source of truth: src/components/GroupedRail.tsx (306 lines), src/styles/GroupedRail.css (677), src/styles/tokens.css (303), src/App.tsx (rail state, ⌘K), src/styles/app.css (workspace offset). Presentation robbed; no client routes, auth or data.
read-onlySISO
No public payload
sisodias/siso-shell
https://github.com/sisodias/siso-shell
public
main branch
This bank: shell/ (tokens, rail.css, rail.js, icons), shell.mjs, parts/, templates/, bin/compose.
SISO · lucide ISC
Open repo
sisodias/siso-agent-zero-protocol
https://github.com/sisodias/siso-agent-zero-protocol
public
main branch
The plan: plan/templates.json, the 24 template issues, atlas/crm-rail.{css,js} (v1/v2 ports, superseded), receipts.
satelliteSISO
Open repo