@nadicodeai/design-system 0.10.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/AGENTS.md +30 -101
  2. package/CONTEXT.md +75 -0
  3. package/DESIGN.md +180 -345
  4. package/README.md +27 -54
  5. package/dist/assets/logo-mark.svg +6 -0
  6. package/dist/assets/logo-wordmark.svg +4 -0
  7. package/dist/assets/nadia-canonical-face.png +0 -0
  8. package/dist/css/chat-autoplay.js +18 -27
  9. package/dist/css/index.css +2540 -56
  10. package/dist/favicon/apple-touch-icon.png +0 -0
  11. package/dist/favicon/favicon.ico +0 -0
  12. package/dist/favicon/favicon.svg +6 -16
  13. package/dist/favicon/icon-192.png +0 -0
  14. package/dist/favicon/icon-512.png +0 -0
  15. package/dist/favicon/site.webmanifest +2 -2
  16. package/dist/tailwind/nadicode.tailwind.json +98 -143
  17. package/dist/tokens/nadicode.dtcg.json +413 -908
  18. package/package.json +19 -11
  19. package/src/assets/logo-geometry.d.ts +27 -0
  20. package/src/assets/logo-geometry.js +204 -0
  21. package/src/assets/nadia-canonical-face.d.ts +2 -0
  22. package/dist/css/components/.gitkeep +0 -0
  23. package/dist/css/components/agent-avatar.css +0 -52
  24. package/dist/css/components/approval-gate.css +0 -145
  25. package/dist/css/components/artifact-preview.css +0 -81
  26. package/dist/css/components/chat-bubble-agent.css +0 -63
  27. package/dist/css/components/chat-bubble-user.css +0 -28
  28. package/dist/css/components/chat-thread.css +0 -159
  29. package/dist/css/components/handoff-banner.css +0 -37
  30. package/dist/css/components/image.css +0 -87
  31. package/dist/css/components/memory-item.css +0 -36
  32. package/dist/css/components/run-timeline.css +0 -160
  33. package/dist/css/components/state-row.css +0 -64
  34. package/dist/css/components/state-tag.css +0 -67
  35. package/dist/css/components/status-tag.css +0 -101
  36. package/dist/css/components/tool-call-trace.css +0 -36
  37. package/dist/css/components/typing-dots.css +0 -54
  38. package/dist/css/components/usage-meter.css +0 -63
  39. package/dist/css/foundation.css +0 -177
  40. package/dist/css/layout.css +0 -657
  41. package/dist/css/motion.css +0 -225
  42. package/dist/css/primitives.css +0 -333
  43. package/dist/css/reset.css +0 -22
  44. package/dist/css/tokens.generated.css +0 -349
  45. package/dist/css/tokens.local.css +0 -11
  46. package/dist/tailwind/nadicode.theme.css +0 -596
  47. package/src/assets/favicon.svg +0 -17
  48. package/src/assets/logo-mark.svg +0 -15
  49. package/src/assets/logo-wordmark.svg +0 -26
  50. package/src/assets/nadia.d.ts +0 -9
  51. package/src/assets/nadia.png +0 -0
package/README.md CHANGED
@@ -1,19 +1,20 @@
1
1
  # NadicodeAI Design System
2
2
 
3
- The `@nadicodeai/design-system` package. [`DESIGN.md`](./DESIGN.md) is the normative implementation contract for reusable design tokens and package output; the canonical human brand book lives in the monorepo at `brand/brand-book/index.html`.
3
+ The `@nadicodeai/design-system` package. [`DESIGN.md`](./DESIGN.md) is the normative contract for reusable design tokens, mode behavior, CSS architecture, and generated output. The canonical human brand book lives in the monorepo at `brand/brand-book/index.html`.
4
4
 
5
- `DESIGN.md` defines the normative NadicodeAI design system contract: tokens, typography, layout, components, do's and don'ts, written to the [@google/design.md](https://github.com/google-labs-code/design.md) spec. `npm run build` emits two consumable exports: `dist/tokens/nadicode.dtcg.json` (DTCG token format) and `dist/tailwind/nadicode.tailwind.json` (Tailwind config).
5
+ This README is a package map and the setup guide for static or non-React consumers. React consumers use the UI package's single stylesheet interface and follow [`@nadicodeai/ui/docs/consuming-cross-repo.md`](../@nadicodeai/ui/docs/consuming-cross-repo.md). They do not compose design-system stylesheets themselves.
6
6
 
7
- For Tailwind CSS v4 CSS-first projects, `npm run build` also emits `dist/tailwind/nadicode.theme.css`, exported as `@nadicodeai/design-system/tailwind/theme.css`. Import it from the consuming app's CSS entry:
7
+ ## Static and non-React consumption
8
+
9
+ Import the complete CSS module once:
8
10
 
9
11
  ```css
10
- @import "tailwindcss";
11
- @import "@nadicodeai/design-system/tailwind/theme.css";
12
+ @import "@nadicodeai/design-system/css";
12
13
  ```
13
14
 
14
- The CSS adapter provides shadcn-compatible semantic utilities such as `bg-background`, `text-foreground`, `bg-primary`, `text-primary-foreground`, `border-border`, and `ring-ring`. It publishes both `:root` light roles and `.dark` dark roles; consuming apps opt into dark mode by applying a `.dark` ancestor, normally through their own theme provider. The raw `--nc-*` brand-token remaps (the state, selection, cross, and chart families) are the one exception: they are emitted at `:root.dark`, so they flip only when the `dark` class sits on the root element itself (the next-themes `attribute="class"` default), not on an inner wrapper. NadicodeAI-specific spacing utilities are namespaced, for example `p-nadicode-lg` and `h-nadicode-h-cell-sm`, so standard Tailwind/shadcn classes such as `max-w-3xl` keep their normal Tailwind behavior. React consumers normally get this through `@nadicodeai/ui/globals.css`.
15
+ That interface includes the generated tokens, mode aliases, semantic role maps, page geometry, type utilities, motion primitives, and framework-agnostic CSS components. Apply `.dark` to the document root or to a scoped static composition to select dark mode. The generation and cascade mechanics live only in [`DESIGN.md`, "CSS Architecture & Token Pipeline"](./DESIGN.md#css-architecture--token-pipeline).
15
16
 
16
- Geist and Geist Mono (SIL Open Font License 1.1) ship inside the package under `src/assets/fonts/`. Consumers can pull the `@font-face` shim directly:
17
+ Geist and Geist Mono (SIL Open Font License 1.1) are optional package assets. A static consumer that does not supply its own font loading can import the `@font-face` shim:
17
18
 
18
19
  ```css
19
20
  @import "@nadicodeai/design-system/assets/fonts/geist.css";
@@ -21,62 +22,36 @@ Geist and Geist Mono (SIL Open Font License 1.1) ship inside the package under `
21
22
 
22
23
  Individual font files are also exposed under `@nadicodeai/design-system/assets/fonts/*` if the consumer needs to write its own `@font-face` declarations.
23
24
 
24
- ## The `/css` bundle
25
-
26
- `DESIGN.md` is the token contract (Surface 1, exported as values). The CSS bundle is Surface 2: the hand-authored, framework-agnostic stylesheet that turns those tokens into the actual NadicodeAI website geometry, chrome, and the agent-chat experience. Import it with one line:
27
-
28
- ```css
29
- @import "@nadicodeai/design-system/css";
30
- ```
31
-
32
- That single import delivers:
33
-
34
- - the kernel page geometry — the 12-column page frame, the centered 10-column active lane, and single-owner seams;
35
- - the framework-agnostic brand display vocabulary: the agent-chat component family, run-state tags, `image`, artifact surfaces, and workflow state chrome;
36
- - the brand motion contract (`--nc-duration-*` / `--nc-ease-*` tokens, the `nc-msg-in` / `nc-typing` / `nc-pulse` keyframes, and a `prefers-reduced-motion: reduce` block that disables them);
37
- - the agent-chat CSS components — `nc-chat-thread`, `nc-chat-bubble-user`, `nc-chat-bubble-agent`, `nc-tool-call-trace`, `nc-memory-item`, `nc-handoff-banner`, `nc-approval-gate`, `nc-artifact-preview`, `nc-typing-dots`, `nc-state-row`, plus `nc-agent-avatar` and `nc-usage-meter`.
38
-
39
- Everything is token-only (`var(--nc-*)`); there is no hard-coded hex in the CSS components or structural geometry. Individual files are also reachable under `@nadicodeai/design-system/css/*` (for example `@nadicodeai/design-system/css/components/chat-thread.css`).
25
+ ## Package surface
40
26
 
41
- The built bundle mirrors every kept partial into `dist/css/`. Generic marketing/SaaS sections and interactive components ship from `@nadicodeai/ui`, not this CSS package.
27
+ `package.json` owns the current public export paths. [`DESIGN.md`](./DESIGN.md)
28
+ owns what those exports mean and how the CSS cascade, modes, tokens, layout,
29
+ components, motion, and assets behave. The runnable [`examples/`](./examples/)
30
+ consume only those public exports and are the inspection surface. This README
31
+ does not maintain a parallel inventory.
42
32
 
43
- ### The eight-layer cascade
33
+ CSS partials and generated adapter files are implementation details. React
34
+ components and compositions are discovered through the UI package rather than
35
+ inferred from this CSS package.
44
36
 
45
- The bundle declares one explicit `@layer` order up front, then imports each partial into its own layer:
46
-
47
- ```css
48
- @layer tokens, reset, foundation, motion, layout, primitives, components;
49
- ```
50
-
51
- Because the order is declared data, consumer overrides are predictable: layer your own rules in a layer that comes *after* the bundle and they win regardless of selector specificity. Open a page-local block with `@layer page;` and write page overrides into `@layer page { … }`, which sits after `components`:
37
+ Consumer overrides belong in an explicit later layer:
52
38
 
53
39
  ```css
54
40
  @layer page;
55
41
  @layer page {
56
- /* page-specific overrides — always win over the bundle */
42
+ /* Page-specific overrides. */
57
43
  }
58
44
  ```
59
45
 
60
- ### Relationship to `theme.css` and shadcn
61
-
62
- The `/css` bundle and the Tailwind `theme.css` adapter are complementary:
46
+ The exact layer order and ownership rules are defined in `DESIGN.md`.
63
47
 
64
- - `@nadicodeai/design-system/tailwind/theme.css` publishes the shadcn `:root` and `.dark` token variables (the semantic `bg-background` / `text-foreground` / `border-border` family), so interactive shadcn app islands land on-brand when they need JS-driven accessibility behavior such as dialogs or comboboxes.
65
- - The `/css` bundle ships NadicodeAI's framework-agnostic page grammar, CSS components, brand motion contract, and agent-chat surfaces.
66
- - `@nadicodeai/ui` ships the React shadcn-style components and reusable section/app compositions on top of those tokens and CSS components.
48
+ ### Optional chat auto-play
67
49
 
68
- Use both together: React apps import `@nadicodeai/ui/globals.css` for Tailwind/shadcn utilities and `@import "@nadicodeai/design-system/css"` for NadicodeAI geometry and CSS components.
69
-
70
- ### The agent-chat CSS components and the optional auto-play enhancer
71
-
72
- The chat CSS components render a complete, static agent conversation from CSS alone — no JavaScript required. `nc-chat-bubble-agent` carries a 3px accent edge whose color is switched by `[data-accent]` (for example `data-accent="green"`), mapped to existing `--nc-*` tokens.
73
-
74
- For motion, the package ships exactly one optional, vanilla, dependency-free enhancer: `chat-autoplay.js`, exported as `@nadicodeai/design-system/css/chat-autoplay.js`. It is the **only** JavaScript in the package — no React, no framework, no registry, no module/CDN imports. It is pure progressive enhancement:
75
-
76
- - add `data-nc-autoplay` to a `nc-chat-thread` and include the script; messages then reveal in scripted order, a typing indicator shows between turns, the thread scrolls to the newest message, and the cycle loops;
77
- - playback starts when the thread scrolls into view (`IntersectionObserver`);
78
- - under `prefers-reduced-motion: reduce`, the full thread is shown immediately with no loop;
79
- - **with the script absent, the full thread renders statically** — the components are usable framework-agnostically, with zero React.
50
+ Static chat markup needs no JavaScript. To opt a `data-nc-autoplay` thread into
51
+ progressive playback, include the public
52
+ `@nadicodeai/design-system/css/chat-autoplay.js` export. The `chat-thread`
53
+ entry in [`DESIGN.md`](./DESIGN.md#agentic-work-surfaces) owns the behavior and
54
+ accessibility contract.
80
55
 
81
56
  ### Worked example (static HTML)
82
57
 
@@ -116,8 +91,6 @@ For motion, the package ships exactly one optional, vanilla, dependency-free enh
116
91
  </html>
117
92
  ```
118
93
 
119
- `examples/chat-showcase.html` is a live proof page that composes the chat CSS components with the auto-play enhancer across twelve conversations.
94
+ `examples/chat-showcase.html` is the live proof page for the chat CSS components and auto-play enhancer.
120
95
 
121
96
  Use the monorepo's `brand/brand-book/` for NadicodeAI story, positioning, buyer, promise, method, use cases, technology story, trust doctrine, identity, voice, visual direction, sales behavior, language, and boundaries.
122
-
123
- The `design-canvas/` prototypes the kernel re-expresses (chat motion and component prototypes) are deleted from the tree; git history retains them under `docs/experiments/design-canvas/`. They are not package runtime or current brand canon.
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 160" role="img" aria-label="NadicodeAI mark">
2
+ <clipPath id="mark-overlap"><rect x="58" y="84" width="26" height="26"/></clipPath>
3
+ <rect fill="none" stroke="currentColor" stroke-width="10" x="42" y="50" width="46" height="46" rx="13"/>
4
+ <rect fill="none" stroke="var(--nc-primary, #00a85a)" stroke-width="10" x="72" y="64" width="46" height="46" rx="13"/>
5
+ <rect fill="none" stroke="currentColor" stroke-width="10" x="42" y="50" width="46" height="46" rx="13" clip-path="url(#mark-overlap)"/>
6
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 100" role="img" aria-label="NadicodeAI wordmark">
2
+ <g fill="currentColor" transform="translate(0 76) scale(0.06 -0.06)"><path transform="translate(0 0)" d="M74 0L74 710L242 710L524 220L524 710L676 710L676 0L506 0L226 473L226 0Z"/><path transform="translate(706.867 0)" d="M225 -12Q142 -12 89.5 26.5Q37 65 37 134Q37 205 81.5 243.5Q126 282 213 300L386 334Q386 386 362.5 412.5Q339 439 295 439Q252 439 228 419.5Q204 400 197 362L46 369Q61 457 125.5 502.5Q190 548 295 548Q415 548 475.5 491Q536 434 536 324L536 141Q536 118 543.5 110.5Q551 103 566 103L581 103L581 0Q574 -2 558.5 -4Q543 -6 528 -6Q496 -6 468.5 5Q441 16 424 42.5Q407 69 407 118L420 108Q410 72 384.5 45Q359 18 318.5 3Q278 -12 225 -12ZM261 91Q298 91 326 105.5Q354 120 370 148Q386 176 386 214L386 240L264 214Q228 207 209.5 190.5Q191 174 191 148Q191 121 209 106Q227 91 261 91Z"/><path transform="translate(1258.133 0)" d="M257 -12Q189 -12 139.5 22.5Q90 57 63.5 119.5Q37 182 37 268Q37 354 64 416.5Q91 479 140.5 513.5Q190 548 257 548Q314 548 355.5 524.5Q397 501 418 460L418 710L568 710L568 0L425 0L422 79Q400 36 356.5 12Q313 -12 257 -12ZM306 103Q342 103 367 122Q392 141 405 177.5Q418 214 418 268Q418 323 405 359.5Q392 396 367 414.5Q342 433 306 433Q253 433 222 388.5Q191 344 191 268Q191 193 222.5 148Q254 103 306 103Z"/><path transform="translate(1844.8 0)" d="M66 0L66 536L216 536L216 0ZM63 602L63 722L218 722L218 602Z"/><path transform="translate(2082.667 0)" d="M309 -12Q227 -12 166 22.5Q105 57 71 120Q37 183 37 268Q37 353 71 415.5Q105 478 166 513Q227 548 309 548Q380 548 436.5 523Q493 498 528 451Q563 404 571 338L416 331Q409 381 380.5 406.5Q352 432 309 432Q253 432 222 389Q191 346 191 268Q191 190 222 146.5Q253 103 309 103Q352 103 381 129.5Q410 156 416 210L571 204Q564 138 529.5 89.5Q495 41 438.5 14.5Q382 -12 309 -12Z"/><path transform="translate(2636.933 0)" d="M309 -12Q227 -12 166 22.5Q105 57 71 120Q37 183 37 268Q37 353 71 415.5Q105 478 166 513Q227 548 309 548Q391 548 452 513Q513 478 547 415.5Q581 353 581 268Q581 183 547 120Q513 57 452 22.5Q391 -12 309 -12ZM309 103Q365 103 396 146.5Q427 190 427 268Q427 346 396 389.5Q365 433 309 433Q253 433 222 389.5Q191 346 191 268Q191 190 222 146.5Q253 103 309 103Z"/><path transform="translate(3211.6 0)" d="M257 -12Q189 -12 139.5 22.5Q90 57 63.5 119.5Q37 182 37 268Q37 354 64 416.5Q91 479 140.5 513.5Q190 548 257 548Q314 548 355.5 524.5Q397 501 418 460L418 710L568 710L568 0L425 0L422 79Q400 36 356.5 12Q313 -12 257 -12ZM306 103Q342 103 367 122Q392 141 405 177.5Q418 214 418 268Q418 323 405 359.5Q392 396 367 414.5Q342 433 306 433Q253 433 222 388.5Q191 344 191 268Q191 193 222.5 148Q254 103 306 103Z"/><path transform="translate(3802.267 0)" d="M307 -12Q225 -12 164.5 22.5Q104 57 70.5 120Q37 183 37 268Q37 353 70.5 415.5Q104 478 164 513Q224 548 306 548Q386 548 445 513Q504 478 536.5 413Q569 348 569 258L569 228L192 228Q195 164 226.5 133Q258 102 310 102Q348 102 373.5 118Q399 134 410 167L561 158Q540 78 472 33Q404 -12 307 -12ZM192 320L415 320Q412 379 382.5 408Q353 437 306 437Q259 437 228.5 406.5Q198 376 192 320Z"/></g>
3
+ <g fill="var(--nc-primary, #00a85a)" transform="translate(259 76) scale(0.06 -0.06)"><path transform="translate(0 0)" d="M19 0L275 710L455 710L711 0L553 0L501 151L228 151L176 0ZM271 276L459 276L365 550Z"/><path transform="translate(670.467 0)" d="M74 0L74 710L226 710L226 0Z"/></g>
4
+ </svg>
@@ -4,24 +4,23 @@
4
4
  *
5
5
  * It is pure progressive enhancement, framework-free, dependency-free, with no
6
6
  * module-loader statements and no third-party runtime. It turns an
7
- * already-static `.nc-chat-thread` into the auto-playing, looping agent
8
- * conversation from the archived prototype
9
- * `docs/experiments/design-canvas/chat-anim.jsx` — re-expressed as plain DOM.
7
+ * already-static `.nc-chat-thread` into an auto-playing, looping agent
8
+ * conversation.
10
9
  *
11
- * Contract (mirrors AC-018 and the M5 motion contract):
10
+ * Runtime behavior:
12
11
  *
13
12
  * (a) Motion on: messages are hidden, then revealed in scripted source order by
14
- * toggling the M5 `.nc-anim-msg-in` hook (the rise-in). A typing indicator
13
+ * toggling the `.nc-anim-msg-in` hook (the rise-in). A typing indicator
15
14
  * (`.nc-typing-dots`) shows between turns, the thread body auto-scrolls to
16
15
  * the newest message, the `.nc-usage-meter-fill` is driven via `--nc-usage`,
17
- * and after `loopHold` (default 2400ms) the cycle restarts.
16
+ * and after `LOOP_HOLD` the cycle restarts.
18
17
  *
19
18
  * (b) `prefers-reduced-motion: reduce`: the FULL thread is shown immediately,
20
19
  * every message visible, NO loop, no typing animation. (We also stop if the
21
20
  * preference changes to reduce mid-play.)
22
21
  *
23
22
  * (c) Script absent: the conversation renders FULLY and statically from CSS
24
- * alone. The atoms set `animation-name: nc-msg-in` but, without the M5
23
+ * alone. The atoms set `animation-name: nc-msg-in` but, without the
25
24
  * `.nc-anim-msg-in` hook supplying a duration, that is inert and every
26
25
  * message is visible. This file is the ONLY thing that ever hides a message
27
26
  * (via the per-element inline `display` it sets while playing). No hidden
@@ -30,13 +29,11 @@
30
29
  * (d) Playback starts on scroll-into-view via `IntersectionObserver`; it pauses
31
30
  * (resets to the static full thread and re-arms) when scrolled fully out.
32
31
  *
33
- * Timing parity with `src/css/motion.css`: the loop reads the M5 duration tokens
32
+ * Timing parity with `src/css/motion.css`: the loop reads the duration token
34
33
  * (`--nc-duration-stagger`) from the thread's computed style and uses the
35
- * per-role `defaultTiming()` rhythm ported verbatim from the prototype's
36
- * `defaultTiming` (typingMs / holdMs per role + `loopHold`). The stagger unit
37
- * comes from CSS, not a re-typed magic number; the per-role typing/hold cadence
38
- * is the documented constants table below, carried with a parity note because
39
- * the prototype owns those numbers in JS, not in CSS.
34
+ * per-role `defaultTiming()` rhythm below. The stagger unit comes from CSS, not
35
+ * a re-typed magic number; this module owns the sequencing cadence because it
36
+ * is runtime behavior rather than a reusable visual token.
40
37
  *
41
38
  * Opt-in: only `.nc-chat-thread[data-nc-autoplay]` elements are enhanced. A
42
39
  * thread without the attribute is left fully static.
@@ -51,14 +48,9 @@
51
48
 
52
49
  if (typeof window === "undefined" || typeof document === "undefined") return;
53
50
 
54
- // ── Per-role timing, ported verbatim from chat-anim.jsx `defaultTiming`. ──
55
- // PARITY NOTE: these (typingMs, holdMs) pairs and `LOOP_HOLD` live in JS in the
56
- // prototype (they are sequencing logic, not CSS), so they are mirrored here as
57
- // a documented constants table rather than read from motion.css. The CSS owns
58
- // the *visual* cadence (the stagger step), which we DO read from motion.css
59
- // below; this table owns the *sequencing* cadence.
60
- var LOOP_HOLD = 6000; // chat-anim.jsx loopHold default (raised: payoff frame dominates loop duty cycle)
61
- var START_DELAY = 240; // chat-anim.jsx `await sleep(startDelay + 240)` with startDelay 0
51
+ // The CSS token owns visual stagger. These values own runtime sequencing.
52
+ var LOOP_HOLD = 6000; // Keep the completed state visible for most of the loop.
53
+ var START_DELAY = 240;
62
54
 
63
55
  function defaultTiming(role, textLen) {
64
56
  var len = textLen || 0;
@@ -255,7 +247,7 @@
255
247
 
256
248
  ChatThreadPlayer.prototype._reveal = function (msg, index) {
257
249
  msg.style.display = "";
258
- // Re-trigger the M5 rise-in: the hook supplies duration/easing; the atom
250
+ // Re-trigger the rise-in: the hook supplies duration/easing; the atom
259
251
  // already carries `animation-name: nc-msg-in`. Force a reflow so re-adding
260
252
  // the class restarts the animation on a re-loop.
261
253
  msg.style.setProperty("--nc-anim-delay", "0ms");
@@ -266,9 +258,8 @@
266
258
  this._scrollToBottom();
267
259
  };
268
260
 
269
- // The reveal loop a vanilla re-expression of chat-anim.jsx's `run()`. A loop
270
- // is "stale" once it is cancelled OR a newer epoch has started; either way it
271
- // must stop touching the DOM. `myGen` is captured once at start so a queued
261
+ // A loop is "stale" once it is cancelled OR a newer epoch has started; either
262
+ // way it must stop touching the DOM. `myGen` is captured once at start so a queued
272
263
  // continuation can detect that the player was stopped-and-re-armed underneath
273
264
  // it (see the `generation` note in the constructor).
274
265
  ChatThreadPlayer.prototype._runLoop = function () {
@@ -406,7 +397,7 @@
406
397
  function enhance(thread) {
407
398
  if (thread.__ncAutoplayPlayer) return thread.__ncAutoplayPlayer;
408
399
  var player = new ChatThreadPlayer(thread);
409
- // Read the M5 stagger token off the live thread (parity with motion.css);
400
+ // Read the stagger token off the live thread (parity with motion.css);
410
401
  // fallback equals the motion.css default (160ms) if the bundle is absent.
411
402
  player.staggerMs = durationToken(thread, "--nc-duration-stagger", 160);
412
403
  thread.__ncAutoplayPlayer = player;
@@ -477,7 +468,7 @@
477
468
  for (var j = 0; j < players.length; j++) observer.observe(players[j].thread);
478
469
  }
479
470
 
480
- // ── Settle module — enhancer-armed, run-once scroll entrance ─────────────
471
+ // ── Enhancer-armed, run-once scroll entrance ─────────────────────────────
481
472
  // Arms .nc-settle elements that are fully below the viewport at init.
482
473
  // On first IntersectionObserver entry, switches data-nc-settle from "armed"
483
474
  // to "in" (triggers the CSS nc-msg-in animation) and immediately unobserves