Select the types of activity you want to include in your feed.
[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/
···11+# Sidebar standards info and API topics: variant prototypes
22+33+Experimental branch `feat/toc-sidebar-info`. It does not merge and has no PR:
44+it exists so I can look at five ways of surfacing "what standard governs this
55+page" in the docs, plus three ways of dealing with the API reference tree,
66+switch between them live, and then keep one.
77+88+The predecessor of this branch, `exp/sidebar-standard-chips`
99+(`SIDEBAR-CHIPS-NOTES.md` there), put a coloured badge on every sidebar item.
1010+The classification work was right; the presentation was too loud. Every
1111+variant here reuses that classification untouched and only changes how, when
1212+and where it is shown.
1313+1414+## Mechanism
1515+1616+The per-item classification travels as a JSON string in Starlight's sanctioned
1717+`attrs` passthrough, under `data-chips`:
1818+1919+- `site/astro.config.mjs` builds it for the guides with the helpers `S(...)`
2020+ (governing standard, teal), `T(...)` (named reference, amber) and
2121+ `chips(...)`.
2222+- `scripts/generate_api_docs.py` emits the same shape for the API modules into
2323+ `site/src/generated/api-sidebar.mjs`, from the module docstrings.
2424+- `site/src/components/SidebarSublist.astro` parses it, renders one `<Badge>`
2525+ per chip inside a `.sidebar-chips` run in the link, and strips the raw
2626+ attribute so it never reaches the DOM.
2727+- `site/src/styles/toc-info.css` decides what that run looks like, or whether
2828+ it is shown at all. All of its selectors are unlayered, so they win over
2929+ Starlight's layered styles without specificity tricks.
3030+3131+Two more components exist for the page-level variant:
3232+`PageTitle.astro` (the subtitle under the H1) and `SectionStandards.astro`
3333+(the "standards by page" table on section landings). Both always render and
3434+are only displayed by CSS when the relevant variant is active, so switching
3535+never needs a rebuild.
3636+3737+The active variant is an attribute on `<html>`, applied before first paint by
3838+an inline script in `Head.astro` and persisted in `localStorage`. The same
3939+script stamps `data-area` (`guides` or `api`) from the URL, mounts the
4040+floating switcher, wires the API caret, and mirrors the section table heading
4141+into "On this page" when the clean variant is active.
4242+4343+Chip text is language neutral (designations and author names), so EN and ES
4444+share one classification and there is nothing extra to translate. Only the
4545+table headings, the visually hidden prefix and the back link are localized.
4646+4747+## Variant matrix
4848+4949+TOC info, attribute `data-toc-style` on `<html>`, localStorage key `tocStyle`:
5050+5151+| Value | What the reader sees |
5252+| --- | --- |
5353+| `focus` (default) | Annotation line under the label, only for the items of the section the reader is currently in. Rest of the tree untouched. |
5454+| `annotate` | The same line on every item of the whole tree. |
5555+| `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. |
5656+| `clean` | Nothing in the sidebar. The info moves to a subtitle under the H1 and to a table on each section landing page. |
5757+| `none` | Nothing anywhere. The pre-experiment look. |
5858+5959+API sidebar, attribute `data-api-style`, localStorage key `apiStyle`:
6060+6161+| Value | What the reader sees |
6262+| --- | --- |
6363+| `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. |
6464+| `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. |
6565+| `inline` | Status quo: the whole API tree always expanded in place. |
6666+6767+### How to switch
6868+6969+- The round "UX" button at the bottom right of every page opens the switcher.
7070+ The choice is remembered across pages and reloads.
7171+- Without the widget, from the console:
7272+ `document.documentElement.dataset.tocStyle = 'annotate'` and
7373+ `document.documentElement.dataset.apiStyle = 'collapsed'`. To make it stick,
7474+ `localStorage.setItem('tocStyle', 'annotate')`.
7575+- To go back to the shipped look, pick `none` and `inline`.
7676+7777+## Screenshots
7878+7979+In `ux-variants2/`. Desktop is 1440 x 1000, mobile is 390 x 844 with the menu
8080+open. Sidebar-only crops for the sidebar variants, full viewport where the
8181+page itself carries the information.
8282+8383+| File | What it shows |
8484+| --- | --- |
8585+| `focus-dark-desktop-en.png` | Focus, dark. Only the current section is annotated. |
8686+| `focus-light-desktop-en.png` | Focus, light. |
8787+| `focus-dark-desktop-es.png` | Focus on the Spanish tree: same chips, no translation needed. |
8888+| `focus-dark-mobile-en.png` | Focus inside the mobile menu. |
8989+| `annotate-dark-desktop-en.png` | Every item annotated, dark. |
9090+| `annotate-light-desktop-en.png` | Every item annotated, light. |
9191+| `annotate-dark-mobile-en.png` | Every item annotated, phone. |
9292+| `hover-resting-dark-desktop-en.png` | Hover variant at rest: no marks at all. |
9393+| `hover-card-dark-desktop-en.png` | Hover variant engaged: markers visible, card open. |
9494+| `hover-card-light-desktop-en.png` | The same in light. |
9595+| `hover-card-dark-mobile-en.png` | The card at 390 px in a hover-capable browser. |
9696+| `hover-touchfallback-simulated-dark-mobile-en.png` | What a real phone gets instead: the annotation line. Simulated, see the caveat below. |
9797+| `clean-subtitle-dark-desktop-en.png` | Clean: subtitle under the H1, sidebar empty. |
9898+| `clean-subtitle-light-desktop-en.png` | The same in light. |
9999+| `clean-subtitle-light-desktop-es.png` | The same in Spanish. |
100100+| `clean-subtitle-dark-mobile-en.png` | Subtitle on a phone. |
101101+| `clean-sectiontable-light-desktop-en.png` | Section landing table, light. |
102102+| `clean-sectiontable-dark-desktop-en.png` | Section landing table, dark, with its entry in "On this page". |
103103+| `clean-sectiontable-light-desktop-es.png` | Section landing table in Spanish. |
104104+| `clean-sectiontable-dark-mobile-en.png` | The table stacked for a phone. |
105105+| `none-dark-desktop-en.png`, `none-dark-mobile-en.png` | Reference: today's sidebar. |
106106+| `api-inline-guidepage-dark-desktop-en.png` | API tree expanded in place on a guide page. |
107107+| `api-collapsed-guidepage-dark-desktop-en.png` | API group folded behind a caret. |
108108+| `api-split-guidepage-dark-desktop-en.png` | API group reduced to a label with an arrow. |
109109+| `api-inline-apipage-dark-desktop-en.png` | Status quo on an API page. |
110110+| `api-collapsed-apipage-dark-desktop-en.png` | Collapsed mode on an API page (opens itself). |
111111+| `api-split-apipage-dark-desktop-en.png` | Split mode on an API page: back link plus reference only. |
112112+| `api-split-apipage-dark-mobile-en.png` | The same on a phone. |
113113+| `switcher-widget-dark-desktop-en.png` | The switcher panel. |
114114+115115+## Design critique
116116+117117+**focus.** The strongest of the five. The tree stays exactly as quiet as it is
118118+today except for the five or six rows the reader is actually working in, and
119119+those rows answer the only question the annotation is there to answer: which
120120+of these neighbouring pages do I want. The annotation sits at 11 px, indented
121121+under the label, one step below the label colour, so the eye reads label
122122+first and metadata second without effort. Weaknesses: the annotated block is
123123+a visible island in an otherwise plain tree, which looks slightly arbitrary
124124+until you notice it tracks the current section; multi-standard rows such as
125125+"Laboratory Insulation Measurement" wrap to two annotation lines and the run
126126+dots then fall mid-line, which reads ragged; and if a reader wants to compare
127127+two distant sections it shows nothing useful.
128128+129129+**annotate.** Honest and complete, and the least clever. It also roughly
130130+doubles the height of the tree, which on this site means a very long scroll,
131131+and it puts an almost equal density of text on every row, so the labels stop
132132+standing out as the thing you click. It is the right baseline to compare
133133+against and the wrong thing to ship. If it were shipped, the annotation
134134+should probably be limited to one designation per item.
135135+136136+**hover.** The cleanest resting state by a wide margin and the only variant
137137+that costs zero vertical space. Its structural problem is that nearly every
138138+page in this library is governed by something, so the affordance would mark
139139+almost every row and therefore distinguish nothing. That is why the marker is
140140+now gone at rest and only fades in while the pointer or the keyboard focus is
141141+inside the sidebar; even then it reads as texture across the whole tree. The
142142+card itself is good: it is anchored to the trailing edge of the link so it can
143143+never push the sidebar into horizontal scroll, it has a 250 ms intent delay,
144144+it opens on keyboard focus, and Escape dismisses it without moving the focus.
145145+It has two real costs. It hides the row underneath while open, because the
146146+sidebar is a scroll container and a card placed outside it would be clipped.
147147+And it is a desktop interaction: on touch there is no hover, so the fallback
148148+turns it into `annotate`, which means a phone reader never gets the clean
149149+tree the variant is for.
150150+151151+**clean.** The best looking of the five, and my second choice. The subtitle
152152+under the H1 reads like the dateline of a standard, it is the first thing you
153153+see on the page, and the sidebar keeps its current silence. The section
154154+landing table is the weakest part: on the section pages it duplicates the
155155+bullet list that already sits above it, where each bullet names its standards
156156+in prose, so it repeats rather than adds. It also introduces a heading that
157157+the markdown pipeline never sees, so its entry in "On this page" has to be
158158+injected client side, and on a phone the three columns only work because they
159159+now collapse into a stacked list. The deeper objection: the information
160160+arrives only after you have already chosen the page, so it never helps you
161161+choose one. That is exactly the job the sidebar annotation does.
162162+163163+**none.** The control. Worth flipping to now and then to check how much any
164164+of the others actually cost.
165165+166166+**API modes.** `inline` is what makes the sidebar unmanageable today: the API
167167+tree is far longer than the guide tree and it is always open. `collapsed` is
168168+the cheap fix and behaves well, though a caret is a single small target for a
169169+very large piece of navigation. `split` is the most comfortable to read on an
170170+API page, since the guide groups disappear entirely, but it is also the most
171171+custom, and it exposes a real flaw of the current information architecture:
172172+the API items still live three levels deep, under "Reference" and then "API
173173+reference", so module names like `loudness_moore_glasberg_time` wrap even when
174174+they are the only thing on screen.
175175+176176+## Recommendation
177177+178178+Ship `focus` for the standards info and `split` for the API sidebar, with two
179179+caveats.
180180+181181+`focus` because it is the only variant that puts the information where the
182182+decision is made, at the moment it is made, without paying for it everywhere
183183+else. `clean` is prettier but arrives too late to influence a choice, `hover`
184184+hides the information behind an interaction that half the readers cannot
185185+perform, and `annotate` makes the reader pay on every row for something they
186186+need on five.
187187+188188+The two caveats:
189189+190190+1. `focus` and `clean` are not exclusive. The subtitle under the H1 from the
191191+ `clean` variant costs nothing in the sidebar and confirms on arrival what
192192+ the annotation promised. I would ship the subtitle together with `focus`
193193+ and drop the section landing table, which duplicates prose that is already
194194+ there.
195195+2. For the API split, prefer the plugin over this prototype. See below.
196196+197197+Before shipping `focus` I would also trim the classification: cap the
198198+annotation at two standards plus one reference per item, so the wrapped
199199+three-designation rows stop happening, and keep the full list for the page
200200+subtitle where there is room.
201201+202202+## `split` versus `starlight-sidebar-topics`
203203+204204+My `split` prototype and the `starlight-sidebar-topics` plugin solve the same
205205+problem, and the plugin solves it better in the ways that matter long term.
206206+207207+What they share: one sidebar for the guides, another for the API reference,
208208+and a way back. What differs:
209209+210210+- The plugin makes each topic a root sidebar, so the API items lose the two
211211+ wrapper levels they currently sit under, and the topic switcher is a real
212212+ navigation control at the top of the sidebar rather than a link that only
213213+ appears on some pages. My prototype only hides things with CSS, so the
214214+ nesting, and the wrapping module names that come with it, stay.
215215+- The plugin's topic labels and badges take per-locale objects, so EN and ES
216216+ are handled by the config. Mine hardcodes the back link label in
217217+ `Sidebar.astro`.
218218+- The plugin is maintained and documented. Mine is roughly 30 lines of CSS
219219+ plus a hand-written back link, and every future Starlight release is my
220220+ problem.
221221+222222+What I would want to check before adopting it: this repo already overrides
223223+`Sidebar.astro` and `SidebarSublist.astro`, and the whole "overview first"
224224+group-label-as-link convention lives in that override. If the plugin also
225225+overrides `Sidebar`, one of the two has to give, and reconciling them is the
226226+real cost of the migration. The plugin docs do not say. That is a
227227+one-afternoon experiment, not a blocker.
228228+229229+So: keep `split` in this branch as the visual argument for splitting, and
230230+implement the split with the plugin rather than with this CSS.
231231+232232+## Verification
233233+234234+Checked in Chrome at 1440 x 1000 and at 390 x 844, in both themes, on EN and
235235+ES pages, on a guide page, a section landing and an API page:
236236+237237+- All five `data-toc-style` values and all three `data-api-style` values
238238+ render as intended, including the API caret toggle and its session memory.
239239+- No horizontal overflow of the sidebar in any variant at either width. The
240240+ hover card used to cause it and no longer does.
241241+- Keyboard: the hover card opens on `:focus-visible`, Escape dismisses it
242242+ without moving the focus, any other key brings it back, and leaving the link
243243+ resets it.
244244+- The "Guides" back link used to point at a page that does not exist
245245+ (`/guides/getting-started/`); it now points at `/getting-started/` and its
246246+ Spanish counterpart, and both answer 200.
247247+- `pnpm --dir site build` succeeds and the Starlight link validator reports
248248+ all internal links valid.
249249+- `pnpm run html-validate` passes. It did not at first: the section table
250250+ needed `scope="col"` on its headers, 36 errors across 12 pages.
251251+- `pnpm run pa11y` passes 46 of 46 URLs at WCAG2AA.
252252+- `node scripts/check-i18n-parity.mjs` passes.
253253+254254+What I could not verify locally:
255255+256256+- pa11y only exercises the default variant, since it starts with an empty
257257+ `localStorage`. The other four TOC variants and two API modes are not
258258+ covered by the audit. Colour choices were checked by hand instead: the
259259+ annotation ink is about 5.3:1 on the dark sidebar and 5.6:1 on the light
260260+ one, both above the 4.5:1 that 11 px text needs.
261261+- The touch fallback of the `hover` variant. The automation browser reports
262262+ `hover: hover`, so `@media (hover: none)` never applies there and the
263263+ screenshot of it is a simulation: the same declarations injected without the
264264+ media query. It needs one look on the actual phone.
265265+- Whether the injected "On this page" entry for the clean variant participates
266266+ in scroll spy. It does not, since Starlight collects its links at connect
267267+ time. It is a prototype-only wart that disappears with the client-side
268268+ injection if the variant is chosen.
269269+270270+## When a variant is chosen
271271+272272+Everything below is prototype scaffolding and comes out:
273273+274274+- both inline scripts at the bottom of `Head.astro`, and the
275275+ `.toc-switcher` rules in `toc-info.css`;
276276+- every branch of `toc-info.css` for the variants not chosen;
277277+- `SectionStandards.astro` and its import in `MarkdownContent.astro`, unless
278278+ the section table survives;
279279+- `PageTitle.astro` and its `components` entry in `astro.config.mjs`, unless
280280+ the subtitle survives;
281281+- the `api-caret` button in `SidebarSublist.astro` if the split is done with
282282+ the plugin instead.
283283+284284+The classification itself, the `chips()` helpers in `astro.config.mjs`, the
285285+`_API_CHIPS` table in `scripts/generate_api_docs.py` and the parsing in
286286+`SidebarSublist.astro` stay whatever the outcome.