Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
feat(site): link sidebar group labels to their section landing pages (#212)
* feat(site): link sidebar group labels to their section landing pages
Replace the stock Starlight sidebar with a local override
(src/components/Sidebar.astro + SidebarSublist.astro, adapted from
upstream 0.41.3) that renders every group permanently expanded and,
when a group's first item carries attrs: { 'data-group-link': true },
consumes that entry and turns the group label itself into the link
(Overview-first convention). The separate Overview rows disappear from
the sidebar while the landing pages stay published, indexed and in the
prev/next chain. Groups without a landing page (Start, Reference and
the generated API sections) remain static headings, now without a
caret, and the collapsed flag has no effect.
The API sidebar generator marks reference/api the same way, so the
"API reference" label links to the index page. sidebar.css splits
typography and color rules, guards the color on
:not([aria-current='page']) so the accent pill keeps its inverted text
when a label link is the current page, and restores the accent
hover/focus feedback for label links.
* test: expect the linked API group entry in the sidebar fragment
* refactor(site): forward landing link attributes and flatten the sublist mapping
docs: content enrichment (4 new figures, diagrams, equations) + full SEO/GEO layer (#66)
* docs: add group-delay, IEC toneburst, block-continuity and class-mask figures
Four new auto-generated figures (light+dark) wired into the filter-banks,
time-weighting, why-pyoctaveband and block-processing pages (docs/ EN +
site EN/ES), including a new 'Verifying the IEC 61260-1 class' section
documenting verify_filter_class with the acceptance-mask overlay.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: remove unreferenced legacy filter_fraction_* images
Leftovers from the pre-restructure README naming; nothing references
them (docs, site, scripts). Light/dark figure parity is now exact 26/26.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): GEO layer - robots.txt AI opt-in, llms.txt generation, mermaid
- robots.txt: universal allow + Content-Signal + explicit opt-in for 14 AI
crawlers + sitemap pointer.
- scripts/gen_llms.py generates llms.txt (structured project context with
AI-assistant install notes) and llms-full.txt (all docs pages inline);
committed at root, republished to the site via prebuild copy and
regenerated in the docs workflow for freshness. New 'make llms' target.
- astro-mermaid (+ mermaid) with autoTheme for the new calibration and
multirate diagrams; starlight-links-validator and lastUpdated enabled.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): SEO/GEO layer complete - JSON-LD, per-page heads, quality gates
- Site-wide JSON-LD @graph (Person with canonical jmrp.io identity incl.
ORCID, WebSite, SoftwareApplication with single-sourced version and
feature list, SoftwareSourceCode) + og/twitter/author/theme metas,
rel=me links, PGP key, manifest, Bing verification (Google property
already verified).
- Head.astro: per-page TechArticle (+speakable) and locale-aware
BreadcrumbList linked into the @graph, canonical URLs, twitter tags.
Footer.astro maintainer block. favicon.svg + PWA manifest.
- Quality gates: sitemap lastmod stamping (git dates, postbuild), EN/ES
i18n parity check, html-validate and pa11y (WCAG2AA) wired into the
docs workflow with fetch-depth: 0.
- Accessibility sweep: descriptive EN/ES alt text on all 147 figure
references; site uses style width (valid HTML), GitHub docs keep the
width attribute.
- Splash landing now shows the mobile menu button (route middleware
enables the sidebar; CSS hides the pane on desktop to keep the hero).
- og-image: designed 1200x630 card (gpt-image-2 via inference.sh, adapted
and committed); matplotlib generator kept as documented fallback.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: fix extraneous f-prefix and duplicate canonical link
Starlight already emits the canonical URL; Head.astro no longer adds a
second one.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): WCAG2AA - convert deprecated table align attributes to CSS
pa11y flagged 158 deprecated align attributes from markdown table
alignment; the rehypeTableAlign plugin (ported from the reference site)
rewrites them to text-align styles. 10/10 audited URLs now pass WCAG2AA.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: address review feedback (robustness, Table 4 consistency, llms links)
- version regex accepts single/double quotes; rehypeTableAlign appends to
existing styles; routeData guards undefined starlightRoute; Footer lang
detection handles /es without trailing slash; pa11y script kills by PID
(job control unavailable in some CI shells).
- why-pyoctaveband: the toneburst table is Table 4 in IEC 61672-1:2013
(Table 3 is the weightings) - fixed the stale issue-#38 wording, and
softened 'peaking exactly' to 'within 0.1 dB' (EN/ES).
- gen_llms.py absolutizes docs-relative links so llms-full.txt resolves
as a flat artifact.
- Intentionally NOT changed: docs/ keeps the width attribute on images
(GitHub strips style attributes); the site uses style widths.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
feat(site): unified APA references, accessible video embeds and build optimization (#223)
* feat(site): unified per-page references from typed frontmatter
Pages can now declare their bibliography as a typed references list in
the frontmatter (docsSchema extension: standard, book, article, web and
report entries with DOI/URL fields). A MarkdownContent override renders
one localized APA-7 References section at the end of the article,
alphabetized, with the title carrying the link and the DOI rendered as
its own descriptive link, and the route middleware appends the matching
On this page entry. Custom UI strings ride Starlight's i18n collection
(EN/ES).
* feat(site): accessible video embed with a download link
Video.astro wraps the Tier-1 animation convention (preload none, poster,
reserved width/height, EN/ES x light/dark WebM variants resolved from
the clip basename and the page language) and adds the accessibility
layer: required accessible name and textual description (aria-label +
aria-describedby), a visible localized download link per theme variant,
an in-element textual fallback, an optional visible caption and no
autoplay. The theme switch now also covers the wrapping figure.
* fix(site): keep the programme-loudness page titles within 70 characters
html-validate's long-title rule caps document titles at 70 characters
and the page suffix pushed both languages over the limit. The ITU-R/UIT-R
qualifier moves out of the title (the description and body keep the full
designations).
* docs: pilot migration to frontmatter references and the video embed
Loudness, aircraft noise and psychoacoustic annoyance (EN and ES) move
their References and Standards prose into the typed frontmatter
bibliography, with verified publisher links for every entry (ISO/IEC and
Ecma catalogues, ICAO store, SAE, ECAC, doi.org). Loudness and surface
scattering become MDX and embed their animations through the Video
component. The pa11y audit gains the six migrated URLs.
* perf(site): recompress served raster images and parallelize page rendering
A postbuild step palette-quantizes PNGs and re-encodes JPEGs in dist/
(sources untouched, rewritten only when smaller): the social card drops
from 663 KiB to 337 KiB. Page rendering moves to four concurrent pages.
The build profile documents the ceiling: the content-sync phase cannot
be cached while starlight-links-validator is enabled, since the plugin
clears the content-layer cache so its link map sees every page.
* docs: changelog for the site references, video embed and build optimization
* fix(site): review pass over the references and video infrastructure
References: nothing rendered after a DOI (APA-7), the annotation moves
to its own line and auto-links bare URLs keeping trailing sentence
punctuation out of the link (restoring the IEC 61265:2018 and ECAC
documents-page links in the aircraft-noise notes and the ICA 2016 venue
gloss in the annoyance notes), the Spanish pages join the last author
with "y" instead of the ampersand per the Spanish adaptation of APA-7,
the injected heading gets the same hover anchor as authored headings,
journal volumes italicize with <i> instead of <cite>, undated entries
sort first and the unreachable author fallback now fails loudly.
Video: figcaption kept as the last figure child (valid HTML) and an id
override for repeated embeds. Image recompression: per-file failures
skip with the file named instead of failing the build, and
already-indexed PNGs are skipped so a manual postbuild re-run cannot
re-quantize. Stale autoplay wording removed from the theme CSS comment;
leftover double blank lines collapsed.
docs(site): readable wide tables and full-width figures on phones (#200)
* docs(site): readable wide tables and full-width figures on phones
Wide markdown tables (4+ columns with a long-text notes column) crushed
every column to a few characters per line on narrow screens, with
enormously tall cells, because the browser's automatic table layout
wraps text down to min-content width before Starlight's scroll container
engages. New theme-tables.css gives the cells of 4+ column tables
readable minimum widths at <=50rem (8rem, 16rem for the trailing notes
column) so the table scrolls horizontally instead of crushing; 2-3
column tables and all desktop rendering are unchanged. The wide tables
also get tabindex="0" (via the existing rehype table transform) and a
visible focus outline, keeping the scroll container keyboard-reachable
on Safari/WebKit, which unlike Chrome 127+ and Firefox does not focus
scrollable regions by default.
Figure sizing on phones now uses a single generic selector so every
inline-sized image and video spans the full reading column at <=50rem:
the old per-tier list (80/88/92 to 100%, 70 to 90%, 60 to 80%) missed
the 72/75/78/82/86/90/94/96% tiers, which kept wasted side margins and
illegible axis labels on mobile.
Verified with headless-browser screenshots at 375x812 and 1440x900
across guide, generated API, theory and bibliography pages (EN and ES):
no page-level horizontal overflow anywhere, desktop metrics identical,
keyboard scrolling of the focused table works. Gates: pnpm build,
html-validate, pa11y-ci 30/30, ruff, mypy.
* docs(site): match the authored width convention with a prefix selector