thibaud frere commited on
Commit
8e480d5
·
1 Parent(s): f29f914

update colors, fix layout

Browse files
app/src/content/chapters/available-blocks.mdx CHANGED
@@ -380,6 +380,7 @@ You can fetch them with this address: **`[domain]/data/your-data.ext`**
380
  Here are some real world examples to inspire you.
381
 
382
  <HtmlEmbed src="d3-line.html" title="Training curves by metric" desc="Interactive time series across runs. Choose a metric; hover for values." />
 
383
  ---
384
  <HtmlEmbed src="d3-bar.html" title="D3 Memory usage with recomputation" desc={`Memory usage with recomputation — <a href="https://huggingface.co/spaces/nanotron/ultrascale-playbook?section=activation_recomputation" target="_blank">from the ultrascale playbook</a>`}/>
385
  ---
 
380
  Here are some real world examples to inspire you.
381
 
382
  <HtmlEmbed src="d3-line.html" title="Training curves by metric" desc="Interactive time series across runs. Choose a metric; hover for values." />
383
+ <HtmlEmbed src="d3-line-example.html" title="Training curves by metric" desc="Interactive time series across runs. Choose a metric; hover for values." />
384
  ---
385
  <HtmlEmbed src="d3-bar.html" title="D3 Memory usage with recomputation" desc={`Memory usage with recomputation — <a href="https://huggingface.co/spaces/nanotron/ultrascale-playbook?section=activation_recomputation" target="_blank">from the ultrascale playbook</a>`}/>
386
  ---
app/src/content/chapters/writing-your-content.mdx CHANGED
@@ -15,8 +15,8 @@ Your **article** lives in **one place**
15
 
16
  Everything is **self-contained** under `app/src/content/`:
17
  - **MDX**: `article.mdx` and [**optional chapters**](#chapters) in `chapters/`
18
- - **Assets**: `assets/` (**images**, **audios**, **datas**, etc.) tracked via **Git LFS**)
19
- - **Embeds**: `embed/` ([**HtmlEmbed**](#htmlembed) for **Plotly/D3**, etc.)
20
 
21
  The `article.mdx` file is the **main entry point** of your article.
22
 
 
15
 
16
  Everything is **self-contained** under `app/src/content/`:
17
  - **MDX**: `article.mdx` and [**optional chapters**](#chapters) in `chapters/`
18
+ - **Assets**: `assets/` **images**, **audios**, **datas**, etc. (tracked via **Git LFS**)
19
+ - **Embeds**: `embed/` [**HtmlEmbed**](#htmlembed) for **Plotly/D3**, etc.
20
 
21
  The `article.mdx` file is the **main entry point** of your article.
22
 
app/src/content/embeds/d3-line-example.html CHANGED
@@ -89,13 +89,29 @@
89
  };
90
 
91
  const bootstrap = () => {
92
- const mount = document.currentScript ? document.currentScript.previousElementSibling : null;
93
- const container = (mount && mount.querySelector && mount.querySelector('.d3-line')) || document.querySelector('.d3-line');
94
- if (!container) return;
95
- if (container.dataset) {
96
- if (container.dataset.mounted === 'true') return;
97
- container.dataset.mounted = 'true';
98
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
  // Dataset params matching the Plotly version
101
  const datasets = [
@@ -418,6 +434,7 @@
418
  window.addEventListener('resize', render);
419
  }
420
  render();
 
421
  };
422
 
423
  if (document.readyState === 'loading') {
 
89
  };
90
 
91
  const bootstrap = () => {
92
+ const scriptEl = document.currentScript;
93
+
94
+ const getLocalPrev = () => {
95
+ if (!scriptEl) return null;
96
+ let el = scriptEl.previousElementSibling;
97
+ while (el && !(el.classList && el.classList.contains('d3-line'))) {
98
+ el = el.previousElementSibling;
99
+ }
100
+ return el || null;
101
+ };
102
+
103
+ const localTarget = getLocalPrev();
104
+ const targets = localTarget
105
+ ? [localTarget]
106
+ : Array.from(document.querySelectorAll('.d3-line'))
107
+ .filter((el) => !(el.dataset && el.dataset.mounted === 'true'));
108
+
109
+ targets.forEach((container) => {
110
+ if (!container) return;
111
+ if (container.dataset) {
112
+ if (container.dataset.mounted === 'true') return;
113
+ container.dataset.mounted = 'true';
114
+ }
115
 
116
  // Dataset params matching the Plotly version
117
  const datasets = [
 
434
  window.addEventListener('resize', render);
435
  }
436
  render();
437
+ });
438
  };
439
 
440
  if (document.readyState === 'loading') {
app/src/content/embeds/palettes.html CHANGED
@@ -1,11 +1,14 @@
1
  <div class="palettes" style="width:100%; margin: 10px 0;">
2
  <style>
3
- .palettes .palettes__grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
4
- .palettes .palette-card { position: relative; display: grid; grid-template-columns: auto 1fr 260px; align-items: stretch; gap: 14px; border: 1px solid var(--border-color); border-radius: 10px; background: var(--surface-bg); padding: 12px; transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease; }
 
5
  /* removed circular badge */
6
- .palettes .palette-card__swatches { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); grid-auto-rows: 1fr; gap: 8px; margin: 0; min-height: 20px; }
7
- .palettes .palette-card__swatches .sw { width: 100%; min-width: 0; min-height: 0; border-radius: 8px; border: 1px solid var(--border-color); }
8
- .palettes .palette-card__content { display: flex; flex-direction: row; align-items: center; justify-content: center; gap: 6px; min-width: 0; padding-right: 24px; border-right: 1px solid var(--border-color); }
 
 
9
  .palettes .palette-card__content__info { display: flex; flex-direction: column; }
10
  .palettes .palette-card__title { text-align: left; font-weight: 800; font-size: 15px; }
11
  .palettes .palette-card__desc { text-align: left; color: var(--muted-color); line-height: 1.5; font-size: 12px; }
@@ -17,9 +20,11 @@
17
  /* Simulation UI */
18
  .palettes .palettes__select { width: 100%; max-width: 100%; border: 1px solid var(--border-color); background: var(--surface-bg); color: var(--text-color); padding: 8px 10px; border-radius: 8px; }
19
  .palettes .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 1px, 1px); white-space: nowrap; border: 0; }
20
- .palettes .palettes__controls { display: flex; flex-wrap: nowrap; gap: 16px; align-items: center; margin: 8px 0 14px; }
21
- .palettes .palettes__field { display: flex; flex-direction: column; gap: 6px; min-width: 0; flex: 0 0 50%; max-width: 50%; }
22
  .palettes .palettes__label { font-size: 12px; color: var(--muted-color); font-weight: 800; }
 
 
23
  .palettes .palettes__count { display: flex; align-items: center; gap: 8px; max-width: 100%; }
24
  .palettes .palettes__count input[type="range"] { width: 100%; }
25
  .palettes .palettes__count output { min-width: 28px; text-align: center; font-variant-numeric: tabular-nums; font-size: 12px; color: var(--muted-color); }
@@ -59,10 +64,12 @@
59
  </select>
60
  </div>
61
  <div class="palettes__field">
62
- <label class="palettes__label" for="color-count">Number of colors</label>
 
 
 
63
  <div class="palettes__count">
64
  <input id="color-count" type="range" min="6" max="10" step="1" value="6" aria-label="Number of colors" />
65
- <output id="color-count-out" for="color-count">6</output>
66
  </div>
67
  </div>
68
  </div>
@@ -109,7 +116,7 @@
109
  };
110
 
111
  const cards = [
112
- { key: 'categorical', title: 'Categorical', desc: 'For <strong>non‑numeric categories</strong>; <strong>visually distinct</strong> colors.', generator: (baseHex, count) => {
113
  const base = chroma(baseHex);
114
  const lc = base.lch();
115
  const baseH = base.get('hsl.h') || 0;
@@ -195,15 +202,11 @@
195
  const c = chroma(baseHex).saturate(0.3);
196
  return chroma.scale([c.darken(2), c, c.brighten(2)]).mode('lab').correctLightness(true).colors(total);
197
  }},
198
- { key: 'diverging', title: 'Diverging', desc: 'For <strong>centered ranges</strong> with <strong>two extremes</strong> around a <strong>baseline</strong>. (e.g., negatives/positives)', generator: (baseHex, count) => {
199
  const total = Math.max(6, Math.min(10, count || 6));
200
- const h = chroma(baseHex).get('hsl.h');
201
- const baseH = Number.isFinite(h) ? h : 0;
202
- const compH = (baseH + 180) % 360;
203
- const left = chroma.hsl(baseH, 0.75, 0.55);
204
- const right = chroma.hsl(compH, 0.75, 0.55);
205
- const mid = chroma.mix(left, right, 0.5, 'lch');
206
- return chroma.scale([left, mid, right]).mode('lch').correctLightness(true).colors(total);
207
  }}
208
  ];
209
 
 
1
  <div class="palettes" style="width:100%; margin: 10px 0;">
2
  <style>
3
+ .palettes { box-sizing: border-box; overflow-x: hidden; }
4
+ .palettes .palettes__grid { display: grid; grid-template-columns: 1fr; gap: 12px; max-width: 100%; }
5
+ .palettes .palette-card { position: relative; display: grid; grid-template-columns: auto 1fr minmax(0, 220px); align-items: stretch; gap: 12px; border: 1px solid var(--border-color); border-radius: 10px; background: var(--surface-bg); padding: 12px; transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease; }
6
  /* removed circular badge */
7
+ .palettes .palette-card__swatches { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); grid-auto-rows: 1fr; gap: 2px; margin: 0; min-height: 20px; }
8
+ .palettes .palette-card__swatches .sw { width: 100%; min-width: 0; min-height: 0; border-radius: 0; border: 1px solid var(--border-color); }
9
+ .palettes .palette-card__swatches .sw:first-child { border-top-left-radius: 8px; border-bottom-left-radius: 8px; }
10
+ .palettes .palette-card__swatches .sw:last-child { border-top-right-radius: 8px; border-bottom-right-radius: 8px; }
11
+ .palettes .palette-card__content { display: flex; flex-direction: row; align-items: center; justify-content: center; gap: 6px; min-width: 0; padding-right: 16px; border-right: 1px solid var(--border-color); }
12
  .palettes .palette-card__content__info { display: flex; flex-direction: column; }
13
  .palettes .palette-card__title { text-align: left; font-weight: 800; font-size: 15px; }
14
  .palettes .palette-card__desc { text-align: left; color: var(--muted-color); line-height: 1.5; font-size: 12px; }
 
20
  /* Simulation UI */
21
  .palettes .palettes__select { width: 100%; max-width: 100%; border: 1px solid var(--border-color); background: var(--surface-bg); color: var(--text-color); padding: 8px 10px; border-radius: 8px; }
22
  .palettes .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 1px, 1px); white-space: nowrap; border: 0; }
23
+ .palettes .palettes__controls { display: flex; flex-wrap: wrap; gap: 16px; align-items: center; margin: 8px 0 14px; }
24
+ .palettes .palettes__field { display: flex; flex-direction: column; gap: 6px; min-width: 0; flex: 1 1 280px; max-width: 100%; }
25
  .palettes .palettes__label { font-size: 12px; color: var(--muted-color); font-weight: 800; }
26
+ .palettes .palettes__label-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
27
+ .palettes .ghost-badge { font-size: 11px; padding: 1px 6px; border-radius: 999px; border: 1px solid var(--border-color); color: var(--muted-color); background: transparent; font-variant-numeric: tabular-nums; }
28
  .palettes .palettes__count { display: flex; align-items: center; gap: 8px; max-width: 100%; }
29
  .palettes .palettes__count input[type="range"] { width: 100%; }
30
  .palettes .palettes__count output { min-width: 28px; text-align: center; font-variant-numeric: tabular-nums; font-size: 12px; color: var(--muted-color); }
 
64
  </select>
65
  </div>
66
  <div class="palettes__field">
67
+ <div class="palettes__label-row">
68
+ <label class="palettes__label" for="color-count">Number of colors</label>
69
+ <output id="color-count-out" for="color-count" class="ghost-badge">6</output>
70
+ </div>
71
  <div class="palettes__count">
72
  <input id="color-count" type="range" min="6" max="10" step="1" value="6" aria-label="Number of colors" />
 
73
  </div>
74
  </div>
75
  </div>
 
116
  };
117
 
118
  const cards = [
119
+ { key: 'categorical', title: 'Categorical', desc: 'For <strong>non‑numeric categories</strong>; <strong>visually distinct</strong> colors. The more you have the more likely they are to look similar.', generator: (baseHex, count) => {
120
  const base = chroma(baseHex);
121
  const lc = base.lch();
122
  const baseH = base.get('hsl.h') || 0;
 
202
  const c = chroma(baseHex).saturate(0.3);
203
  return chroma.scale([c.darken(2), c, c.brighten(2)]).mode('lab').correctLightness(true).colors(total);
204
  }},
205
+ { key: 'diverging', title: 'Diverging', desc: 'Opposing extremes via <strong>base white complement</strong>; smooth contrast around a neutral midpoint.', generator: (baseHex, count) => {
206
  const total = Math.max(6, Math.min(10, count || 6));
207
+ const comp = chroma(baseHex).set('hsl.h', '+180');
208
+ const bez = chroma.bezier([baseHex, '#ffffff', comp]);
209
+ return bez.scale().padding(-0.15).colors(total);
 
 
 
 
210
  }}
211
  ];
212
 
app/src/styles/_layout.css CHANGED
@@ -5,11 +5,24 @@
5
  --content-padding-x: 16px;
6
  }
7
 
8
- .content-grid { max-width: 1280px; margin: 0 auto; padding: 0 var(--content-padding-x); margin-top: 40px; display: grid; grid-template-columns: 220px minmax(0, 680px) 260px; gap: 32px; align-items: start; }
9
- .content-grid > main { max-width: 100%; margin: 0; padding: 0; }
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
  @media (max-width: 1100px) {
12
- .content-grid > main { overflow: hidden; }
13
  }
14
 
15
  /* TOC (left column) */
 
5
  --content-padding-x: 16px;
6
  }
7
 
8
+ .content-grid {
9
+ max-width: 1280px;
10
+ margin: 0 auto;
11
+ padding: 0 var(--content-padding-x);
12
+ margin-top: 40px;
13
+ display: grid;
14
+ grid-template-columns: 220px minmax(0, 680px) 260px;
15
+ gap: 32px;
16
+ align-items: start;
17
+ }
18
+
19
+ .content-grid > main { max-width: 100%;
20
+ margin: 0;
21
+ padding: 0;
22
+ }
23
 
24
  @media (max-width: 1100px) {
25
+ .content-grid { overflow: hidden; }
26
  }
27
 
28
  /* TOC (left column) */