NS Design System
v3.0.0 · 257 tokens

86Course detail page

The course's landing: hero (title, meta, the one primary action), the stat band, the outcomes, and then the five arguments — overview, curriculum, instructors, reviews, FAQ — as TABS in the content column, with the enrol card sticky in the rail beside them. One primary button on the whole page.

Use it for

  • Every course's public page, both products

Not for

  • The lesson experience — Course player

Anatomy — content + sticky rail

The grid at documentation scale; open the full-screen demo for the real thing.

// Course · Beginner

Apex basics

Objects, triggers and your first deploy — the platform's own language from zero. Concept, concrete example, bridge to the next step: every lesson, same shape.

01

Getting oriented

3 lessons
What is an org?Free Objects & fields
markup
<div class="ns-course-detail" style="inline-size:100%">
  <div>
    <span class="ns-kicker">// Course · Beginner</span>
    <h2 style="font-size:var(--size-h3);margin-block:var(--space-2) var(--space-3)">Apex basics</h2>
    <p style="color:var(--color-muted);font-size:var(--size-small);max-inline-size:34rem">Objects, triggers and your first deploy — the platform's own language from zero. Concept, concrete example, bridge to the next step: every lesson, same shape.</p>
    <div class="ns-curriculum" style="margin-block-start:var(--space-5)">
      <section class="ns-curriculum__section">
        <header class="ns-curriculum__head"><span class="ns-curriculum__index">01</span><h3 class="ns-curriculum__title">Getting oriented</h3><span class="ns-curriculum__meta">3 lessons</span></header>
        <a class="ns-lesson" href="#"><span class="ns-lesson__index" aria-hidden="true">01</span><span class="ns-lesson__title">What is an org?</span><span class="ns-lesson__time"><span class="ns-tag">Free</span></span></a>
        <a class="ns-lesson" href="#" data-state="locked"><span class="ns-lesson__index" aria-hidden="true">02</span><span class="ns-lesson__title">Objects &amp; fields</span><span class="ns-lesson__time"><i class="ph ph-lock" aria-hidden="true"></i></span></a>
      </section>
    </div>
  </div>
  <aside class="ns-course-detail__rail">
    <div class="ns-railbox">
      <p class="ns-railbox__title">This course</p>
      <p style="font-size:var(--size-small);color:var(--color-muted)">12 lessons · 3h 40m · certificate</p>
      <button class="ns-btn ns-btn--primary ns-btn--block" style="margin-block-start:var(--space-3)">Start learning free</button>
    </div>
    <div class="ns-railbox">
      <p class="ns-railbox__title">Instructor</p>
      <div style="display:flex;align-items:center;gap:var(--space-3)">
        <span class="ns-avatar">SW</span>
        <span style="font-size:var(--size-small)">Swarnil Singhai<br><span style="color:var(--color-muted)">Salesforce architect</span></span>
      </div>
    </div>
  </aside>
</div>

Full page

Three decisions worth knowing before you copy it. Tabs, not eight stacked bands — a course page carries five separate arguments, and stacked they make a page nobody reaches the bottom of, with the curriculum (the thing people came to read) buried three screens down. Outcomes above the tabs, never inside one — "what will I be able to do" is the question every visitor arrives with, and it decides whether they read anything else; each promise takes the icon of the thing it produces rather than a fifth identical tick, because five ticks is a list that has to be read and five glyphs is one that can be scanned. The lesson kind is an icon — twenty-four rows that each spell out VIDEO turn a curriculum into a spreadsheet; the word stays in the DOM and returns as a tooltip, which frees the row's second line for what the glyph cannot say: whether the row is open to you.

markup
<p><a class="ns-btn ns-btn--outline ns-btn--sm" href="./demo-course-detail.html" target="_blank" rel="noopener">Open the full-screen demo <i class="ph ph-arrow-up-right" aria-hidden="true"></i></a></p>

The five shapes

Same content, same components, five arrangements — because a $9 course, a certification track and a free tutorial are not the same sale. --wide puts the rail LEFT for a course whose curriculum is the product; --stacked drops the rail entirely (free courses: a sticky price rail advertising nothing); --syllabus leads with the curriculum for a returning learner; --compact is one prose column, the documentation-page look.

--wide

The curriculum is the product, so it gets the wide column and the price follows it down.

--stacked

No rail at all — the buy box sits after the outcomes, in the reading column.

--compact

One column at the prose measure, no media: a course documented rather than sold.

markup
<div style="display:grid;gap:var(--space-6);inline-size:100%">
  <div class="ns-course-detail ns-course-detail--wide" style="border:1px solid var(--color-border);border-radius:var(--radius-card);padding:var(--pad-card)">
    <aside class="ns-course-detail__rail"><div class="ns-card"><div class="ns-card__body"><span class="ns-card__kicker">// Rail left</span><span class="ns-card__title">$49</span></div></div></aside>
    <div class="ns-course-detail__main"><p class="ns-kicker">--wide</p><p>The curriculum is the product, so it gets the wide column and the price follows it down.</p></div>
  </div>
  <div class="ns-course-detail ns-course-detail--stacked" style="border:1px solid var(--color-border);border-radius:var(--radius-card);padding:var(--pad-card)">
    <div class="ns-course-detail__main"><p class="ns-kicker">--stacked</p><p>No rail at all — the buy box sits after the outcomes, in the reading column.</p></div>
    <aside class="ns-course-detail__rail"><div class="ns-card"><div class="ns-card__body"><span class="ns-card__title">Free</span></div></div></aside>
  </div>
  <div class="ns-course-detail ns-course-detail--compact" style="border:1px solid var(--color-border);border-radius:var(--radius-card);padding:var(--pad-card)">
    <div class="ns-course-detail__main"><p class="ns-kicker">--compact</p><p>One column at the prose measure, no media: a course documented rather than sold.</p></div>
  </div>
</div>

Accessibility contract

  • The hero's enroll button and the rail's are the same action — one label, both reachable
  • The curriculum is the real component, so its row semantics come along
  • Tabs are the real ARIA pattern via assets/js/tabs.js — and with no JS every panel is visible, so the stacked page is the fallback rather than a page with four sections missing