SPEC-046
Setting up your dashboard 0 entities found · 8/32 branches scanned
ID:SPEC-046Status:draft

Navigation structure

Extend the nav rune so a single content model expresses sidebar, header, footer, and section-landing navigation — with collapsible groups in the sidebar, dropdown menus in the header, column grids in the footer, and card grids on landing pages. One authoring vocabulary, four contextual renderings.

Problem

Refrakt has a sidebar nav rune today (packages/runes/src/tags/nav.ts) that interprets ## Heading as a group and list items as links. The model is exactly what header dropdowns and footer link columns also need — but the current rune is hard-wired to vertical sidebar layout, and the header/footer regions have no structured nav at all.

Header is unstructured plain markdown. site/content/_layout.md puts a flat row of [Docs] [Runes] [Blog] links in the header region. There's no way to group "Product → Pricing, Features" or "Resources → About, Blog" into desktop dropdowns / mobile accordions, and no way for themes to style header navigation consistently because there's no BEM block to hang CSS off.

Sidebar groups have no collapse affordance. Long sidebars (the runes catalog, the docs index) render every group fully expanded. Authors can't say "collapse everything except the section the reader is in" without writing a custom Svelte component.

No footer navigation primitive. The footer region exists but has no rune designed for it. Sites that want a multi-column "Product / Resources / Legal / Social" footer either inline plain markdown (no structure, no theming) or build a one-off component.

Section landing pages have no card grid. When a section index wants to show its child pages as cards with title and summary instead of a bare link list, there's no rune for it. {% nav auto %} gives a flat link list; the only card-shaped primitives (bento, feature) live in the marketing plugin and don't read from the registry. Authors fall back to writing card markup by hand on every section landing page.

Four separate runes would fragment the model. Inventing menubar, nav, footer-cols, and card-grid runes would mean four schemas, four Markdoc grammars, four CSS surfaces — for content that's structurally identical (named groups containing links).

Design Principles

One primitive, contextual rendering. Sidebar, header menubar, footer columns, and section-landing cards are the same content shape: groups of links with an optional top-level row. The nav rune already models this. Add a layout attribute (vertical | menubar | columns | cards) that selects the presentation; keep the content model identical across all four. This matches refrakt's "same primitive, different meaning by context" philosophy — a heading inside {% nav %} is already a group title, not a heading, regardless of where the nav lives.

Theme owns presentation, not authoring. Authors don't write "open by default" markers, dropdown CSS, or breakpoint logic. They write structure. The theme decides that on desktop, menubar groups are dropdowns and on mobile they're accordion sections — that's a CSS / behaviors concern, not a content concern.

Smart defaults over explicit state. For collapsible sidebars, the question "which group is open?" almost always has the answer "the one containing the current page." Make that automatic. Authors only opt in to collapsible; URL-aware expansion is handled at postProcess time.

Avoid per-heading syntax for UI state. Reject prefix conventions like ## + Heading / ## - Heading. They bleed presentation into source, break if the markdown ever renders elsewhere, and answer a question (which one starts open) that has a better automatic answer.

Authoring Surface

A single layout attribute selects rendering. All three values accept the same content shape.

{% nav %}                    # default: vertical sidebar
{% nav collapsible %}        # vertical, groups collapse, current section auto-opens
{% nav layout="menubar" %}   # horizontal bar; groups → desktop dropdowns / mobile accordion
{% nav layout="columns" %}   # column grid; groups → column titles (footer pattern)
{% nav layout="cards" %}     # card grid; items enriched with title / description / icon from frontmatter