NS Design System
v3.0.0 · 257 tokens

59Course & dashboard bars

Two bars for the signed-in product. The course bar is chrome for a page you are inside: where am I in this course, how far through, what is next — and no site navigation at all, because a link row in a lesson is an invitation to leave halfway through. The dashboard bar is the site bar with the marketing removed: places instead of pages, a Continue menu instead of a mega panel, and no sign-up anything, because they already did.

Use it for

  • The course bar above the lesson player (templates/course-player.html)
  • The dashboard bar on every signed-in app screen
  • Icons in the link row here — this is the case they exist for

Not for

  • The marketing bar's mega menu on either — a learner mid-course does not need the catalog's information architecture
  • A second row of tabs under the course bar; the curriculum rail is the course's navigation
  • Three metrics in the chrome — that is a stat band, and it belongs on the page

Course bar

Back · lesson · completion · account — and no primary action, because finishing a lesson belongs to the player’s docked prev/next and a second solid button here would compete for the one click a screen is allowed. Full page: open the course bar demo ↗

markup
<nav class="ns-coursenav" aria-label="Course example">
  <a class="ns-coursenav__back" href="#"><i class="ph ph-arrow-left" aria-hidden="true"></i> <span>Salesforce Admin</span></a>
  <span class="ns-topnav__divider" aria-hidden="true"></span>
  <span class="ns-coursenav__id">
    <span class="ns-coursenav__title">Objects, fields &amp; relationships</span>
  </span>
  <div class="ns-coursenav__progress">
    <span class="ns-coursenav__pct">29%</span>
    <div class="ns-coursenav__bar" role="progressbar" aria-label="Course progress" aria-valuenow="29" aria-valuemin="0" aria-valuemax="100" style="--p:29"><span></span></div>
  </div>
  <div class="ns-coursenav__actions">
    <button type="button" class="ns-navicon" aria-label="Previous lesson"><i class="ph ph-caret-left" aria-hidden="true"></i></button>
    <button type="button" class="ns-navicon" aria-label="Notes"><i class="ph ph-note" aria-hidden="true"></i></button>
    <button type="button" class="ns-navicon" aria-label="Toggle curriculum" aria-expanded="true"><i class="ph ph-sidebar" aria-hidden="true"></i></button>
    <a class="ns-navicon" href="#0" aria-label="Search the site"><i class="ph ph-magnifying-glass" aria-hidden="true"></i></a>
  </div>
</nav>

Course bar on the stage

--dark for a player whose video stage stays navy in both themes — the bar meets the stage rather than framing it in white.

markup
<nav class="ns-coursenav ns-coursenav--dark" aria-label="Dark course example">
  <a class="ns-coursenav__back" href="#"><i class="ph ph-arrow-left" aria-hidden="true"></i> <span>Apex for Admins</span></a>
  <span class="ns-topnav__divider" aria-hidden="true"></span>
  <span class="ns-coursenav__id">
    <span class="ns-coursenav__title">Writing your first trigger</span>
  </span>
  <div class="ns-coursenav__progress">
    <span class="ns-coursenav__pct">38%</span>
    <div class="ns-coursenav__bar" role="progressbar" aria-label="Course progress" aria-valuenow="38" aria-valuemin="0" aria-valuemax="100" style="--p:38"><span></span></div>
  </div>
  <div class="ns-coursenav__actions">
    <button type="button" class="ns-navicon" aria-label="Previous lesson"><i class="ph ph-caret-left" aria-hidden="true"></i></button>
    <button type="button" class="ns-btn ns-btn--white ns-btn--sm"><i class="ph ph-check-circle" aria-hidden="true"></i> Complete</button>
  </div>
</nav>

Dashboard bar

Places, not pages: icons earn their space, the trigger opens what you were last in, and the avatar wears the trail's progress ring. Live: click Continue or the avatar. Full page: open the dashboard bar demo ↗

markup
<nav class="ns-topnav ns-topnav--compact" aria-label="Dashboard example">
  <a class="ns-topnav__brand" href="#"><img src="../assets/logo/favicon.svg" alt=""><span class="ns-topnav__brand-name">Namaste Salesforce</span></a>
  <ul class="ns-topnav__links">
    <li><a href="#" aria-current="page"><i class="ph ph-squares-four" aria-hidden="true"></i> Dashboard</a></li>
    <li class="ns-navitem">
      <button type="button" class="ns-topnav__trigger" data-ns-menu aria-expanded="false" aria-controls="doc-continue"><i class="ph ph-play-circle" aria-hidden="true"></i> Continue</button>
      <div class="ns-navmenu" id="doc-continue">
        <p class="ns-navmenu__label">Pick up where you left off</p>
        <a class="ns-navmenu__item" href="#">
          <span class="ns-navmenu__icon"><i class="ph ph-play" aria-hidden="true"></i></span>
          <span><span class="ns-navmenu__title">Objects &amp; fields</span><span class="ns-navmenu__desc">Salesforce Admin · lesson 07 of 24</span></span>
        </a>
        <a class="ns-navmenu__item" href="#">
          <span class="ns-navmenu__icon"><i class="ph ph-code" aria-hidden="true"></i></span>
          <span><span class="ns-navmenu__title">Apex triggers</span><span class="ns-navmenu__desc">Developer trail · lesson 03 of 31</span></span>
        </a>
        <div class="ns-navmenu__foot"><span>2 in progress</span><a href="#">All courses →</a></div>
      </div>
    </li>
  </ul>
  <div class="ns-topnav__actions">
    <span class="ns-navstat"><i class="ph ph-lightning" aria-hidden="true"></i> <strong>12</strong> day streak</span>
    <a class="ns-navicon" href="#" aria-label="Notifications — 3 unread"><i class="ph ph-bell" aria-hidden="true"></i><span class="ns-navicon__badge" aria-hidden="true">3</span></a>
    <button type="button" class="ns-themeswitch" role="switch" aria-checked="false" aria-label="Dark mode" data-ns-theme-toggle>
      <span class="ns-themeswitch__mark" aria-hidden="true"></span>
    </button>
    <span class="ns-topnav__divider" aria-hidden="true"></span>
    <div class="ns-usermenu">
      <button type="button" class="ns-usermenu__trigger" data-ns-menu aria-expanded="false" aria-controls="doc-dash-account" aria-label="Account menu for Aarti Kulkarni">
        <span class="ns-avatar-ring" style="--p:29"><span class="ns-avatar ns-avatar--sm" aria-hidden="true">AK</span></span>
      </button>
      <div class="ns-usermenu__panel" id="doc-dash-account">
        <div class="ns-usermenu__head">
          <span class="ns-avatar" aria-hidden="true">AK</span>
          <span class="ns-usermenu__identity"><span class="ns-usermenu__fullname">Aarti Kulkarni</span><span class="ns-usermenu__email">aarti@example.com</span></span>
          <span class="ns-usermenu__plan">Pro</span>
        </div>
        <div class="ns-usermenu__progress">
          <span class="ns-usermenu__progress-label"><span>Admin trail</span><span>29%</span></span>
          <progress class="ns-progress" value="29" max="100" aria-label="Admin trail progress">29%</progress>
        </div>
        <hr class="ns-menu__sep">
        <a class="ns-menu__item" href="#"><i class="ph ph-user" aria-hidden="true"></i> Profile</a>
        <a class="ns-menu__item" href="#"><i class="ph ph-gear" aria-hidden="true"></i> Settings</a>
      </div>
    </div>
  </div>
</nav>

Bar pieces

The two parts these bars add to the vocabulary. .ns-navicon is the icon-only action — square, hairline on hover, an aria-label always, and a badge that is a COUNT rather than a bare dot, because a dot tells a screen-reader user nothing. .ns-navstat is one mono metric; two at most.

12 day streak 48 min today
markup
<button type="button" class="ns-navicon" aria-label="Notifications"><i class="ph ph-bell" aria-hidden="true"></i></button>
<button type="button" class="ns-navicon" aria-label="Notifications — 3 unread"><i class="ph ph-bell" aria-hidden="true"></i><span class="ns-navicon__badge" aria-hidden="true">3</span></button>
<button type="button" class="ns-navicon" aria-label="Toggle curriculum" aria-expanded="true"><i class="ph ph-sidebar" aria-hidden="true"></i></button>
<button type="button" class="ns-navicon" aria-label="Notes"><i class="ph ph-note" aria-hidden="true"></i></button>
<span class="ns-navstat"><i class="ph ph-lightning" aria-hidden="true"></i> <strong>12</strong> day streak</span>
<span class="ns-navstat"><i class="ph ph-timer" aria-hidden="true"></i> <strong>48</strong> min today</span>

Accessibility contract

  • Course progress is a real progressbar with aria-valuenow: unlike the blog's reading line it is a number the learner acts on, so it is labelled and announced
  • The back control names its destination — a bare chevron sends people to the browser's back button, and out of the video
  • Every icon-only control (previous, notes, curriculum, notifications) carries an aria-label, and the notification badge is a count that appears in that label too
  • Below md the bar sheds in a fixed order — the back label, then the inline meter, then the button labels. The lesson title and Next never go