RJ HQ · menu techniques

brand-006 RJ Laravel Admin · 4b·R shell · 2026-10-18 · mechanics only · sample items, grouping illustrative
phone board → earlier menu board (M1–M3) →
Not a decision board. Frank, 2026-10-18: the menu's content belongs to the server (AdminMenu.php). Regrouping it is a later exercise, led by evidence and done with backend. This board covers mechanics only: how a menu of any shape opens, nests and stays findable in the 4b·R shell. Every frame uses sample items. The labels come from the live menu so they feel real, but the grouping is illustrative, not a proposal.
Recommended defaults by depth
Every technique at a glance live demos are in the Depth 1 · 2 · 3 tabs; ⌘K, pins, CJK and permissions are under Cross-cutting
DepthTechniqueExpanded sidebar (232px)Collapsed (76px rail)PhoneGood forWeak atDefault?
1Flat labelled listplain list, icon + labellabelled rail, label under icondrawer listup to ~14 entries per loginbreaks past the fold: the live full admin has 52 top-level entriesDEFAULT ≤14
2T-a Accordiongroups open in place (chevron)no native form: a click expands the sidebar to that groupdrawer accordion, one openreading the whole tree; the open path stays visiblelong open groups push everything downDEFAULT expanded
2T-b Rail + flyoutaccordion (T-a)hover or click opens a child panel beside the raildrawer accordionfast hops; the rail stays 76px wideneeds hover intent and a touch ruleDEFAULT collapsed
2T-c Rail + pinned columnrail + 200px column for the current areathe column hides; the rail falls back to T-bdrawer accordionlong sessions inside one areacosts ~200px all the time; overkill for 2–3 childrenALTERNATIVE
3T-d Mega flyout (headings → links)accordion with level-2 headingswide flyout: level-2 heading, level-3 links, 1–3 columnsdrawer accordion with headingsseeing a whole area at oncelarge panel; dense past ~25 linksDEFAULT collapsed
3T-e Column + in-page tabscolumn lists level 2; level 3 = tabs on the pagecolumn hides; flyout lists level 2accordion to level 2 + chip tabsmoving sideways between sibling pageslevel-3 pages must share a frame; more than ~7 tabs scrollDEFAULT tabs part
3T-f Header section switchernav goes to level 2; breadcrumb ▾ switches level 3samebreadcrumb opens a sheetdeep links; small screenshidden until you know it is thereCOMPLEMENT
The contract the shell follows full text in MENU-TECHNIQUES.md

Depth 1 · flat

Every entry is one click away and nothing nests. It is the simplest form, and it fails on count alone.

Try: click any rail item · use the panel button at the top left to switch between the collapsed rail and the expanded list

Flat labelled listDEFAULT

Collapsed
Labelled rail at 76px, with the label under the icon (2b form). Each item is a link.
Expanded
Plain list at 232px: icon, label and optional count pill. Section captions come from sections[].label.
Keyboard
↑ ↓ move through the rail and Enter opens. The rail is one tab stop.
Touch
Tap opens. There is no hover state to depend on.
Phone
Drawer list, rows 44px tall.
When it breaks
At about 14 entries in the rail and about 22 in the expanded list on a 1440×900 laptop. The live full-admin menu sends 52 top-level entries today (right).
Good forsmall logins, such as support, with about 10 rail items.
Weak atlarge logins: 52 entries leave most of the menu below the fold.
Why depth 1 alone fails today the real 52 top-level entries the super admin's /me/menu sends, as a 76px rail at 1:1, with the 900px fold marked

Count, not looks

…

The 900px fold is generous: the browser's own chrome takes about 90px of a 900px laptop screen. Every entry below the line costs a scroll before it can be read, so a 52-entry login needs either nesting (depth 2–3) or a server regroup. The regroup is a separate exercise and out of scope here.

Source: AdminMenu.php super-admin tree as captured for the earlier menu board (phase-1/menu/src/menu_data.py): 8 sections, 52 entries, 111 links. The largest group, Materials, has 13 children.

Depth 2 · group → page

One level of nesting. The live menu is already this shape: 8 sections, then items, then children. The open question is how level 2 appears when the sidebar is collapsed and when it is expanded.

Try: click a group to open or close it · the panel button collapses it to the rail, and clicking a group there re-expands the sidebar onto that group

T-aAccordionDEFAULT

Expanded
The group row has a chevron, and its children open in place under a guide line. The group holding the active page opens on load. Several groups can stay open.
Collapsed
There is no accordion in 76px. Clicking a group re-expands the sidebar with that group open. Pair it with T-b so the rail keeps working.
Keyboard
Enter or Space toggles a group. ↑ ↓ move between rows.
Touch
Tap toggles. Rows are 30px on desktop and 34–44px in the drawer.
Phone
Drawer accordion with one group open at a time.
Good forreading the whole tree; the active path stays visible.
Weak atlong groups (13 in today's Materials) push everything below them down.
Try: hover a rail item (the panel opens after about 140ms) · click to pin it open · Tab to an item, then → or Enter to step into the panel, ↑ ↓ to move, Esc or ← to come back · the panel button switches to the accordion

T-bRail + flyoutDEFAULT

Collapsed
Hovering opens a 240px panel beside the rail after about 140ms, so the mouse can pass over the rail without opening anything. It closes about 280ms after the pointer leaves, so moving diagonally into the panel does not close it. Clicking pins it open; clicking outside or Esc closes it.
Expanded
Accordion (T-a). Same tree, same links.
Keyboard
The rail item is a button with aria-haspopup. Enter, Space or → opens the panel and focuses its first link. ↑ ↓ Home End move, and Esc or ← return to the rail item.
Touch
There is no hover on touch. The first tap opens the panel, a tap on a link navigates, and a tap outside closes it. The panel must never depend on hover.
Phone
No flyouts on a phone: the drawer accordion is used instead.
Good forfast hops between areas without giving up width.
Weak athover precision; every behaviour needs a touch and keyboard twin (built in here).
Try: click a rail item: the column switches to that area and stays open while you work · the panel button hides the column, and the rail then falls back to the flyout

T-cRail + pinned secondary column (two-pane nav)ALTERNATIVE

Expanded
Rail (76px) plus a 200px column listing the current area's children. It stays open while you work in that area.
Collapsed
The column hides, giving back 200px, and the rail behaves as T-b.
Keyboard
The rail and the column are two landmarks. Tab moves between them and ↑ ↓ move within each.
Touch
Tap a rail item to switch areas.
Phone
Drawer accordion. The column does not fit.
Good forlong sessions inside one area with 8+ pages, such as a materials workbench.
Weak atcosts 200px all the time; wasteful for areas with 2–3 children.

Depth 3 · area → group → page

Use this if the backend regroup ever produces areas with sub-groups. The rule throughout: never put an accordion inside an accordion. Level 3 appears as headings and tabs, never as a third collapsible tier.

Try: hover Catalogue or Materials: level-2 headings with their level-3 links, in up to 3 columns · Content mixes direct links and one sub-group · the panel button shows the expanded form, with headings inside the accordion

T-dFlyout with grouped headings ("mega" panel)DEFAULT

Collapsed
Wide flyout. Direct links come first, then one block per level-2 group with its heading and links. The panel is 1 column for one block, 2 for two and 3 for three or more.
Expanded
Accordion at level 1. Inside, level 2 is a small heading and level 3 is a link. There is no nested accordion.
Keyboard
As T-b. ↑ ↓ run through every link in the panel in reading order, and headings are not focusable.
Touch
Tap to open, as T-b.
Phone
Drawer accordion with the same level-2 headings.
Good forseeing a whole area at a glance, with one hop to any page.
Weak atpast ~25 links the panel becomes a page in its own right; that is the signal to regroup on the server.
Try: the column lists level 2 · open Fabrics or Components and switch pages with the tabs on the page · the panel button hides the column

T-eSecondary column + in-page tabs for level 3DEFAULT (tabs part)

Expanded
The rail selects the area, the column picks the level-2 group (it opens the group's first page), and level-3 siblings show as tabs on the page.
Collapsed
The column hides and the rail flyout lists level 2 only. The tabs stay.
Keyboard
The tabs use a tablist, with ← → between tabs as in the shadcn Tabs pattern.
Touch
Tabs scroll sideways when they overflow.
Phone
Drawer to level 2, then chip tabs across the top of the page (see Phone).
Good formoving sideways between sibling pages without going back to the menu.
Weak atlevel-3 pages must share one frame and title; past about 7 tabs they scroll.
Try: the rail flyout goes to level 2 only · in the breadcrumb, click Components ▾ or PT Colours ▾ to jump to a sibling · Esc closes

T-fBreadcrumb / section switcher in the page headerCOMPLEMENT

Expanded / collapsed
Nav goes to level 2 as in T-b and T-a. Each breadcrumb segment with siblings gets a ▾ that opens a sibling list.
Keyboard
The breadcrumb segment is a button. Enter opens it, ↑ ↓ move, Esc closes and returns focus.
Touch
Tap the segment. On a phone the list opens as a bottom sheet.
Phone
Works well, because the header is always on screen.
Good fordeep links from email or chat (you land deep and step sideways); small screens.
Weak atit is invisible until you know it is there, so it supports the menu but cannot replace it.
Recommended depth-3 combination T-d mega flyout when collapsed · accordion with headings when expanded · T-e tabs on the page · ⌘K always
Try: go to Materials › Fabrics › Fabric Codes and watch the rail item, the panel link, the breadcrumb, the page title and the tab all light together · switch tabs · toggle the sidebar

Default for depth 3DEFAULT

Why
One hop to any page from the collapsed rail, one place to look on the page for siblings, and no nested accordion anywhere.
Deeper than 3
Not drawn in the nav. The level-3 page owns any level-4 view as its own tabs or segmented control.
Good forany tree the server sends, up to 3 levels, with no special cases.
Weak atit relies on the regroup keeping each area to a size a panel can hold (~25 links).

Cross-cutting · what every depth needs

These apply on top of whichever technique is used.

Try: press ⌘K / Ctrl K or click Search · type lin, ship, codes or 发货 · ↑ ↓ ↵

⌘K Find: the escape hatch for the long tailDEFAULT

What
One input that searches every page this login can reach, at any depth, matching the label, the path and the 中文 label. Each result shows its path, so the menu is learned as you search.
Empty state
Recent pages first, then the rest.
Open from
⌘K or Ctrl K anywhere, the search box in the top bar, or the magnifier at the top of the rail.
Scope
Pages only on this board. Orders and records are the existing global search (out of scope here).
Good forthe 60% of pages a person uses once a month.
Weak atit does not teach where things live unless results show their paths, which they do here.
Try: hover a link in any flyout and click its pin · open the Pinned rail item to see pins and recent pages · switch to expanded to see them as the top two sections

Pins + recentDEFAULT

Collapsed
A Pinned rail item sits first, and its flyout shows pins and the last 4 pages.
Expanded
"Pinned" and "Recent" sections sit above the server tree.
Rules
A pin is a page key, never a copy of the label, so it follows renames. A pin to a page the login has lost disappears quietly.
Storage
Per staff. Keeping it on the server is a backend proposal (/me/preferences).
Good forgiving each person their own short menu without regrouping anything.
Weak atone more thing to tidy; keep the list short (≤8).
Try: navigate anywhere and check the four lit signals · switch the board to 中文 (top right): labels without a cn key fall back to English, as the live server does

Active-state wayfinding at every depthDEFAULT

Level 1
The rail item is lit, with a 3px steel tick and a bright icon. When expanded and open, the group row stays bright but unfilled, and the child carries the fill.
Level 2–3
The child link is lit in the flyout, accordion or column, and the active tab is underlined.
Header
The breadcrumb shows the full path, and the page title says which level-2 group generic labels like "List" belong to.
Rule
All of these come from one route match. Nothing is lit by hand per page.
Good fornever being lost after a deep link.
Weak at—
CJK labels under the 76px icon label box 62px · 10px Archivo/PingFang · 2-line clamp · full label always in the tooltip
EN
中文

Label rules for the railDEFAULT

Wrap
Up to 2 lines. CJK breaks between characters, about 6 per line at 10px. English never breaks inside a word.
Overflow
A word wider than 62px shrinks once to 9px. If it still overflows it is clamped with an ellipsis, and the tooltip carries the full label. The pink outline here is a board marker for a clipped label.
Fallback
Only 29 of 119 live labels have a cn key. A missing key shows the English label, which is what the server sends.
Stress rows
The last two rails show stress labels (8 and 9 characters, made up for this test) to prove the clamp.
Good formixed EN/中文 teams on one rail.
Weak atlong English compounds ("Declaration Composition Map") will always clamp; the expanded list shows them in full.
Permission shaping the server filters; the shell draws whatever comes back
Try: switch role · Operations loses Materials › Setup entirely (empty group) · Support loses whole sections, and Accounts becomes a direct link

Empty groups vanishDEFAULT

Server
/me/menu already omits pages a login cannot open (WP-F-02 golden fixtures: super 109 links, operations 54, edge-quirks 7, none 3).
Shell guards
Drop empty groups and sections, promote a single-child group to a direct link, and never draw a disabled row for a missing permission.
Counts (sample tree)
Good forone shell for every role; no per-role menus in the frontend.
Weak atpermission bugs show as missing pages, so the golden test on the server is the safety net.

Phone · one answer per depth

On a phone there is no rail, no flyout and no hover. The menu is a drawer, and only how the drawer nests is open. Tap ☰ to reopen the drawer after navigating.

Accordion drawer DEFAULT

One group open at a time, and the active group opens on load. Level 2 shows as headings, so there is no nested accordion. The whole path stays visible after you close and reopen the drawer.

Drill-down drawer ALTERNATIVE

One level per screen, with a ‹ back row. It opens where you are, at the active page's parent. It reads cleanly for very long groups, but you lose sight of the whole path.

Level 3 on the page

Level-3 siblings show as chip tabs under the title and scroll sideways. This is the phone form of T-e, and it covers depth 3 without a third drawer level.

Phone answer per depth
DepthDefaultAlternative
1Drawer list, rows 44px—
2Drawer accordion, one group openDrill-down
3Accordion with level-2 headings + chip tabs for level 3Drill-down (2 pushes)