@neuromatch/course-kit 0.1.2 → 0.1.3

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.
package/README.md CHANGED
@@ -61,8 +61,12 @@ nma:
61
61
  pyodide_url: https://cdn.jsdelivr.net/pyodide/v314.0.7/full/
62
62
  ```
63
63
 
64
- One rule belongs in the course's own CSS, because a plugin can't add
65
- site-wide CSS: `.myst-jp-nb-toolbar { display: none !important; }`.
64
+ A plugin can't add site-wide CSS, so the Neuromatch look (colours, Rubik font,
65
+ logos, favicon, and the rule that hides JupyterLite's toolbar) comes from the
66
+ `nma-kit sync-assets` command in the PyPI package instead. It writes `_nma/`,
67
+ which the course's `myst.yml` lists under `site.options` (`style`, `logo`,
68
+ `logo_dark`, `favicon`). See the
69
+ [kit README](https://github.com/neuromatch/course-kit#site-branding).
66
70
 
67
71
  ## What's in the package
68
72
 
@@ -1,6 +1,7 @@
1
1
  /* Editable cell panel (in each panel's shadow root).
2
2
  Layout: header, editor, action bar, output. Colours follow the site theme.
3
- Public tokens, set on :root / html.dark in _static/custom.css:
3
+ Public tokens, set on :root / html.dark in the kit stylesheet (python/src/nma_kit/assets/site.css);
4
+ a course overrides them in its own CSS (nma.style.extra):
4
5
  --nma-cell-{bg,fg}-{light,dark}, --nma-cell-head-{bg,fg}-{light,dark},
5
6
  --nma-cell-bar-bg-{light,dark}, --nma-cell-out-bg-{light,dark},
6
7
  --nma-cell-gutter-{bg,fg}-{light,dark}, --nma-cell-active-line-{light,dark},
@@ -2,7 +2,7 @@
2
2
  .nma-cells-runtime { display: none; }
3
3
 
4
4
  /* Floating "Run all" control (runtime-widget.mjs). Brand-coloured via the theme
5
- variables set in _static/custom.css, with safe fallbacks. */
5
+ variables set in the kit stylesheet (site.css), with safe fallbacks. */
6
6
  .nma-run-all-bar {
7
7
  position: fixed;
8
8
  right: 1rem;
@@ -11,14 +11,14 @@
11
11
 
12
12
  const STYLE = `
13
13
  .hud { position: absolute; top: 0; left: 0; right: 0; display: flex; align-items: center; gap: 16px; padding: 14px 28px; pointer-events: none; font-family: var(--nm-font-head, system-ui, sans-serif); }
14
- .sec { font-weight: 600; font-size: 0.78rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--nm-mint, #5efbd7); min-width: 12ch; }
15
- .bar { flex: 1; height: 3px; background: rgba(255,255,255,0.14); border-radius: 3px; overflow: hidden; }
16
- .bar i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--nm-salmon, #fb7a7a), var(--nm-mint, #5efbd7)); transition: width 0.4s; }
14
+ .sec { font-weight: 600; font-size: 0.78rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--sc-accent, #008cbf); min-width: 12ch; }
15
+ .bar { flex: 1; height: 3px; background: var(--sc-track, rgba(26,26,26,0.12)); border-radius: 3px; overflow: hidden; }
16
+ .bar i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--sc-warm, #fa7a7a), var(--sc-accent, #008cbf)); transition: width 0.4s; }
17
17
  .py[hidden] { display: none; }
18
- .py { pointer-events: auto; flex: none; font: 600 0.74rem var(--nm-font-head, system-ui, sans-serif); letter-spacing: 0.04em; border: 1px solid var(--nm-mint, #5efbd7); border-radius: 999px; padding: 0.3rem 0.85rem; cursor: pointer; max-width: 34ch; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: var(--nm-mint, #5efbd7); color: var(--nm-indigo, #2a2952); }
19
- .py[data-state="loading"] { background: transparent; color: var(--nm-mint, #5efbd7); cursor: progress; }
20
- .py[data-state="ready"] { background: transparent; color: var(--nm-mint, #5efbd7); cursor: default; }
21
- .py[data-state="error"] { background: var(--nm-salmon, #fb7a7a); border-color: var(--nm-salmon, #fb7a7a); }
18
+ .py { pointer-events: auto; flex: none; font: 600 0.74rem var(--nm-font-head, system-ui, sans-serif); letter-spacing: 0.04em; border: 1px solid var(--sc-accent, #008cbf); border-radius: 999px; padding: 0.3rem 0.85rem; cursor: pointer; max-width: 34ch; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: var(--sc-accent, #008cbf); color: var(--sc-accent-fg, #fff); }
19
+ .py[data-state="loading"] { background: transparent; color: var(--sc-accent, #008cbf); cursor: progress; }
20
+ .py[data-state="ready"] { background: transparent; color: var(--sc-accent, #008cbf); cursor: default; }
21
+ .py[data-state="error"] { background: var(--sc-warm, #fa7a7a); border-color: var(--sc-warm, #fa7a7a); color: #1a1a1a; }
22
22
  `;
23
23
 
24
24
  // Section width (px) from which the stage sits beside the cards.
@@ -1,27 +1,28 @@
1
1
  /* Runnable Python panel (inside the widget's shadow DOM).
2
- Colours come from the --nm-* variables set on .scrolly in scrolly.css. */
2
+ Colours come from the --sc-* variables set on .scrolly in scrolly.css (they
3
+ inherit into the shadow DOM and switch with the site's light/dark mode). */
3
4
  :host { display: block; width: 100%; }
4
5
  * { box-sizing: border-box; }
5
6
  [hidden] { display: none !important; }
6
7
 
7
8
  .fl-codebox {
8
9
  width: 100%;
9
- background: #14131f;
10
- border: 1px solid rgba(185, 184, 255, 0.28);
10
+ background: var(--sc-code-bg);
11
+ border: 1px solid var(--sc-line);
11
12
  border-radius: 12px;
12
13
  overflow: hidden;
13
- box-shadow: 0 12px 34px rgba(8, 7, 30, 0.5);
14
- color: #ecebff;
14
+ box-shadow: var(--sc-shadow);
15
+ color: var(--sc-code-text);
15
16
  font-family: var(--nm-font-body, system-ui, sans-serif);
16
17
  text-align: left;
17
18
  }
18
- .fl-codehead { display: flex; justify-content: space-between; padding: 0.45rem 1rem; background: #22214a; font: 600 0.72rem var(--nm-font-head, system-ui, sans-serif); letter-spacing: 0.1em; text-transform: uppercase; color: var(--nm-lilac, #b9b8ff); }
19
+ .fl-codehead { display: flex; justify-content: space-between; padding: 0.45rem 1rem; background: var(--sc-code-bar); border-bottom: 1px solid var(--sc-line); font: 600 0.72rem var(--nm-font-head, system-ui, sans-serif); letter-spacing: 0.1em; text-transform: uppercase; color: var(--sc-code-head-fg); }
19
20
 
20
- .fl-params { display: flex; flex-wrap: wrap; gap: 0.4rem 1.4rem; padding: 0.55rem 1rem; background: #1b1a36; border-bottom: 1px solid rgba(185, 184, 255, 0.2); }
21
- .fl-params label { display: flex; align-items: center; gap: 0.5rem; font: 600 0.8rem ui-monospace, Consolas, monospace; color: var(--nm-lilac, #b9b8ff); }
22
- .fl-params input[type=range] { width: 9rem; accent-color: var(--nm-mint, #5efbd7); }
23
- .fl-params output { min-width: 4ch; color: var(--nm-mint, #5efbd7); text-align: right; }
24
- .fl-params select { font: inherit; background: #14131f; color: var(--nm-mint, #5efbd7); border: 1px solid rgba(185, 184, 255, 0.4); border-radius: 6px; padding: 0.15rem 0.4rem; }
21
+ .fl-params { display: flex; flex-wrap: wrap; gap: 0.4rem 1.4rem; padding: 0.55rem 1rem; background: var(--sc-code-bar); border-bottom: 1px solid var(--sc-line); }
22
+ .fl-params label { display: flex; align-items: center; gap: 0.5rem; font: 600 0.8rem ui-monospace, Consolas, monospace; color: var(--sc-code-head-fg); }
23
+ .fl-params input[type=range] { width: 9rem; accent-color: var(--sc-accent); }
24
+ .fl-params output { min-width: 4ch; color: var(--sc-accent); text-align: right; }
25
+ .fl-params select { font: inherit; background: var(--sc-code-bg); color: var(--sc-accent); border: 1px solid var(--sc-line); border-radius: 6px; padding: 0.15rem 0.4rem; }
25
26
 
26
27
  .fl-editor { position: relative; max-height: 46vh; overflow: auto; }
27
28
  .fl-editor .fl-hl, .fl-editor .fl-ta {
@@ -31,37 +32,37 @@
31
32
  white-space: pre;
32
33
  tab-size: 4;
33
34
  }
34
- .fl-editor .fl-hl { color: #ecebff; overflow: hidden; pointer-events: none; }
35
+ .fl-editor .fl-hl { color: var(--sc-code-text); overflow: hidden; pointer-events: none; }
35
36
  .fl-editor .fl-ta {
36
37
  position: absolute; inset: 0; width: 100%; height: 100%;
37
- color: transparent; caret-color: var(--nm-mint, #5efbd7); background: transparent; border: 0; outline: 0; resize: none; overflow: hidden;
38
+ color: transparent; caret-color: var(--sc-accent); background: transparent; border: 0; outline: 0; resize: none; overflow: hidden;
38
39
  }
39
- .fl-editor .fl-ta::selection { background: rgba(94, 251, 215, 0.28); }
40
- .fl-editor:focus-within { box-shadow: inset 0 0 0 2px rgba(94, 251, 215, 0.55); }
40
+ .fl-editor .fl-ta::selection { background: color-mix(in srgb, var(--sc-accent) 30%, transparent); }
41
+ .fl-editor:focus-within { box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--sc-accent) 55%, transparent); }
41
42
 
42
- .fl-actions { display: flex; align-items: center; gap: 0.6rem; padding: 0.45rem 1rem; background: #1b1a36; border-top: 1px solid rgba(185, 184, 255, 0.2); }
43
+ .fl-actions { display: flex; align-items: center; gap: 0.6rem; padding: 0.45rem 1rem; background: var(--sc-code-bar); border-top: 1px solid var(--sc-line); }
43
44
  .mode-output .fl-actions { border-top: 0; background: transparent; padding: 0.35rem 0.6rem; }
44
45
  .fl-actions button { font: 600 0.78rem var(--nm-font-head, system-ui, sans-serif); border: 0; border-radius: 999px; padding: 0.3rem 0.95rem; cursor: pointer; }
45
- .fl-run { background: var(--nm-mint, #5efbd7); color: var(--nm-indigo, #2a2952); }
46
+ .fl-run { background: var(--sc-accent); color: var(--sc-accent-fg); }
46
47
  .fl-run:disabled { opacity: 0.55; cursor: progress; }
47
- .fl-reset, .fl-toggle { background: transparent; color: var(--nm-lilac, #b9b8ff); border: 1px solid rgba(185, 184, 255, 0.5) !important; }
48
- .fl-status { font-size: 0.76rem; color: var(--nm-muted, #b4b3e6); }
48
+ .fl-reset, .fl-toggle { background: transparent; color: var(--sc-code-text); border: 1px solid var(--sc-line) !important; }
49
+ .fl-status { font-size: 0.76rem; color: var(--sc-muted); }
49
50
 
50
- .fl-out { border-top: 1px solid rgba(185, 184, 255, 0.2); background: #0e0d18; padding: 0.55rem 1.1rem 0.75rem; }
51
+ .fl-out { border-top: 1px solid var(--sc-line); background: var(--sc-code-out); padding: 0.55rem 1.1rem 0.75rem; }
51
52
  .mode-output .fl-out { border-top: 0; }
52
- .fl-out pre { margin: 0.25rem 0 0; font: 0.84rem/1.55 ui-monospace, "Cascadia Code", Consolas, monospace; color: #c9f5ea; white-space: pre-wrap; max-height: 30vh; overflow: auto; }
53
+ .fl-out pre { margin: 0.25rem 0 0; font: 0.84rem/1.55 ui-monospace, "Cascadia Code", Consolas, monospace; color: var(--sc-code-text); white-space: pre-wrap; max-height: 30vh; overflow: auto; }
53
54
  .fl-figs img { display: block; max-width: 100%; max-height: 48vh; margin: 0.5rem auto 0; border-radius: 8px; background: #fff; }
54
- .fl-err { color: var(--nm-salmon, #fb7a7a); font-size: 0.86rem; margin-top: 0.3rem; }
55
- .fl-err details { margin-top: 0.25rem; color: var(--nm-muted, #b4b3e6); }
56
- .fl-err pre { font: 0.74rem/1.5 ui-monospace, Consolas, monospace; color: #f5c1c1; }
57
- .fl-note { margin: 0 0 0.3rem; font-size: 0.78rem; color: var(--nm-salmon, #fb7a7a); }
58
- .fl-empty { margin: 0; font-size: 0.8rem; color: var(--nm-muted, #b4b3e6); font-style: italic; }
55
+ .fl-err { color: var(--sc-warm-text); font-size: 0.86rem; margin-top: 0.3rem; }
56
+ .fl-err details { margin-top: 0.25rem; color: var(--sc-muted); }
57
+ .fl-err pre { font: 0.74rem/1.5 ui-monospace, Consolas, monospace; color: var(--sc-warm-text); }
58
+ .fl-note { margin: 0 0 0.3rem; font-size: 0.78rem; color: var(--sc-warm-text); }
59
+ .fl-empty { margin: 0; font-size: 0.8rem; color: var(--sc-muted); font-style: italic; }
59
60
 
60
- .tk-c { color: #8b8ac7; font-style: italic; }
61
- .tk-s { color: var(--nm-mint, #5efbd7); font-style: normal; }
62
- .tk-k { color: var(--nm-salmon, #fb7a7a); font-style: normal; }
63
- .tk-n { color: var(--nm-lilac, #b9b8ff); font-style: normal; }
64
- .tk-f { color: #7cc4ff; font-style: normal; }
65
- .tk-b { font-style: normal; color: #fff; background: rgba(251, 122, 122, 0.35); border-radius: 4px; }
61
+ .tk-c { color: var(--sc-tok-comment); font-style: italic; }
62
+ .tk-s { color: var(--sc-tok-string); font-style: normal; }
63
+ .tk-k { color: var(--sc-tok-keyword); font-style: normal; }
64
+ .tk-n { color: var(--sc-tok-number); font-style: normal; }
65
+ .tk-f { color: var(--sc-tok-function); font-style: normal; }
66
+ .tk-b { font-style: normal; color: inherit; background: color-mix(in srgb, var(--sc-warm) 30%, transparent); border-radius: 4px; }
66
67
 
67
68
  .is-collapsed .fl-editor { display: none; }
@@ -1,4 +1,4 @@
1
- /* Scrollytelling page layout (plugins/scrolly/).
1
+ /* Scrollytelling page layout and colours (js/src/scrolly/).
2
2
  Attached to the engine widget so MyST bundles it; engine.mjs copies it
3
3
  into <head>. Without JavaScript the page is a plain linear document; the
4
4
  pinned layout switches on when the engine sets data-ready.
@@ -26,28 +26,95 @@
26
26
  body:has(.myst-primary-sidebar.lg\:hidden) .article-grid:not(:has(> .lg\:col-margin-right)) > .scrolly-col { grid-column: screen-inset; }
27
27
  }
28
28
 
29
+ /* ---- colours ----
30
+ The section follows the site: light and dark mode (the theme's `.dark` class
31
+ on <html>), the brand colours from the kit stylesheet (--nma-brand-*, which a
32
+ course changes with `nma.brand`) and the kit's syntax colours (--nma-tok-*,
33
+ shared with the editable cells). The hex values are the Neuromatch defaults,
34
+ used when the kit stylesheet is not loaded. runnable.css and the HUD in
35
+ engine.mjs read the same --sc-* tokens through the shadow DOM. */
29
36
  .scrolly {
30
37
  --scrolly-top: 60px;
31
- --nm-indigo: #2a2952;
32
- --nm-indigo-deep: #1c1b3e;
33
- --nm-purple: #45429c;
34
- --nm-blue: #008cbf;
35
- --nm-salmon: #fa7a7a;
36
- --nm-mint: #5efbd7;
37
- --nm-lilac: #b9b8ff;
38
- --nm-cream: #f3f0ec;
39
- --nm-ink: #161922;
40
- --nm-muted: #b4b3e6;
41
- --nm-text: #f3f0ec;
38
+ --sc-primary: var(--nma-brand-primary, #008cbf);
39
+ --sc-primary-light: var(--nma-brand-primary-light, #35b4dc);
40
+ --sc-secondary: var(--nma-brand-secondary, #45429c);
41
+ --sc-warm: var(--nma-brand-accent, #fa7a7a);
42
+
43
+ --sc-bg: #f7f8fa;
44
+ --sc-text: #1a1a1a;
45
+ --sc-muted: #7a7a7a;
46
+ --sc-line: #e6e6e6;
47
+ --sc-heading: var(--sc-secondary);
48
+ --sc-title: var(--sc-secondary);
49
+ --sc-link: var(--sc-primary);
50
+ --sc-accent: var(--sc-primary);
51
+ --sc-accent-fg: #ffffff;
52
+ --sc-warm-text: color-mix(in srgb, var(--sc-warm) 60%, #1a1a1a);
53
+ --sc-glow-1: color-mix(in srgb, var(--sc-secondary) 10%, transparent);
54
+ --sc-glow-2: color-mix(in srgb, var(--sc-primary) 12%, transparent);
55
+ --sc-track: rgba(26, 26, 26, 0.12);
56
+ --sc-chip-bg: color-mix(in srgb, var(--sc-primary) 6%, #ffffff);
57
+ --sc-chip-line: color-mix(in srgb, var(--sc-primary) 28%, transparent);
58
+
59
+ --sc-card-bg: #ffffff;
60
+ --sc-card-text: #1a1a1a;
61
+ --sc-card-code: color-mix(in srgb, var(--sc-primary) 10%, #ffffff);
62
+ --sc-shadow: 0 10px 30px rgba(26, 26, 26, 0.1);
63
+
64
+ --sc-code-bg: #ffffff;
65
+ --sc-code-bar: #f7f8fa;
66
+ --sc-code-out: #f7f8fa;
67
+ --sc-code-text: #1a1a1a;
68
+ --sc-code-head-fg: var(--sc-secondary);
69
+ --sc-tok-comment: var(--nma-tok-comment-light, #7a7a7a);
70
+ --sc-tok-string: var(--nma-tok-string-light, #0e7c86);
71
+ --sc-tok-keyword: var(--nma-tok-keyword-light, #45429c);
72
+ --sc-tok-number: var(--nma-tok-number-light, #b5484b);
73
+ --sc-tok-function: var(--nma-tok-function-light, #006b8f);
74
+
42
75
  --nm-font-body: inherit;
43
76
  --nm-font-head: inherit;
44
77
  position: relative;
45
78
  margin-block: 1.5rem;
46
- color: var(--nm-text);
47
- background: var(--nm-indigo-deep);
79
+ color: var(--sc-text);
80
+ background: var(--sc-bg);
81
+ border: 1px solid var(--sc-line);
48
82
  border-radius: 12px;
49
83
  padding: 1rem;
50
84
  }
85
+ .dark .scrolly {
86
+ --sc-bg: #232323;
87
+ --sc-text: #f7f8fa;
88
+ --sc-muted: #bdcfcf;
89
+ --sc-line: #3a3a3a;
90
+ --sc-heading: var(--nma-tok-keyword-dark, #b9b8ff);
91
+ --sc-title: #f7f8fa;
92
+ --sc-link: var(--sc-primary-light);
93
+ --sc-accent: var(--sc-primary-light);
94
+ --sc-accent-fg: #14131f;
95
+ --sc-warm-text: color-mix(in srgb, var(--sc-warm) 75%, #ffffff);
96
+ --sc-glow-1: color-mix(in srgb, var(--sc-secondary) 45%, transparent);
97
+ --sc-glow-2: color-mix(in srgb, var(--sc-primary) 18%, transparent);
98
+ --sc-track: rgba(255, 255, 255, 0.14);
99
+ --sc-chip-bg: rgba(255, 255, 255, 0.05);
100
+ --sc-chip-line: color-mix(in srgb, var(--sc-primary-light) 30%, transparent);
101
+
102
+ --sc-card-bg: #2e2e2e;
103
+ --sc-card-text: #f7f8fa;
104
+ --sc-card-code: rgba(255, 255, 255, 0.1);
105
+ --sc-shadow: 0 14px 40px rgba(0, 0, 0, 0.45);
106
+
107
+ --sc-code-bg: #1b1b1b;
108
+ --sc-code-bar: #262626;
109
+ --sc-code-out: #151515;
110
+ --sc-code-text: #e6e6e6;
111
+ --sc-code-head-fg: #bdcfcf;
112
+ --sc-tok-comment: var(--nma-tok-comment-dark, #9aa7a7);
113
+ --sc-tok-string: var(--nma-tok-string-dark, #5efbd7);
114
+ --sc-tok-keyword: var(--nma-tok-keyword-dark, #b9b8ff);
115
+ --sc-tok-number: var(--nma-tok-number-dark, #ff9e9e);
116
+ --sc-tok-function: var(--nma-tok-function-dark, #5ec8ec);
117
+ }
51
118
  .scrolly *, .scrolly *::before, .scrolly *::after { box-sizing: border-box; }
52
119
  .scrolly-engine { display: block; }
53
120
  .scrolly-stage { margin-bottom: 1.5rem; }
@@ -77,8 +144,8 @@ body:has(.scrolly) .myst-jp-nb-toolbar-power { display: none !important; }
77
144
  z-index: 0;
78
145
  border-radius: 12px;
79
146
  background:
80
- radial-gradient(ellipse 60% 50% at 78% 20%, rgba(68, 67, 156, 0.55), transparent 70%),
81
- radial-gradient(ellipse 40% 40% at 10% 95%, rgba(0, 137, 247, 0.16), transparent 70%);
147
+ radial-gradient(ellipse 60% 50% at 78% 20%, var(--sc-glow-1), transparent 70%),
148
+ radial-gradient(ellipse 40% 40% at 10% 95%, var(--sc-glow-2), transparent 70%);
82
149
  }
83
150
  .scrolly[data-ready="true"] .scrolly-view {
84
151
  position: absolute;
@@ -104,59 +171,60 @@ body:has(.scrolly) .myst-jp-nb-toolbar-power { display: none !important; }
104
171
  pointer-events: auto;
105
172
  max-width: 32rem;
106
173
  min-width: 0; /* flex item in .scrolly-step: don't grow to the widest code line */
107
- background: var(--nm-cream);
108
- color: var(--nm-ink);
174
+ background: var(--sc-card-bg);
175
+ color: var(--sc-card-text);
176
+ border: 1px solid var(--sc-line);
109
177
  border-radius: 14px;
110
- border-left: 6px solid var(--nm-salmon);
178
+ border-left: 6px solid var(--sc-warm);
111
179
  padding: 1.1rem 1.35rem 1.25rem;
112
- box-shadow: 0 14px 40px rgba(8, 7, 30, 0.45);
180
+ box-shadow: var(--sc-shadow);
113
181
  line-height: 1.6;
114
182
  }
115
183
  .scrolly[data-ready="true"] .scrolly-card { opacity: 0.32; transform: translateX(-10px) scale(0.985); transition: opacity 0.35s, transform 0.35s; }
116
184
  .scrolly[data-ready="true"] .scrolly-step.is-active .scrolly-card { opacity: 1; transform: none; }
117
185
  .scrolly-card > :first-child { margin-top: 0; }
118
186
  .scrolly-card > :last-child { margin-bottom: 0; }
119
- .scrolly-card :is(h1, h2, h3, h4, h5, h6) { display: block; border: 0; padding: 0; margin: 0.2rem 0 0.45rem; font-weight: 600; font-size: 1.35rem; line-height: 1.2; color: var(--nm-indigo); }
187
+ .scrolly-card :is(h1, h2, h3, h4, h5, h6) { display: block; border: 0; padding: 0; margin: 0.2rem 0 0.45rem; font-weight: 600; font-size: 1.35rem; line-height: 1.2; color: var(--sc-heading); }
120
188
  .scrolly-card p { margin: 0 0 0.6rem; font-size: 1rem; }
121
- .scrolly-card :is(p, li, strong, em, span, b, i, td, th) { color: var(--nm-ink); }
122
- .scrolly-card code { background: #e4e0f7; color: var(--nm-indigo); padding: 0.05em 0.4em; border-radius: 5px; font-size: 0.88em; }
123
- .scrolly-card a { color: var(--nm-purple); }
189
+ .scrolly-card :is(p, li, strong, em, span, b, i, td, th) { color: var(--sc-card-text); }
190
+ .scrolly-card code { background: var(--sc-card-code); color: var(--sc-heading); padding: 0.05em 0.4em; border-radius: 5px; font-size: 0.88em; }
191
+ .scrolly-card a { color: var(--sc-link); }
124
192
  .scrolly-card .katex-display { overflow-x: auto; overflow-y: hidden; }
125
193
  .scrolly-card details { margin: 0.5rem 0; }
126
194
  .scrolly-card pre { max-width: 100%; overflow-x: auto; }
127
195
  .scrolly-card .nma-solution-link p { margin: 0.4rem 0; }
128
196
  .scrolly-kicker { margin: 0 0 0.1rem; }
129
- .scrolly-kicker p { margin: 0; font-weight: 600; font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--nm-purple) !important; }
197
+ .scrolly-kicker p { margin: 0; font-weight: 600; font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--sc-heading) !important; }
130
198
 
131
199
  /* ---- stage content ---- */
132
- .scrolly-view { color: var(--nm-text); }
200
+ .scrolly-view { color: var(--sc-text); }
133
201
  .scrolly-view :is(p, li, strong, em, span) { color: inherit; }
134
- .scrolly-view :is(h1, h2, h3, h4) { display: block; border: 0; padding: 0; color: #fff; }
135
- .scrolly-view a { color: var(--nm-mint); }
136
- .scrolly-view img { max-width: 100%; max-height: 70vh; width: auto; height: auto; border-radius: 10px; background: #fff; margin: 0 auto; display: block; }
202
+ .scrolly-view :is(h1, h2, h3, h4) { display: block; border: 0; padding: 0; color: var(--sc-title); }
203
+ .scrolly-view a { color: var(--sc-link); }
204
+ .scrolly-view img { max-width: 100%; max-height: 70vh; width: auto; height: auto; border-radius: 10px; background: #fff; border: 1px solid var(--sc-line); margin: 0 auto; display: block; }
137
205
  .scrolly-view video { max-width: 100%; max-height: 70vh; border-radius: 10px; margin: 0 auto; display: block; }
138
206
  .scrolly-view figure { margin: 0; }
139
- .scrolly-view figcaption, .scrolly-view figcaption * { color: var(--nm-muted); }
207
+ .scrolly-view figcaption, .scrolly-view figcaption * { color: var(--sc-muted); }
140
208
  .scrolly-view iframe { width: 100%; aspect-ratio: 16 / 9; height: auto; border: 0; border-radius: 10px; background: #000; }
141
209
  .scrolly-view .nma-video p, .scrolly-view .nma-slides p { margin: 0.3rem 0; font-size: 0.85rem; }
142
- .scrolly-view .nma-video [role="tab"] { color: var(--nm-lilac); }
210
+ .scrolly-view .nma-video [role="tab"] { color: var(--sc-link); }
143
211
  .scrolly-view .scrolly-runnable { width: 100%; }
144
212
  .scrolly-view.is-list ol, .scrolly-view.is-list ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.75rem; counter-reset: chip; }
145
- .scrolly-view.is-list li { counter-increment: chip; display: grid; grid-template-columns: 2.6rem 1fr; align-items: center; gap: 0.9rem; font-size: 1.05rem; line-height: 1.45; background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(185, 184, 255, 0.2); border-radius: 12px; padding: 0.75rem 1rem; margin: 0; }
146
- .scrolly-view.is-list li::before { content: counter(chip); display: grid; place-items: center; width: 2.6rem; height: 2.6rem; border-radius: 50%; background: var(--nm-mint); color: var(--nm-indigo); font-weight: 700; font-size: 1.1rem; }
213
+ .scrolly-view.is-list li { counter-increment: chip; display: grid; grid-template-columns: 2.6rem 1fr; align-items: center; gap: 0.9rem; font-size: 1.05rem; line-height: 1.45; background: var(--sc-chip-bg); border: 1px solid var(--sc-chip-line); border-radius: 12px; padding: 0.75rem 1rem; margin: 0; }
214
+ .scrolly-view.is-list li::before { content: counter(chip); display: grid; place-items: center; width: 2.6rem; height: 2.6rem; border-radius: 50%; background: var(--sc-accent); color: var(--sc-accent-fg); font-weight: 700; font-size: 1.1rem; }
147
215
  .scrolly-view.is-list li > p { margin: 0; }
148
216
  .scrolly-view.is-list :is(h2, h3, h4) { margin: 0 0 0.5rem; font-size: clamp(1.4rem, 4cqi, 2.2rem); font-weight: 700; }
149
217
 
150
218
  /* ---- hero (title and closing screens) ----
151
219
  MyST re-levels headings, so the title is styled by position, not by tag. */
152
220
  .scrolly-view.is-hero { max-width: 72rem; margin-inline: auto; padding: 0 clamp(0.5rem, 5cqi, 4rem); }
153
- .scrolly-view.is-hero .scrolly-kicker p { font-size: 0.85rem; letter-spacing: 0.32em; color: var(--nm-mint) !important; margin-bottom: 0.6rem; }
221
+ .scrolly-view.is-hero .scrolly-kicker p { font-size: 0.85rem; letter-spacing: 0.32em; color: var(--sc-accent) !important; margin-bottom: 0.6rem; }
154
222
  .scrolly-view.is-hero :is(h1, h2, h3, h4, h5, h6) { display: block; margin: 0; padding: 0; border: 0; }
155
- .scrolly-view.is-hero :is(h1, h2, h3, h4, h5, h6):not(:is(h1, h2, h3, h4, h5, h6) ~ *) { font-weight: 700; font-size: clamp(2rem, 8cqi, 4.6rem); line-height: 1.05; color: #fff; }
156
- .scrolly-view.is-hero :is(h1, h2, h3, h4, h5, h6) ~ :is(h1, h2, h3, h4, h5, h6) { font-weight: 500; font-size: 1.15rem; color: var(--nm-lilac); margin: 0.9rem 0 0.3rem; }
157
- .scrolly-view.is-hero :is(h1, h2, h3, h4, h5, h6) em { font-style: normal; background: linear-gradient(90deg, var(--nm-salmon), var(--nm-mint)); -webkit-background-clip: text; background-clip: text; color: transparent; }
223
+ .scrolly-view.is-hero :is(h1, h2, h3, h4, h5, h6):not(:is(h1, h2, h3, h4, h5, h6) ~ *) { font-weight: 700; font-size: clamp(2rem, 8cqi, 4.6rem); line-height: 1.05; color: var(--sc-title); }
224
+ .scrolly-view.is-hero :is(h1, h2, h3, h4, h5, h6) ~ :is(h1, h2, h3, h4, h5, h6) { font-weight: 500; font-size: 1.15rem; color: var(--sc-link); margin: 0.9rem 0 0.3rem; }
225
+ .scrolly-view.is-hero :is(h1, h2, h3, h4, h5, h6) em { font-style: normal; background: linear-gradient(90deg, var(--sc-warm), var(--sc-accent)); -webkit-background-clip: text; background-clip: text; color: transparent; }
158
226
  .scrolly-view.is-hero p { margin: 0.5rem 0; font-size: 0.98rem; line-height: 1.5; max-width: 52rem; }
159
- .scrolly-view.is-hero p strong { color: var(--nm-salmon); }
227
+ .scrolly-view.is-hero p strong { color: var(--sc-warm-text); }
160
228
 
161
229
  /* ---- narrow sections: stage on top, cards below it ----
162
230
  Keep the 760px breakpoint in sync with WIDE in engine.mjs. */
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "mode": "release",
3
- "version": "0.1.2"
3
+ "version": "0.1.3"
4
4
  }
package/dist/nma.mjs CHANGED
@@ -1,4 +1,4 @@
1
- // @neuromatch/course-kit 0.1.2 MyST plugin (release build). GENERATED, do not edit.
1
+ // @neuromatch/course-kit 0.1.3 MyST plugin (release build). GENERATED, do not edit.
2
2
  import { createRequire as __nmaCreateRequire } from 'node:module';
3
3
  const require = __nmaCreateRequire(import.meta.url);
4
4
  var __create = Object.create;
@@ -7645,7 +7645,7 @@ import { readFileSync as readFileSync2 } from "node:fs";
7645
7645
  // src/shared/assets.mjs
7646
7646
  import { dirname, join as join2, relative as relative2, sep as sep2 } from "node:path";
7647
7647
  import { fileURLToPath } from "node:url";
7648
- var BASE = true ? "https://cdn.jsdelivr.net/npm/@neuromatch/course-kit@0.1.2/dist/assets/" : null;
7648
+ var BASE = true ? "https://cdn.jsdelivr.net/npm/@neuromatch/course-kit@0.1.3/dist/assets/" : null;
7649
7649
  var BUNDLED = true;
7650
7650
  function assetsDir() {
7651
7651
  const here = dirname(fileURLToPath(import.meta.url));
package/dist/nma.yml CHANGED
@@ -1,4 +1,4 @@
1
- # Course kit 0.1.2. Courses add this file with
1
+ # Course kit 0.1.3. Courses add this file with
2
2
  # extend: https://cdn.jsdelivr.net/npm/@neuromatch/course-kit@0.1/dist/nma.yml
3
3
  # and `nma-kit prepare-site` pins that URL to the CLI's exact version on CI.
4
4
  version: 1
@@ -6,4 +6,4 @@ project:
6
6
  jupyter:
7
7
  lite: true
8
8
  plugins:
9
- - https://cdn.jsdelivr.net/npm/@neuromatch/course-kit@0.1.2/dist/nma.mjs
9
+ - https://cdn.jsdelivr.net/npm/@neuromatch/course-kit@0.1.3/dist/nma.mjs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neuromatch/course-kit",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Neuromatch course kit: MyST plugins for Neuromatch courses",
5
5
  "repository": {
6
6
  "type": "git",