[READ-ONLY] Mirror of https://github.com/jmrplens/PyOctaveBand. [Python3] Octave-Band and Fractional Octave-Band filter. For signal in time domain. jmrplens.github.io/PyOctaveBand/
acoustics audio filter frequency frequency-analysis frequency-domain octave python3 signal time-domain
0

Configure Feed

Select the types of activity you want to include in your feed.

Write up the variant matrix, screenshot index and recommendation

José M. Requena Plens (Jul 25, 2026, 11:16 PM +0200) eb99db36 a7e11f95

+286
+286
TOC-REDESIGN-NOTES.md
··· 1 + # Sidebar standards info and API topics: variant prototypes 2 + 3 + Experimental branch `feat/toc-sidebar-info`. It does not merge and has no PR: 4 + it exists so I can look at five ways of surfacing "what standard governs this 5 + page" in the docs, plus three ways of dealing with the API reference tree, 6 + switch between them live, and then keep one. 7 + 8 + The predecessor of this branch, `exp/sidebar-standard-chips` 9 + (`SIDEBAR-CHIPS-NOTES.md` there), put a coloured badge on every sidebar item. 10 + The classification work was right; the presentation was too loud. Every 11 + variant here reuses that classification untouched and only changes how, when 12 + and where it is shown. 13 + 14 + ## Mechanism 15 + 16 + The per-item classification travels as a JSON string in Starlight's sanctioned 17 + `attrs` passthrough, under `data-chips`: 18 + 19 + - `site/astro.config.mjs` builds it for the guides with the helpers `S(...)` 20 + (governing standard, teal), `T(...)` (named reference, amber) and 21 + `chips(...)`. 22 + - `scripts/generate_api_docs.py` emits the same shape for the API modules into 23 + `site/src/generated/api-sidebar.mjs`, from the module docstrings. 24 + - `site/src/components/SidebarSublist.astro` parses it, renders one `<Badge>` 25 + per chip inside a `.sidebar-chips` run in the link, and strips the raw 26 + attribute so it never reaches the DOM. 27 + - `site/src/styles/toc-info.css` decides what that run looks like, or whether 28 + it is shown at all. All of its selectors are unlayered, so they win over 29 + Starlight's layered styles without specificity tricks. 30 + 31 + Two more components exist for the page-level variant: 32 + `PageTitle.astro` (the subtitle under the H1) and `SectionStandards.astro` 33 + (the "standards by page" table on section landings). Both always render and 34 + are only displayed by CSS when the relevant variant is active, so switching 35 + never needs a rebuild. 36 + 37 + The active variant is an attribute on `<html>`, applied before first paint by 38 + an inline script in `Head.astro` and persisted in `localStorage`. The same 39 + script stamps `data-area` (`guides` or `api`) from the URL, mounts the 40 + floating switcher, wires the API caret, and mirrors the section table heading 41 + into "On this page" when the clean variant is active. 42 + 43 + Chip text is language neutral (designations and author names), so EN and ES 44 + share one classification and there is nothing extra to translate. Only the 45 + table headings, the visually hidden prefix and the back link are localized. 46 + 47 + ## Variant matrix 48 + 49 + TOC info, attribute `data-toc-style` on `<html>`, localStorage key `tocStyle`: 50 + 51 + | Value | What the reader sees | 52 + | --- | --- | 53 + | `focus` (default) | Annotation line under the label, only for the items of the section the reader is currently in. Rest of the tree untouched. | 54 + | `annotate` | The same line on every item of the whole tree. | 55 + | `hover` | Nothing at rest. A hairline dotted marker appears on annotated items while the pointer or the keyboard focus is inside the sidebar, and the info opens in a small floating card on hover or focus. On touch devices it falls back to the always-visible line. | 56 + | `clean` | Nothing in the sidebar. The info moves to a subtitle under the H1 and to a table on each section landing page. | 57 + | `none` | Nothing anywhere. The pre-experiment look. | 58 + 59 + API sidebar, attribute `data-api-style`, localStorage key `apiStyle`: 60 + 61 + | Value | What the reader sees | 62 + | --- | --- | 63 + | `split` (default) | Topic style. On guide pages the API group shrinks to its label with a forward arrow; on API pages the guide groups disappear and a "Guides" back link takes their place. | 64 + | `collapsed` | The API group gets a caret and folds. Folded on guide pages, open on API pages, and the reader's choice is kept for the session. | 65 + | `inline` | Status quo: the whole API tree always expanded in place. | 66 + 67 + ### How to switch 68 + 69 + - The round "UX" button at the bottom right of every page opens the switcher. 70 + The choice is remembered across pages and reloads. 71 + - Without the widget, from the console: 72 + `document.documentElement.dataset.tocStyle = 'annotate'` and 73 + `document.documentElement.dataset.apiStyle = 'collapsed'`. To make it stick, 74 + `localStorage.setItem('tocStyle', 'annotate')`. 75 + - To go back to the shipped look, pick `none` and `inline`. 76 + 77 + ## Screenshots 78 + 79 + In `ux-variants2/`. Desktop is 1440 x 1000, mobile is 390 x 844 with the menu 80 + open. Sidebar-only crops for the sidebar variants, full viewport where the 81 + page itself carries the information. 82 + 83 + | File | What it shows | 84 + | --- | --- | 85 + | `focus-dark-desktop-en.png` | Focus, dark. Only the current section is annotated. | 86 + | `focus-light-desktop-en.png` | Focus, light. | 87 + | `focus-dark-desktop-es.png` | Focus on the Spanish tree: same chips, no translation needed. | 88 + | `focus-dark-mobile-en.png` | Focus inside the mobile menu. | 89 + | `annotate-dark-desktop-en.png` | Every item annotated, dark. | 90 + | `annotate-light-desktop-en.png` | Every item annotated, light. | 91 + | `annotate-dark-mobile-en.png` | Every item annotated, phone. | 92 + | `hover-resting-dark-desktop-en.png` | Hover variant at rest: no marks at all. | 93 + | `hover-card-dark-desktop-en.png` | Hover variant engaged: markers visible, card open. | 94 + | `hover-card-light-desktop-en.png` | The same in light. | 95 + | `hover-card-dark-mobile-en.png` | The card at 390 px in a hover-capable browser. | 96 + | `hover-touchfallback-simulated-dark-mobile-en.png` | What a real phone gets instead: the annotation line. Simulated, see the caveat below. | 97 + | `clean-subtitle-dark-desktop-en.png` | Clean: subtitle under the H1, sidebar empty. | 98 + | `clean-subtitle-light-desktop-en.png` | The same in light. | 99 + | `clean-subtitle-light-desktop-es.png` | The same in Spanish. | 100 + | `clean-subtitle-dark-mobile-en.png` | Subtitle on a phone. | 101 + | `clean-sectiontable-light-desktop-en.png` | Section landing table, light. | 102 + | `clean-sectiontable-dark-desktop-en.png` | Section landing table, dark, with its entry in "On this page". | 103 + | `clean-sectiontable-light-desktop-es.png` | Section landing table in Spanish. | 104 + | `clean-sectiontable-dark-mobile-en.png` | The table stacked for a phone. | 105 + | `none-dark-desktop-en.png`, `none-dark-mobile-en.png` | Reference: today's sidebar. | 106 + | `api-inline-guidepage-dark-desktop-en.png` | API tree expanded in place on a guide page. | 107 + | `api-collapsed-guidepage-dark-desktop-en.png` | API group folded behind a caret. | 108 + | `api-split-guidepage-dark-desktop-en.png` | API group reduced to a label with an arrow. | 109 + | `api-inline-apipage-dark-desktop-en.png` | Status quo on an API page. | 110 + | `api-collapsed-apipage-dark-desktop-en.png` | Collapsed mode on an API page (opens itself). | 111 + | `api-split-apipage-dark-desktop-en.png` | Split mode on an API page: back link plus reference only. | 112 + | `api-split-apipage-dark-mobile-en.png` | The same on a phone. | 113 + | `switcher-widget-dark-desktop-en.png` | The switcher panel. | 114 + 115 + ## Design critique 116 + 117 + **focus.** The strongest of the five. The tree stays exactly as quiet as it is 118 + today except for the five or six rows the reader is actually working in, and 119 + those rows answer the only question the annotation is there to answer: which 120 + of these neighbouring pages do I want. The annotation sits at 11 px, indented 121 + under the label, one step below the label colour, so the eye reads label 122 + first and metadata second without effort. Weaknesses: the annotated block is 123 + a visible island in an otherwise plain tree, which looks slightly arbitrary 124 + until you notice it tracks the current section; multi-standard rows such as 125 + "Laboratory Insulation Measurement" wrap to two annotation lines and the run 126 + dots then fall mid-line, which reads ragged; and if a reader wants to compare 127 + two distant sections it shows nothing useful. 128 + 129 + **annotate.** Honest and complete, and the least clever. It also roughly 130 + doubles the height of the tree, which on this site means a very long scroll, 131 + and it puts an almost equal density of text on every row, so the labels stop 132 + standing out as the thing you click. It is the right baseline to compare 133 + against and the wrong thing to ship. If it were shipped, the annotation 134 + should probably be limited to one designation per item. 135 + 136 + **hover.** The cleanest resting state by a wide margin and the only variant 137 + that costs zero vertical space. Its structural problem is that nearly every 138 + page in this library is governed by something, so the affordance would mark 139 + almost every row and therefore distinguish nothing. That is why the marker is 140 + now gone at rest and only fades in while the pointer or the keyboard focus is 141 + inside the sidebar; even then it reads as texture across the whole tree. The 142 + card itself is good: it is anchored to the trailing edge of the link so it can 143 + never push the sidebar into horizontal scroll, it has a 250 ms intent delay, 144 + it opens on keyboard focus, and Escape dismisses it without moving the focus. 145 + It has two real costs. It hides the row underneath while open, because the 146 + sidebar is a scroll container and a card placed outside it would be clipped. 147 + And it is a desktop interaction: on touch there is no hover, so the fallback 148 + turns it into `annotate`, which means a phone reader never gets the clean 149 + tree the variant is for. 150 + 151 + **clean.** The best looking of the five, and my second choice. The subtitle 152 + under the H1 reads like the dateline of a standard, it is the first thing you 153 + see on the page, and the sidebar keeps its current silence. The section 154 + landing table is the weakest part: on the section pages it duplicates the 155 + bullet list that already sits above it, where each bullet names its standards 156 + in prose, so it repeats rather than adds. It also introduces a heading that 157 + the markdown pipeline never sees, so its entry in "On this page" has to be 158 + injected client side, and on a phone the three columns only work because they 159 + now collapse into a stacked list. The deeper objection: the information 160 + arrives only after you have already chosen the page, so it never helps you 161 + choose one. That is exactly the job the sidebar annotation does. 162 + 163 + **none.** The control. Worth flipping to now and then to check how much any 164 + of the others actually cost. 165 + 166 + **API modes.** `inline` is what makes the sidebar unmanageable today: the API 167 + tree is far longer than the guide tree and it is always open. `collapsed` is 168 + the cheap fix and behaves well, though a caret is a single small target for a 169 + very large piece of navigation. `split` is the most comfortable to read on an 170 + API page, since the guide groups disappear entirely, but it is also the most 171 + custom, and it exposes a real flaw of the current information architecture: 172 + the API items still live three levels deep, under "Reference" and then "API 173 + reference", so module names like `loudness_moore_glasberg_time` wrap even when 174 + they are the only thing on screen. 175 + 176 + ## Recommendation 177 + 178 + Ship `focus` for the standards info and `split` for the API sidebar, with two 179 + caveats. 180 + 181 + `focus` because it is the only variant that puts the information where the 182 + decision is made, at the moment it is made, without paying for it everywhere 183 + else. `clean` is prettier but arrives too late to influence a choice, `hover` 184 + hides the information behind an interaction that half the readers cannot 185 + perform, and `annotate` makes the reader pay on every row for something they 186 + need on five. 187 + 188 + The two caveats: 189 + 190 + 1. `focus` and `clean` are not exclusive. The subtitle under the H1 from the 191 + `clean` variant costs nothing in the sidebar and confirms on arrival what 192 + the annotation promised. I would ship the subtitle together with `focus` 193 + and drop the section landing table, which duplicates prose that is already 194 + there. 195 + 2. For the API split, prefer the plugin over this prototype. See below. 196 + 197 + Before shipping `focus` I would also trim the classification: cap the 198 + annotation at two standards plus one reference per item, so the wrapped 199 + three-designation rows stop happening, and keep the full list for the page 200 + subtitle where there is room. 201 + 202 + ## `split` versus `starlight-sidebar-topics` 203 + 204 + My `split` prototype and the `starlight-sidebar-topics` plugin solve the same 205 + problem, and the plugin solves it better in the ways that matter long term. 206 + 207 + What they share: one sidebar for the guides, another for the API reference, 208 + and a way back. What differs: 209 + 210 + - The plugin makes each topic a root sidebar, so the API items lose the two 211 + wrapper levels they currently sit under, and the topic switcher is a real 212 + navigation control at the top of the sidebar rather than a link that only 213 + appears on some pages. My prototype only hides things with CSS, so the 214 + nesting, and the wrapping module names that come with it, stay. 215 + - The plugin's topic labels and badges take per-locale objects, so EN and ES 216 + are handled by the config. Mine hardcodes the back link label in 217 + `Sidebar.astro`. 218 + - The plugin is maintained and documented. Mine is roughly 30 lines of CSS 219 + plus a hand-written back link, and every future Starlight release is my 220 + problem. 221 + 222 + What I would want to check before adopting it: this repo already overrides 223 + `Sidebar.astro` and `SidebarSublist.astro`, and the whole "overview first" 224 + group-label-as-link convention lives in that override. If the plugin also 225 + overrides `Sidebar`, one of the two has to give, and reconciling them is the 226 + real cost of the migration. The plugin docs do not say. That is a 227 + one-afternoon experiment, not a blocker. 228 + 229 + So: keep `split` in this branch as the visual argument for splitting, and 230 + implement the split with the plugin rather than with this CSS. 231 + 232 + ## Verification 233 + 234 + Checked in Chrome at 1440 x 1000 and at 390 x 844, in both themes, on EN and 235 + ES pages, on a guide page, a section landing and an API page: 236 + 237 + - All five `data-toc-style` values and all three `data-api-style` values 238 + render as intended, including the API caret toggle and its session memory. 239 + - No horizontal overflow of the sidebar in any variant at either width. The 240 + hover card used to cause it and no longer does. 241 + - Keyboard: the hover card opens on `:focus-visible`, Escape dismisses it 242 + without moving the focus, any other key brings it back, and leaving the link 243 + resets it. 244 + - The "Guides" back link used to point at a page that does not exist 245 + (`/guides/getting-started/`); it now points at `/getting-started/` and its 246 + Spanish counterpart, and both answer 200. 247 + - `pnpm --dir site build` succeeds and the Starlight link validator reports 248 + all internal links valid. 249 + - `pnpm run html-validate` passes. It did not at first: the section table 250 + needed `scope="col"` on its headers, 36 errors across 12 pages. 251 + - `pnpm run pa11y` passes 46 of 46 URLs at WCAG2AA. 252 + - `node scripts/check-i18n-parity.mjs` passes. 253 + 254 + What I could not verify locally: 255 + 256 + - pa11y only exercises the default variant, since it starts with an empty 257 + `localStorage`. The other four TOC variants and two API modes are not 258 + covered by the audit. Colour choices were checked by hand instead: the 259 + annotation ink is about 5.3:1 on the dark sidebar and 5.6:1 on the light 260 + one, both above the 4.5:1 that 11 px text needs. 261 + - The touch fallback of the `hover` variant. The automation browser reports 262 + `hover: hover`, so `@media (hover: none)` never applies there and the 263 + screenshot of it is a simulation: the same declarations injected without the 264 + media query. It needs one look on the actual phone. 265 + - Whether the injected "On this page" entry for the clean variant participates 266 + in scroll spy. It does not, since Starlight collects its links at connect 267 + time. It is a prototype-only wart that disappears with the client-side 268 + injection if the variant is chosen. 269 + 270 + ## When a variant is chosen 271 + 272 + Everything below is prototype scaffolding and comes out: 273 + 274 + - both inline scripts at the bottom of `Head.astro`, and the 275 + `.toc-switcher` rules in `toc-info.css`; 276 + - every branch of `toc-info.css` for the variants not chosen; 277 + - `SectionStandards.astro` and its import in `MarkdownContent.astro`, unless 278 + the section table survives; 279 + - `PageTitle.astro` and its `components` entry in `astro.config.mjs`, unless 280 + the subtitle survives; 281 + - the `api-caret` button in `SidebarSublist.astro` if the split is done with 282 + the plugin instead. 283 + 284 + The classification itself, the `chips()` helpers in `astro.config.mjs`, the 285 + `_API_CHIPS` table in `scripts/generate_api_docs.py` and the parsing in 286 + `SidebarSublist.astro` stay whatever the outcome.