Capture the sidebar grouping candidates and add a mobile-drawer pa11y run
Twenty-three shots in toc-ux-shots/: the status quo, the responsive treatment
and the collapsed treatment, at 1440x900 and 390x844, in both themes and both
languages, plus the tapped and keyboard-focused states of the fold control.
Desktop shots are clipped to the sidebar column, which is the subject; phone
shots are the whole viewport, because there the tree is a drawer over the page.
The pa11y config for the drawer opens the hamburger before testing, which the
default run never does, so the folded tree and its controls are audited in the
state a phone reader actually sees.
The fold control keeps a 40px square target on the drawer, past the 24px floor
of WCAG 2.2 SC 2.5.8 and small enough that the eleven closed groups still fit
one screen, and it restates the two eyebrow-header rules that the row wrapper
would otherwise stop matching.
Settle the page chips inside the instrument palette
The chips were tuned against the old Starlight default palette, and against
the instrument palette they were doing two things I do not want. The
standards teal sat at OKLCH hue 181 with the accent at 216 to 225, close
enough to read as a near-miss of the accent rather than a category of its
own, and both chip hues carried more chroma than the accent itself (0.103
and 0.141 against 0.056 in the dark theme), so the header run out-weighed
the one colour this palette lets mean something.
So the standards chip now takes the palette accent itself, which is honest:
the standards are what the page is about and the chip is a link. The named
works take its warm mirror, same OKLCH lightness and chroma at hue 74 and 70,
which keeps the two categories far apart without introducing a second loud
colour. The tokens live in theme.css with the rest of the palette and the
chip stylesheet only references them.
check-contrast.mjs now audits the nine chip pairs per theme: text on the
page and on the hover fill at 4.5:1, and the pill border, which is what
carries the category, at 3:1. Everything clears, the tightest being the
"+N more" border at 3.04:1 dark and the standards border at 3.42:1 light.
Also add scripts/integration-shots.mjs, the capture matrix for this branch.
Ship one palette and one language behaviour, and delete the switching
I have decided both questions this branch was carrying, so the code
should carry one answer and not three. The palette is "instrument",
cool steel greys with a deep cyan indicator, and the language handling
is the banner: it offers the other language and nothing ever navigates
on its own.
Gone with them: the floating prototype switcher, the blueprint and
graphite palettes, the `data-accent` attribute and the before-paint
script in Head.astro that stamped it, the `phonometry:accent` and
`phonometry:lang-mode` storage keys, the redirect and off language
modes with their per-session guard, and the bar-height custom property
that only existed so the switcher could sit clear of the bar.
src/styles/theme-directions.css becomes src/styles/theme.css, with the
winning direction promoted to the plain :root and
:root[data-theme='light'] rules.
The language feature keeps a kill switch, but as a build-time constant
rather than a control: ENABLED in LangSuggest.astro renders no markup
and no script when it is false. Nothing on the page and nothing in
storage can flip it.
Everything else about the behaviour is unchanged and still checked: an
explicit choice always wins, the picker and a dismissal both record
one, crawlers are skipped and the English-only API subtree renders no
bar at all. check-contrast.mjs now resolves the two themes of the one
palette (25 pairs, 0 below threshold) and check-lang-suggest.mjs runs
the nine scenarios that survive without modes.
Lift the language bar out of the content column
The bar is fixed across the whole bottom edge, but it was mounted in the
Footer override, which renders inside Starlight's `.main-pane`. That pane
sets `isolation: isolate`, so the bar got its own stacking context and
painted under the sidebar pane no matter what its z-index said: on a desktop
layout the sentence was cut mid-word by the sidebar and the dismiss button
was cut by the table of contents. Mounting it in a PageFrame override makes
it a sibling of the page frame, in the root stacking context, where its
z-index means what it reads. The frame renders on every route, splash
included, so nothing loses the bar.
The floating treatment switcher was landing on the dismiss button as well,
the two branches having each pinned something to that corner. The bar now
publishes its height on <html> while it is on screen and the switcher steps
over it.
check-lang-suggest.mjs gets the scenario that would have caught this: hit
test the bar over the sidebar, over the content and over the toc, plus the
dismiss button itself. The markup was always right; only the paint order
was wrong, so only a hit test can see it.
Land the "+N more" chip where the entries land, and raise the cap to nine
Three things on the header chips.
The "+N more" chip pointed at the References heading, which had no landing
offset of its own, while the entries had one. Starlight's scroll-padding
clears the sticky chrome for both, so neither was hidden, but the heading came
to rest hard against the sticky bar while an entry came to rest a comfortable
way below it, and on a phone, where the mobile table of contents is part of
that chrome, the difference is the whole gap. The offset is now one custom
property in one rule covering the entries, the heading and its wrapper, so
the two targets cannot drift apart again. Both land at 168 px on a 1440 px
desktop and 200 px on a 390 px phone, EN and ES, with and without the
language bar.
The cap is nine chips for the run as a whole, with a tenth slot for the
"+N more" link, replacing five standards plus three works. The budget is not
split per category any more, with one guard: the named works hold a
reservation of up to three slots when the page has any, the standards take
the rest, and whatever the standards do not use goes back to the works. Nine
standards on a standards-only page, nine papers on a paper-only page, and a
page with fourteen standards and three papers shows six and three rather than
nine and none. The `primary: true` flag still orders the run first: flagging a
work that was past the old cap on the underwater page brings it to the front
of its run and into the visible nine.
Worth knowing: nine chips no longer fit the one line the run was designed
around. The densest page is four rows at 1440 px and six at 390 px. It reads
as a block under the H1 rather than a dateline, which is the trade the higher
cap buys.
scripts/check-page-chips.mjs is the new gate: the cap on seven pages in both
locales, and the landing of an entry chip against the more chip at four
viewport sizes, both themes, both locales and with the language bar up.
Audit pass 4c: final identifier sweep against the naming convention (#113)
* refactor: final identifier sweep against the naming convention
Audit batch 4c — the remaining non-conforming identifiers, closing the
library-wide rename batch:
- public constants drop the unit suffix (units belong in docstrings):
OCTAVE_BANDS, THIRD_OCTAVE_BANDS (absorption_rating) and
BASE_PLATE_BANDS (scattering_diffusion), with PEP 562 __getattr__
shims in the home modules and at the package root; plain import stays
warning-free (verified with -W error)
- sii.BAND_CENTRES -> BAND_CENTERS (American spelling, module shim);
the private road_absorption centres constant renames directly
- ExposureWarning -> OccupationalExposureWarning; the module
__getattr__ returns the same class object so isinstance/except and
warning filters via the old name keep matching
- multiple_shock_vibration reuses hearing.SEXES instead of a private
duplicate
- tests/reference_data.py families gain their standard designations
(ANSIS3_5_*, ANSIS12_2_*, NTACOU112_*, ISO7029_*, ISO389_7_*)
- misleading test files renamed: test_parametrized_signals.py (it never
tested parametric_filters) and test_loudness_contours.py (1:1 with
its module); scripts/gen_llms.py -> generate_llms.py (workflow and
Makefile updated)
- conformance internals catch up (_chk_impulse_*) and an internal use
of the deprecated expanded_uncertainty alias is migrated
Flagged and deliberately left: REFERENCE_DURATION_S (the mixed-units
carve-out applies - seconds and hours coexist in the exposure API) and
the private British 'unfavourable' constants (ISO 717/11654 normative
wording; private tables are named after the standard).
Six new alias tests (root and module access, class identity, the
AttributeError path).
* test: anchor the renamed band tables value-by-value
The tests around the renamed constants asserted lengths or spot values;
they now pin every element (nominal one-third-octave and base-plate
bands, the SII band centers, and the per-impulse Formula 1 values),
verified against the code, so an accidental table edit cannot pass
(Gemini).
Ship one palette and one language behaviour, and delete the switching
I have decided both questions this branch was carrying, so the code
should carry one answer and not three. The palette is "instrument",
cool steel greys with a deep cyan indicator, and the language handling
is the banner: it offers the other language and nothing ever navigates
on its own.
Gone with them: the floating prototype switcher, the blueprint and
graphite palettes, the `data-accent` attribute and the before-paint
script in Head.astro that stamped it, the `phonometry:accent` and
`phonometry:lang-mode` storage keys, the redirect and off language
modes with their per-session guard, and the bar-height custom property
that only existed so the switcher could sit clear of the bar.
src/styles/theme-directions.css becomes src/styles/theme.css, with the
winning direction promoted to the plain :root and
:root[data-theme='light'] rules.
The language feature keeps a kill switch, but as a build-time constant
rather than a control: ENABLED in LangSuggest.astro renders no markup
and no script when it is false. Nothing on the page and nothing in
storage can flip it.
Everything else about the behaviour is unchanged and still checked: an
explicit choice always wins, the picker and a dismissal both record
one, crawlers are skipped and the English-only API subtree renders no
bar at all. check-contrast.mjs now resolves the two themes of the one
palette (25 pairs, 0 below threshold) and check-lang-suggest.mjs runs
the nine scenarios that survive without modes.
Capture the sidebar grouping candidates and add a mobile-drawer pa11y run
Twenty-three shots in toc-ux-shots/: the status quo, the responsive treatment
and the collapsed treatment, at 1440x900 and 390x844, in both themes and both
languages, plus the tapped and keyboard-focused states of the fold control.
Desktop shots are clipped to the sidebar column, which is the subject; phone
shots are the whole viewport, because there the tree is a drawer over the page.
The pa11y config for the drawer opens the hamburger before testing, which the
default run never does, so the folded tree and its controls are audited in the
state a phone reader actually sees.
The fold control keeps a 40px square target on the drawer, past the 24px floor
of WCAG 2.2 SC 2.5.8 and small enough that the eleven closed groups still fit
one screen, and it restates the two eyebrow-header rules that the row wrapper
would otherwise stop matching.