NS Design System
v3.0.0 · 257 tokens

113Message turn

One entry in the transcript. The student and the assistant are told apart by structure — measure, surface, the mono role label — never by a tinted bubble. A question is short and sits in a narrow sunken card; an answer is reading, and gets the reading measure on the page surface.

Use it for

  • Every message in a transcript, both sides
  • Per-response actions — copy, regenerate, feedback — in the turn's footer

Not for

  • Colored speech balloons per speaker: that spends the whole color budget (Principle 3) on what the role label already says
  • A photo-real avatar for the assistant — the product is not pretending to be a person, so it gets a hairline mark

The pair

The whole visual argument in two turns: narrow sunken card vs full-measure prose.

You

My trigger works on one record but fails when I data-load 200. What is going on?

Assistant

Your trigger is written for one record at a time. Salesforce hands a trigger up to 200 records in a single call, so a query inside the loop runs 200 times and blows the per-transaction limit.

Query once before the loop into a Map; collect changes into a List and insert once after it.

markup
<div style="max-inline-size:44rem">
  <article class="ns-aiturn ns-aiturn--user">
    <header class="ns-aiturn__head"><span class="ns-avatar ns-avatar--sm" aria-hidden="true">RS</span>You<time datetime="2026-03-04T09:12">09:12</time></header>
    <div class="ns-aiturn__body"><p>My trigger works on one record but fails when I data-load 200. What is going on?</p></div>
  </article>
  <article class="ns-aiturn ns-aiturn--agent" data-state="done">
    <header class="ns-aiturn__head"><span class="ns-aiturn__mark" aria-hidden="true"><i class="ph ph-sparkle"></i></span>Assistant<time datetime="2026-03-04T09:12">09:12</time></header>
    <div class="ns-aiturn__body">
      <p>Your trigger is written for one record at a time. Salesforce hands a trigger up to 200 records in a single call, so a query inside the loop runs 200 times and blows the per-transaction limit.</p>
      <p>Query once before the loop into a Map; collect changes into a List and insert once after it.</p>
    </div>
    <footer class="ns-aiturn__actions">
      <button type="button" class="ns-btn ns-btn--quiet ns-btn--icon ns-btn--sm" aria-label="Copy answer"><i class="ph ph-file-text" aria-hidden="true"></i></button>
      <button type="button" class="ns-btn ns-btn--quiet ns-btn--icon ns-btn--sm" aria-label="Regenerate answer"><i class="ph ph-arrow-counter-clockwise" aria-hidden="true"></i></button>
      <button type="button" class="ns-btn ns-btn--quiet ns-btn--icon ns-btn--sm" aria-label="Helpful"><i class="ph ph-heart" aria-hidden="true"></i></button>
      <button type="button" class="ns-btn ns-btn--quiet ns-btn--icon ns-btn--sm" aria-label="Report a problem with this answer"><i class="ph ph-flag" aria-hidden="true"></i></button>
    </footer>
  </article>
</div>

In dark mode

The same two turns, and nothing about them is re-specified for dark: every surface here is a role token, so the transcript flips when the page does. Use the theme toggle at the top of this styleguide to see it — dark mode is set by data-theme on <html>, page-wide, because the role tokens resolve at the root. A navy band painted behind light components is the thing this system does not do.

You

Explain SOQL selectivity like I have never seen an index.

Assistant

A query is selective when the filter can find its rows without reading the whole table. Below roughly 10% of the object's records, the platform will use the index; above it, it scans.

markup
<div style="max-inline-size:40rem">
  <article class="ns-aiturn ns-aiturn--user">
    <header class="ns-aiturn__head"><span class="ns-avatar ns-avatar--sm" aria-hidden="true">RS</span>You</header>
    <div class="ns-aiturn__body"><p>Explain SOQL selectivity like I have never seen an index.</p></div>
  </article>
  <article class="ns-aiturn ns-aiturn--agent">
    <header class="ns-aiturn__head"><span class="ns-aiturn__mark" aria-hidden="true"><i class="ph ph-sparkle"></i></span>Assistant</header>
    <div class="ns-aiturn__body"><p>A query is selective when the filter can find its rows without reading the whole table. Below roughly 10% of the object's records, the platform will use the index; above it, it scans.</p></div>
  </article>
</div>

Regenerated

A replaced answer says so, in mono. Silently swapping what someone read a moment ago is how a tutor loses trust.

Assistant

Rewritten at your request — the earlier answer assumed you had finished the Collections lesson.

Start with the Map. A Map is a lookup table keyed by Id, and it is the one data structure that turns 200 queries into one.

markup
<article class="ns-aiturn ns-aiturn--agent" style="max-inline-size:40rem">
  <header class="ns-aiturn__head"><span class="ns-aiturn__mark" aria-hidden="true"><i class="ph ph-sparkle"></i></span>Assistant<time datetime="2026-03-04T09:20">09:20</time></header>
  <p class="ns-aiturn__note">Rewritten at your request — the earlier answer assumed you had finished the Collections lesson.</p>
  <div class="ns-aiturn__body"><p>Start with the Map. A Map is a lookup table keyed by Id, and it is the one data structure that turns 200 queries into one.</p></div>
</article>

Accessibility contract

  • Each turn is an <article> with a heading-ish mono head, so turn-by-turn navigation works
  • Actions are visible on hover AND focus, and always visible on touch — a control revealed only by a hover that cannot happen is a missing control
  • State is data-state (thinking / streaming / done / error), never a class