Skip to content

Commit 575d2b5

Browse files
committed
Five layout variants derived from above + between
Following the impeccable/layout protocol — distinct structure, distinct hierarchy, distinct rhythm per variant, not just "same layout, figure moved". Squint test: each variant should be distinguishable by overall shape alone. All five render the same mutability lesson with the aliasing-mutation figure on cell 0, so only the layout differs: layout-above figure leads the cell, then prose, then code. Single-column stacking. Eye flow: picture → intuition → code. layout-after-output figure ends the cell as a visual summary after the output. Single-column stacking. Eye flow: everything → tying-it-together picture. layout-banner-top figure spans both columns as a banner above; prose and code keep their 2-column grid below. Eye flow: illustrated header → 2-up reading. layout-banner-bottom 2-column prose|code above, figure spans both columns as a footer. Eye flow: 2-up reading → illustrated summary. layout-prose-aside figure floats right inside the prose column with paragraphs wrapping around it; code-stack continues beside in its own column. Eye flow: prose with embedded illustration, code beside. The render_cell helper takes a figure_position parameter and emits the right DOM order plus a variant class on the .lp-cell. Per-variant CSS overrides live in VARIANT_CSS and are inlined into each prototype's <style>. Production rendering is unchanged: example pages still use the "between" layout via the existing has-figure class. Index page updated to list the five new variants alongside the canonical example-mutability prototype for direct comparison. https://claude.ai/code/session_01MazwoRWAihW6dwso3fMCHE
1 parent 265268a commit 575d2b5

8 files changed

Lines changed: 625 additions & 14 deletions

public/prototyping/example-mutability.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
</style>
2626
</head>
2727
<body>
28-
<div class="prototype-banner"><strong>Prototype</strong> · Mutability cell 0 with the aliasing-mutation figure inline between prose and code. · <a href="/prototyping/">all prototypes</a></div>
28+
<div class="prototype-banner"><strong>Prototype</strong> · Mutability cell 0 with the aliasing-mutation figure inline between prose and code (production layout). · <a href="/prototyping/">all prototypes</a></div>
2929

3030
<article class="example-shell">
3131
<div class="example-top"><a class="text-link" href="/">← All examples</a><a class="text-link" href="https://docs.python.org/3.13/reference/datamodel.html#objects-values-and-types">Python docs reference</a></div>

public/prototyping/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
<h1>Visual explainer prototypes</h1>
4040
<p class="meta">Real example pages with their attached figures, plus the design-review pages. The example pages all use the production layout: a cell with an attached figure stacks prose, figure, and code vertically; cells without figures keep today's prose|code grid.</p>
4141
</section>
42-
<ul class="prototype-list"><li><a class="text-link" href="/prototyping/marginalia-gestalt.html"><strong>Marginalia gestalt</strong></a><p class="meta">Every journey and example as a card, drawn from the shared grammar. Pure design review.</p></li><li><a class="text-link" href="/prototyping/operators-polish-comparison.html"><strong>Operators alignment polish</strong></a><p class="meta">Side-by-side before/after for the tree-edge alignment fix; demonstrates Canvas.connect().</p></li><li><a class="text-link" href="/prototyping/example-mutability.html"><strong>Example · Mutability</strong></a><p class="meta">Mutability lesson with the aliasing-mutation figure on cell 0. The canonical inline-between layout.</p></li><li><a class="text-link" href="/prototyping/example-closures.html"><strong>Example · Closures</strong></a><p class="meta">Closures lesson with the closure-cell figure on cell 0. Inner function references the outer cell.</p></li><li><a class="text-link" href="/prototyping/example-for-loops.html"><strong>Example · For Loops</strong></a><p class="meta">For-loops lesson with the iterator-unroll figure on cell 1. Each next() advances the caret.</p></li><li><a class="text-link" href="/prototyping/example-slices.html"><strong>Example · Slices</strong></a><p class="meta">Slices lesson with the slice-ruler figure on cell 0. Adjacent slices split at index 3.</p></li><li><a class="text-link" href="/prototyping/journey-streams.html"><strong>Journey · Streams</strong></a><p class="meta">Streams journey with three section-faithful figures: branching for decisions, repetition for loop shapes, the iter/next protocol for streams.</p></li></ul>
42+
<ul class="prototype-list"><li><a class="text-link" href="/prototyping/marginalia-gestalt.html"><strong>Marginalia gestalt</strong></a><p class="meta">Every journey and example as a card, drawn from the shared grammar. Pure design review.</p></li><li><a class="text-link" href="/prototyping/operators-polish-comparison.html"><strong>Operators alignment polish</strong></a><p class="meta">Side-by-side before/after for the tree-edge alignment fix; demonstrates Canvas.connect().</p></li><li><a class="text-link" href="/prototyping/example-mutability.html"><strong>Example · Mutability (canonical · between prose and code)</strong></a><p class="meta">Mutability lesson, figure between prose and code. Production layout: cell stacks vertically when a figure is attached.</p></li><li><a class="text-link" href="/prototyping/layout-above.html"><strong>Layout · figure above prose</strong></a><p class="meta">Variant: figure leads the cell, then prose, then code. Single-column stacking. Eye flow: see picture, read intuition, read code.</p></li><li><a class="text-link" href="/prototyping/layout-after-output.html"><strong>Layout · figure after output</strong></a><p class="meta">Variant: figure ends the cell as a visual summary after the output. Single-column stacking. Eye flow: read everything, then see the picture that ties it together.</p></li><li><a class="text-link" href="/prototyping/layout-banner-top.html"><strong>Layout · figure as banner above 2-col cell</strong></a><p class="meta">Variant: figure spans both columns as a banner above the cell; prose and code keep their 2-column grid below. Eye flow: illustrated header → 2-up reading.</p></li><li><a class="text-link" href="/prototyping/layout-banner-bottom.html"><strong>Layout · figure as banner below 2-col cell</strong></a><p class="meta">Variant: prose and code keep their 2-column grid; figure spans both columns as a footer. Eye flow: 2-up reading → illustrated summary.</p></li><li><a class="text-link" href="/prototyping/layout-prose-aside.html"><strong>Layout · figure floated inside prose</strong></a><p class="meta">Variant: small figure floats right inside the prose column; paragraphs flow around it. Code-stack continues in its own column. Eye flow: prose with embedded illustration, code beside.</p></li><li><a class="text-link" href="/prototyping/example-closures.html"><strong>Example · Closures</strong></a><p class="meta">Closures lesson with the closure-cell figure on cell 0. Inner function references the outer cell.</p></li><li><a class="text-link" href="/prototyping/example-for-loops.html"><strong>Example · For Loops</strong></a><p class="meta">For-loops lesson with the iterator-unroll figure on cell 1. Each next() advances the caret.</p></li><li><a class="text-link" href="/prototyping/example-slices.html"><strong>Example · Slices</strong></a><p class="meta">Slices lesson with the slice-ruler figure on cell 0. Adjacent slices split at index 3.</p></li><li><a class="text-link" href="/prototyping/journey-streams.html"><strong>Journey · Streams</strong></a><p class="meta">Streams journey with three section-faithful figures: branching for decisions, repetition for loop shapes, the iter/next protocol for streams.</p></li></ul>
4343
</article>
4444

4545
</body>
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Mutability · Prototype</title>
6+
<link rel="stylesheet" href="/site.css">
7+
<style>
8+
.prototype-banner {
9+
margin: 0 0 var(--space-4);
10+
padding: var(--space-2) var(--space-3);
11+
background: var(--accent-soft);
12+
border: 1px dashed var(--hairline);
13+
border-radius: .5rem;
14+
color: var(--muted);
15+
font-size: .85rem;
16+
}
17+
.prototype-banner strong { color: var(--text); font-weight: 600; }
18+
.prototype-banner a { color: inherit; }
19+
/* Production layout for cells with figures: single-column stacking. */
20+
.lp-cell.has-figure { grid-template-columns: 1fr; }
21+
.cell-figure { margin: 0; padding: 0; }
22+
.cell-figure svg { width: 100%; max-width: 360px; height: auto; display: block; }
23+
.cell-figure figcaption { margin-top: var(--space-2); color: var(--muted); font-size: .92rem; font-style: italic; max-width: 56ch; }
24+
25+
/* No further rules needed: .has-figure already collapses to 1fr.
26+
The figure simply renders before the prose paragraph in DOM order. */
27+
28+
</style>
29+
</head>
30+
<body>
31+
<div class="prototype-banner"><strong>Prototype</strong> · Variant: figure leads the cell, before prose. Single-column stacking when the cell has a figure. · <a href="/prototyping/">all prototypes</a></div>
32+
33+
<article class="example-shell">
34+
<div class="example-top"><a class="text-link" href="/">← All examples</a><a class="text-link" href="https://docs.python.org/3.13/reference/datamodel.html#objects-values-and-types">Python docs reference</a></div>
35+
<section class="example-intro">
36+
<p class="eyebrow">Data Model</p>
37+
<h1>Mutability</h1>
38+
<p class="meta">Some objects change in place, while others return new values.</p>
39+
</section>
40+
<section class="literate-program" aria-label="Annotated code walkthrough"><section class="lesson-step lp-cell has-figure has-figure--above"><figure class="cell-figure"><svg viewBox="0 0 220 175" xmlns="http://www.w3.org/2000/svg"><text x="0" y="12" font-family="-apple-system, 'Source Sans Pro', sans-serif" font-size="8" fill="rgba(82, 16, 0, 0.7)" text-anchor="start" letter-spacing="0.5">BEFORE</text><rect x="0" y="18" width="60" height="24" fill="none" stroke="#521000" stroke-width="1.0"/><text x="30.0" y="34.0" font-family="'Iowan Old Style', Charter, Georgia, serif" font-size="11" fill="#521000" text-anchor="middle" font-style="italic">first</text><rect x="0" y="48" width="60" height="24" fill="none" stroke="#521000" stroke-width="1.0"/><text x="30.0" y="64.0" font-family="'Iowan Old Style', Charter, Georgia, serif" font-size="11" fill="#521000" text-anchor="middle" font-style="italic">second</text><line x1="60" y1="30" x2="80.03839178306819" y2="42.331318020349656" stroke="#521000" stroke-width="1.0"/><polygon points="86,46 78.57091899120806,44.71596130712238 81.50586457492832,39.946674733576934" fill="#521000"/><line x1="60" y1="60" x2="79.83670230054477" y2="49.31869876124512" stroke="#521000" stroke-width="1.0"/><polygon points="86,46 81.16418180504282,51.784017841027215 78.50922279604673,46.85337968146303" fill="#521000"/><rect x="88" y="32" width="88" height="28" fill="rgba(82, 16, 0, 0.05)" stroke="#521000" stroke-width="1.0"/><text x="132.0" y="50.0" font-family="'JetBrains Mono', 'IBM Plex Mono', Menlo, monospace" font-size="10" fill="#521000" text-anchor="middle">["python"]</text><text x="0" y="100" font-family="-apple-system, 'Source Sans Pro', sans-serif" font-size="8" fill="rgba(82, 16, 0, 0.7)" text-anchor="start" letter-spacing="0.5">AFTER APPEND</text><rect x="0" y="108" width="60" height="24" fill="none" stroke="#521000" stroke-width="1.0"/><text x="30.0" y="124.0" font-family="'Iowan Old Style', Charter, Georgia, serif" font-size="11" fill="#521000" text-anchor="middle" font-style="italic">first</text><rect x="0" y="138" width="60" height="24" fill="none" stroke="#521000" stroke-width="1.0"/><text x="30.0" y="154.0" font-family="'Iowan Old Style', Charter, Georgia, serif" font-size="11" fill="#521000" text-anchor="middle" font-style="italic">second</text><line x1="60" y1="120" x2="80.03839178306819" y2="132.33131802034967" stroke="#521000" stroke-width="1.0"/><polygon points="86,136 78.57091899120806,134.7159613071224 81.50586457492832,129.94667473357694" fill="#521000"/><line x1="60" y1="150" x2="79.83670230054477" y2="139.31869876124512" stroke="#521000" stroke-width="1.0"/><polygon points="86,136 81.16418180504282,141.7840178410272 78.50922279604673,136.85337968146303" fill="#521000"/><rect x="88" y="122" width="130" height="28" fill="rgba(82, 16, 0, 0.05)" stroke="#521000" stroke-width="1.0"/><text x="153.0" y="140.0" font-family="'JetBrains Mono', 'IBM Plex Mono', Menlo, monospace" font-size="10" fill="#521000" text-anchor="middle">["python","workers"]</text></svg><figcaption>Two names share one mutable list — appending through one name changes the object visible through both.</figcaption></figure><div class="lp-prose"><p>Mutable objects can change in place. <code class="syntax-inline">first</code> and <code class="syntax-inline">second</code> point to the same list, so appending through one name changes the object seen through both names.</p></div><div class="cell-code-stack"><div class="cell-source"><p class="cell-label">Source</p><pre><code class="language-python">first = [&quot;python&quot;]
41+
second = first
42+
second.append(&quot;workers&quot;)
43+
print(first)
44+
print(second)</code></pre></div><div class="cell-output"><p class="cell-label">Output</p><pre><code>[&#x27;python&#x27;, &#x27;workers&#x27;]
45+
[&#x27;python&#x27;, &#x27;workers&#x27;]</code></pre></div></div></section><section class="lesson-step lp-cell"><div class="lp-prose"><p>Immutable objects do not change in place. String methods such as <code class="syntax-inline">upper()</code> return a new string, leaving the original string unchanged.</p></div><div class="cell-code-stack"><div class="cell-source"><p class="cell-label">Source</p><pre><code class="language-python">text = &quot;python&quot;
46+
upper_text = text.upper()
47+
print(text)
48+
print(upper_text)</code></pre></div><div class="cell-output"><p class="cell-label">Output</p><pre><code>python
49+
PYTHON</code></pre></div></div></section><section class="lesson-step lp-cell"><div class="lp-prose"><p>Some APIs make the boundary explicit. <code class="syntax-inline">sorted()</code> returns a new list, while methods such as <code class="syntax-inline">append()</code> and <code class="syntax-inline">list.sort()</code> mutate an existing list.</p></div><div class="cell-code-stack"><div class="cell-source"><p class="cell-label">Source</p><pre><code class="language-python">numbers = [3, 1, 2]
50+
ordered = sorted(numbers)
51+
print(ordered)
52+
print(numbers)</code></pre></div><div class="cell-output"><p class="cell-label">Output</p><pre><code>[1, 2, 3]
53+
[3, 1, 2]</code></pre></div></div></section></section>
54+
<h2>Notes</h2>
55+
<ul><li>Lists and dictionaries are mutable; strings and tuples are immutable.</li><li>Aliasing is useful, but copy mutable containers when independent changes are needed.</li><li>Pay attention to whether an operation mutates in place or returns a new value.</li></ul>
56+
<section class="playground" aria-label="Editable runnable example">
57+
<h2>Run the complete example</h2>
58+
<div class="runner-grid">
59+
<div class="runner-panel runner-editor">
60+
<h2>Example code</h2>
61+
<pre><code class="language-python">first = [&quot;python&quot;]
62+
second = first
63+
second.append(&quot;workers&quot;)
64+
print(first)
65+
print(second)
66+
67+
text = &quot;python&quot;
68+
upper_text = text.upper()
69+
print(text)
70+
print(upper_text)
71+
72+
numbers = [3, 1, 2]
73+
ordered = sorted(numbers)
74+
print(ordered)
75+
print(numbers)
76+
</code></pre>
77+
</div>
78+
<section class="runner-panel output-panel"><h2>Expected output</h2><pre><code>[&#x27;python&#x27;, &#x27;workers&#x27;]
79+
[&#x27;python&#x27;, &#x27;workers&#x27;]
80+
python
81+
PYTHON
82+
[1, 2, 3]
83+
[3, 1, 2]
84+
</code></pre></section>
85+
</div>
86+
</section>
87+
</article>
88+
89+
</body>
90+
</html>

0 commit comments

Comments
 (0)