NS Design System
v3.0.0 · 257 tokens

104Training nav

The curriculum rail: track → module → unit, as nested <details>. On load it opens the module holding the current unit, closes the rest, and scrolls it into view inside the rail.

Use it for

  • Any track or module page
  • Curricula long enough that scrolling to find your place is the main cost

Not for

  • Flat documentation — use Docs sidebar
  • A course player — that has its own rail with a playlist

Rail with the current module open

markup
<nav class="ns-trainingnav" data-ns-trainingnav aria-label="Curriculum" style="position:static;max-block-size:22rem;inline-size:100%">
  <a class="ns-trainingnav__track" href="#0">Salesforce Administrator</a>
  <details class="ns-trainingnav__module" open>
    <summary><i class="ph ph-caret-right ns-trainingnav__twist" aria-hidden="true"></i>Objects and fields<span class="ns-trainingnav__count">6</span></summary>
    <ul class="ns-trainingnav__list">
      <li><a class="ns-trainingnav__link" data-state="done" href="#0">Standard vs custom objects</a></li>
      <li><a class="ns-trainingnav__link" data-state="done" href="#0">Field types</a></li>
    </ul>
  </details>
  <details class="ns-trainingnav__module" open>
    <summary><i class="ph ph-caret-right ns-trainingnav__twist" aria-hidden="true"></i>Security and access<span class="ns-trainingnav__count">8</span></summary>
    <ul class="ns-trainingnav__list">
      <li><a class="ns-trainingnav__link" data-state="done" href="#0">Profiles vs permission sets</a></li>
      <li><a class="ns-trainingnav__link" href="#0" aria-current="page">The role hierarchy</a></li>
      <li><a class="ns-trainingnav__link" href="#0">Sharing rules in practice</a></li>
    </ul>
  </details>
  <details class="ns-trainingnav__module" open>
    <summary><i class="ph ph-caret-right ns-trainingnav__twist" aria-hidden="true"></i>Automation: Flow<span class="ns-trainingnav__count">9</span></summary>
    <ul class="ns-trainingnav__list"><li><a class="ns-trainingnav__link" href="#0">Record-triggered flows</a></li></ul>
  </details>
</nav>

Modules, sections and posts

THE STRUCTURAL DIFFERENCE BETWEEN TRAINING AND A COURSE. A course is a flat list of lessons; a training module is a body of writing with parts, so its posts group under section labels. One sidebar, three levels — track → module → section → post. Any deeper and it is a file tree, which is what this is designed not to be. Every row carries its kind as an icon, with the word on hover or focus.

markup
<nav class="ns-trainingnav" style="position:static;max-block-size:none;inline-size:100%;max-inline-size:19rem" aria-label="Training">
  <a class="ns-trainingnav__track" href="#0">// Admin track</a>
  <details class="ns-trainingnav__module" open>
    <summary>
      <i class="ph ph-caret-right ns-trainingnav__twist" aria-hidden="true"></i>
      <span>Security and access</span>
      <span class="ns-trainingnav__count">4</span>
    </summary>
    <div class="ns-trainingnav__bar"><progress class="ns-progress" value="2" max="4" aria-label="2 of 4 posts read"></progress></div>
    <p class="ns-trainingnav__section">Concepts</p>
    <ul class="ns-trainingnav__list">
      <li><a class="ns-trainingnav__link" href="#0" data-state="done">
        <i class="ph ph-article ns-trainingnav__icon" aria-hidden="true"></i>
        <span>The permission set model</span><span class="ns-trainingnav__time">9m</span></a></li>
      <li><a class="ns-trainingnav__link" href="#0" aria-current="page">
        <i class="ph ph-video ns-trainingnav__icon" aria-hidden="true"></i>
        <span>The role hierarchy</span><span class="ns-trainingnav__time">14m</span></a></li>
    </ul>
    <p class="ns-trainingnav__section">Practice</p>
    <ul class="ns-trainingnav__list">
      <li><a class="ns-trainingnav__link" href="#0">
        <i class="ph ph-flask ns-trainingnav__icon" aria-hidden="true"></i>
        <span>Build a sharing rule</span><span class="ns-trainingnav__time">22m</span></a></li>
      <li><a class="ns-trainingnav__link" href="#0">
        <i class="ph ph-exam ns-trainingnav__icon" aria-hidden="true"></i>
        <span>Check what you know</span><span class="ns-trainingnav__time">6q</span></a></li>
    </ul>
  </details>
  <details class="ns-trainingnav__module">
    <summary>
      <i class="ph ph-caret-right ns-trainingnav__twist" aria-hidden="true"></i>
      <span>Automation</span>
      <span class="ns-trainingnav__count">6</span>
    </summary>
    <ul class="ns-trainingnav__list">
      <li><a class="ns-trainingnav__link" href="#0"><i class="ph ph-video ns-trainingnav__icon" aria-hidden="true"></i><span>Record-triggered flow</span><span class="ns-trainingnav__time">16m</span></a></li>
    </ul>
  </details>
</nav>

Accessibility contract

  • Open/closed, keyboard operation and in-page find all come from <details>
  • aria-current="page" marks the unit AND is what the script reads to decide which module to open — one attribute, so highlight and announcement cannot drift
  • Progressive: the markup ships every module open, so with JS off nothing is hidden — the rail is only longer
  • Once the reader opens a module themselves the script stops managing state; a nav that re-collapses what you just opened is fighting you