diff --git a/README.md b/README.md
index 4750c6a..4e5c150 100644
--- a/README.md
+++ b/README.md
@@ -117,7 +117,7 @@ A diagram renderer, which draws flowcharts and diagrams from a plain-text descri
### Essentials / Advanced toggle
-A two-option switch, provided by the [mkdocs-audience-toggle](#mkdocs-audience-toggle) plugin (configured under `plugins:` in `mkdocs.yml`), that lets a reader hide everything beyond a first-pass beginner curriculum. Content is opted into hiding by marking it `data-fcm-hide="essentials"`:
+A two-option switch, provided by the [mkdocs-audience-toggle](#mkdocs-audience-toggle) plugin (configured under `plugins:` in `mkdocs.yml`), that lets a reader hide everything beyond a first-pass beginner curriculum. Content is opted into hiding by marking it `data-audience-hide="essentials"`:
- On a `##`/`###` heading inside a content page (e.g. functions.md's `## Decorators`), it hides that heading plus every sibling up to the next heading of the same or higher level, and removes the matching entry from the `toc.integrate` sidebar — so there's no dead nav link to something that's hidden.
- On a homepage card-grid row, it hides just that row. A whole homepage card hides too, once its first paragraph (the only one attr_list can attach the marker to) carries the marker — extra.css has a small `:has()` rule that extends that into hiding the entire `
`, since the plugin itself only hides the exact element marked.
@@ -177,10 +177,10 @@ plugins:
```
```markdown
-## Decorators {: data-fcm-hide="essentials" }
+## Decorators {: data-audience-hide="essentials" }
```
-Material has no built-in way to tailor a page to different readers. The plugin hides a marked heading together with its whole section and its table of contents entry. It switches to the nearest mode that shows the content when a link points to something hidden. It also collapses to icons or moves to its own row on narrow screens. It includes its own Playwright and axe-core tests. See the [plugin's README](https://github.com/luka-sherman/mkdocs-audience-toggle) for all options. This site's setup is under `audience_toggle` in `mkdocs.yml`, with color overrides in `extra.css`'s `#fcm-toggle` rule.
+Material has no built-in way to tailor a page to different readers. The plugin hides a marked heading together with its whole section and its table of contents entry. It switches to the nearest mode that shows the content when a link points to something hidden. It also collapses to icons or moves to its own row on narrow screens. It includes its own Playwright and axe-core tests. See the [plugin's README](https://github.com/luka-sherman/mkdocs-audience-toggle) for all options. This site's setup is under `audience_toggle` in `mkdocs.yml`, with color overrides in `extra.css`'s `#audience-toggle` rule.
### [mkdocs-cheatsheet](https://pypi.org/project/mkdocs-cheatsheet/)
@@ -205,6 +205,21 @@ plugins:
A section with its own cheatsheet page, like Libraries here, shows up on the homepage as title-and-description cards only. The optional header button replaces the logo with a "Cheatsheet" link home. It includes its own Playwright and axe-core tests. See the [plugin's README](https://github.com/luka-sherman/mkdocs-cheatsheet) for all options. This site's setup is under `cheatsheet` in `mkdocs.yml`, with the flag rules in STRUCTURE.md's "Cheatsheet flags" section.
+### [mkdocs-light-dark-toggle](https://pypi.org/project/mkdocs-light-dark-toggle/)
+
+An always-visible two-button light/dark switch, replacing Material's native single-knob palette toggle (whose knob is the only clickable spot, and whose current scheme is the only thing you can see). It started as this site's own light/dark JavaScript, and I rewrote it as a published plugin.
+
+```bash
+pip install mkdocs-light-dark-toggle
+```
+
+```yaml
+plugins:
+ - light_dark_toggle
+```
+
+Needs zero configuration to work: it ships with built-in sun/moon icons, unlike `mkdocs-audience-toggle` above where mode icons have no universal meaning and must always be supplied. The native palette radios stay in the DOM, hidden — their own JavaScript still applies and persists the scheme via `localStorage`, the plugin only drives them. It includes its own Playwright and axe-core tests. See the [plugin's README](https://github.com/luka-sherman/mkdocs-light-dark-toggle) for all options. This site's setup is under `light_dark_toggle` in `mkdocs.yml`, with color overrides in `extra.css`'s `#light-dark-toggle` rule.
+
## Theme
### Custom CSS
@@ -327,3 +342,23 @@ The domain is set up via the [docs/CNAME](docs/CNAME) file, which MkDocs copies
## License
The content and code in this repo are not licensed for reuse — see [LICENSE](LICENSE).
+
+## AI usage
+
+I used [Claude Code](https://claude.com/claude-code) for:
+
+- Restructuring and rewriting existing content
+- Scaffolding first drafts of library pages based off the site's existing [structure](STRUCTURE.md)
+- Implementing new features (e.g. the [Essentials/Advanced toggle](#essentials--advanced-toggle))
+- Propagating a content or naming change everywhere it's referenced (headings, anchors, homepage keyword links)
+- Diagnosing and fixing test failures (structure, accessibility) instead of just rerunning them
+- Verifying a change with `mkdocs build` and `pytest` before calling it done
+
+How I managed it:
+
+- Scoped to low-judgment, high-volume work — architecture and correctness stayed manual
+- Rewrote drafts in my own words rather than publishing them as-is, so I kept my own mental model of the content I'm teaching from
+- Checked output against [STRUCTURE.md](STRUCTURE.md)
+- Increased [test coverage](#testing) and [continuous integration](#continuous-integration) to protect its integrity
+- Scoped prompts to one task at a time to keep context down
+- After one prompt "fixed" content in bulk on its own, I switched to: report gaps, don't auto-fix content on your behalf
diff --git a/STRUCTURE.md b/STRUCTURE.md
index 1344f3b..6c6f84c 100644
--- a/STRUCTURE.md
+++ b/STRUCTURE.md
@@ -169,16 +169,16 @@ shows library pages as title-and-description cards only, and their links appear
- **Card text.** Each page's front matter sets `cheatsheet_description` (falling back to
`description`), plus `cheatsheet_title`, `cheatsheet_icon` or `cheatsheet_title_suffix` (the
built-in/third-party badge on library cards) where the defaults don't fit.
-- **Essentials mode.** A flagged heading that carries `data-fcm-hide="essentials"` passes it to
+- **Essentials mode.** A flagged heading that carries `data-audience-hide="essentials"` passes it to
its cheatsheet line or link, so the audience toggle hides both together. A whole card is
- hidden with `cheatsheet_attrs: {data-fcm-hide: essentials}` in front matter.
+ hidden with `cheatsheet_attrs: {data-audience-hide: essentials}` in front matter.
- **Verify with a real build.** A renamed heading moves its flag with it, so the cheatsheet can't
go stale, but `mkdocs build` still prints a `WARNING` for any broken link elsewhere.
- **Marking content "advanced" for the Essentials/Advanced toggle** — the header's segmented
control is provided by the `mkdocs-audience-toggle` plugin (configured under `plugins:` in
- `mkdocs.yml`) and hides content marked `data-fcm-hide="essentials"`. On a content page, append
- `{ data-fcm-hide="essentials" }` to the heading line (e.g. `functions.md`'s
- `## Decorators { data-fcm-hide="essentials" }`). This hides that heading, everything up to the
+ `mkdocs.yml`) and hides content marked `data-audience-hide="essentials"`. On a content page, append
+ `{ data-audience-hide="essentials" }` to the heading line (e.g. `functions.md`'s
+ `## Decorators { data-audience-hide="essentials" }`). This hides that heading, everything up to the
next heading of the same or higher level, and its sidebar entry. The cheatsheet picks the
marker up from the heading, so there's no second place to tag.
Which spots to mark, and what counts as advanced/niche vs. core, is a per-editor judgment call
@@ -211,7 +211,7 @@ Pick the existing type that matches the branch, don't invent new ones without a
| `??? info` | Defining a term/concept adjacent to the page but not the topic itself. |
| `??? failure` | The negative counterpart to a `success` branch — "this didn't work, here's what to do about it" (e.g. workspace.md's "download Python here" branch when `python --version` doesn't show 3.x.x). |
| `??? ai` | Opinion/meta content specifically about learning with or around AI (e.g. index.md's FAQ tabs on whether/how to use AI while learning) — not used for teaching content about Python itself. |
-| `??? efficiency` | A runtime/space aside naming the cost behind a choice already shown in prose (e.g. list vs. set membership, `sort()` vs. `sorted()`) — usually a Big O difference, occasionally a constant-factor one (`.get()` vs. two hash lookups, vectorized NumPy vs. a Python loop) where it's still worth flagging but doesn't change the O(...) class. Wrap it in `
` on a page that participates in the Essentials/Advanced toggle (skip it on a page that doesn't, like the library reference pages), and close with a link to [style.md's "Efficiency"](docs/practices/style.md#efficiency) section. Formalizes a tradeoff the surrounding prose already states in plain language; doesn't introduce the tradeoff for the first time. |
+| `??? efficiency` | A runtime/space aside naming the cost behind a choice already shown in prose (e.g. list vs. set membership, `sort()` vs. `sorted()`) — usually a Big O difference, occasionally a constant-factor one (`.get()` vs. two hash lookups, vectorized NumPy vs. a Python loop) where it's still worth flagging but doesn't change the O(...) class. Wrap it in `
` on a page that participates in the Essentials/Advanced toggle (skip it on a page that doesn't, like the library reference pages), and close with a link to [style.md's "Efficiency"](docs/practices/style.md#efficiency) section. Formalizes a tradeoff the surrounding prose already states in plain language; doesn't introduce the tradeoff for the first time. |
| `!!! example` | An always-open side-by-side comparison the reader is meant to see without a click, not a branch — e.g. "how to loop each type," showing every collection type's loop pattern in one visible table. |
Default to collapsed (`???`), not always-open (`!!!`) — an always-open admonition competes with
diff --git a/docs/javascripts/a11y_patches.js b/docs/javascripts/a11y_patches.js
index 8f6862b..104fbe0 100644
--- a/docs/javascripts/a11y_patches.js
+++ b/docs/javascripts/a11y_patches.js
@@ -11,23 +11,8 @@
});
}
- // pymdownx.tasklist (style.md's checklist) renders each `- [ ]` as a real
- // wrapped in its own