Seven comments in the library and the app pointed at probes, checks, a report or research notes that
live outside the repository, where a reader of the code cannot follow them. Each now states what was
found and drops the path: the engine-predicate equivalence, the chooser's globe-fill measurement, the
fit-at-construction probe, the worldview clause, the web-boundaries sizes (1,866 KB to 383 KB, every
feature and part kept). The QA corner and the packet generator lose a dead pointer. The app's nav
comment states the three sections and the third dashboard directly instead of quoting a transcript.
17 of 25 library components that ship motion carried no reduced-motion rule, so
they animated regardless of the reader's OS setting.
The reason it cannot be fixed once, centrally: a @media (prefers-reduced-motion)
rule in the host document does not cross a shadow boundary, and these render
inside one. Measured while surveying: NO generated leaf page ships such a rule
at all — 0 occurrences across the whole built tree — so there was not even a
page rule to inherit. Each component owns its own.
CSS-ONLY AND ADDITIVE. Nothing but new @media blocks; no existing rule changed.
Verified by diff: 0 real removals across 17 files. The two lines git reports as
removed are a trailing comma moving as a new string was chained onto an existing
concatenation, and both original rules are still present — checked by grepping
for them, not by reading the diff.
WHERE MOTION CARRIES MEANING, it is kept rather than hidden:
· SemanticTreeLegend's spinner MEANS "loading". Stopped dead it is a static
ring that says nothing, so it is slowed to a step crawl (2.4s, steps(8)) —
visibly working, no smooth spin.
· LegendProgressBar's only motion is a hover filter, so it simply stops; the
bar's FILL is geometry, not animation, and still reports its value.
The rule goes where each component's styles actually go, and that varies more
than expected: 13 append into a useShadowStyles template literal, 3 into
string-concatenated sheets, and VerticalTabsLayout into its VTL_SHADOW_CSS
constant AND its duplicate <style> block, because its own header says the two
copies must stay identical.
check:reduced-motion asserts both halves, each mutation-tested to fail before I
trusted a pass: strip the rule from an animating component and it fails; move a
rule from the injected sheet into a <style> block and it fails too, because on a
useShadowStyles component that rule would never reach the shadow root. Both
mutated files restored byte-identical.
Two of my own errors caught by tooling rather than by review, and worth naming:
my first patch asserted useShadowStyles existed in every target and RAISED on
VerticalTabsLayout instead of silently skipping it — the assert-the-anchor habit
from the last registration failure working as intended. Then I appended CSS
after the label argument on two concat-built sheets, corrupting the injection
key; check:shadow-css-parses named both files and the fix was to insert before
the label. A gate I did not write caught what I got wrong.
Registered in all three places and verified by re-reading the parsed
package.json.
The QA widget comments (QaCorner, ProfileLoader, app-wrapper-material) say our own surfaces and the host's
session instead of naming one host; StackLayout describes a normal host page's flow; the live-cors script
note says it was measured on the live test host. Comments and notes only; no behaviour changes.
The QA widget's Start now: GET /api/orgs → mint an RS256 gateway token via
/api/o/<slug>/mcp/mint (reads access_token) → POST /sessions to qhoot (Bearer) →
open /qhoot/assembly.html?c=<code>. Verified end-to-end (qhoot 201). Backend side
(qhoot iss/aud aligned to the mint; mint signing key pinned to certified green-key-1)
handled on the app-shell/qhoot infra.
The QA panel now checks the go-base session via same-origin GET /api/auth/me and
shows 'signed in as X' + Start; if not signed in it offers 'Log in with Nuxtinator'
(opens the same-origin /plugin-assets/qa-connect.html popup, which reads the session
and postMessages the identity back). Works when the plugin is same-origin; under
NUXT_PUBLIC_PLUGIN_SANDBOX_ISOLATE_ORIGIN=true the frame is origin-null so the check
is blocked (browser rule) and the button surfaces that. Connect page shipped to the
mfe-index volume root.
The widget mounted but was invisible: as a CHILD component of the custom element,
its <style scoped> block was silently dropped from the shadow root (Vue keeps only
the ROOT component's styles), so position/z-index never applied → it laid out as a
static full-width block. Switch to useShadowStyles (same pattern as legend/table/
map-panel) → the pill now floats bottom-right. Verified headless: absolute,
z-index 2147483000, visible, bottom-right.
The widget rendered but was painted under map legends/panels and could be trapped
by a profile's full-bleed layout. Switch .qa-corner to position:fixed with a
top-of-stack z-index so it floats bottom-right over any map. (Plugin-open path
fixed separately in convert.py: a plugin now opens its representative MAP page,
not the multi-map staging directory — faster load + the widget shows.)
Adds library/components/qa/QaCorner.vue — a bottom-right floating 'QA' button +
panel (OIDC-onboarding shell: 'Log in with Nuxtinator', no key), rendered by
ProfileLoader over any profile. OPT-IN via profile-config.qa (default OFF) so the
same bundles that power partner embeds never show a QA button; the SPA shell sets
qa:true on every mount so it appears on all maps in the power app. Backend (qhoot /
nuxtbase-baas agent bridge + MCP) wired in a later pass — this is the visible shell.
Spec: _qa-cycle/01-ideation-research/qa-loops/qa-embeddable-qa-agent-bridge.md