Skip to content

Docs V2: full Docusaurus rebuild - #2

Draft
paulmatthis wants to merge 53 commits into
mainfrom
docs-v2
Draft

Docs V2: full Docusaurus rebuild#2
paulmatthis wants to merge 53 commits into
mainfrom
docs-v2

Conversation

@paulmatthis

@paulmatthis paulmatthis commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Full rebuild of the FreeMoCap documentation site on Docusaurus, replacing the placeholder currently live at docs.freemocap.org. docs-v2 has no shared git history with main as it was built from a tarball rather than a clone), meaning this diff is a complete replacement.

  • Full information-architecture rebuild (Beginner/Intermediate/Advanced tiers, concepts/tutorials/guides/reference/about split), not a reskin.
  • All content pages (docs/, concepts/, build-docs/, stub-docs/) have real content and have been through a line-by-line accuracy audit against current polyrepo source (ox-alpha-docs-experiment/LINE-BY-LINE-AUDIT-REPORT.md and CODE-BUGS-FOUND.md have the full methodology and findings).
  • Per-repo provenance banners (AI-generated vs. human-checked) and an in-flux banner for content expected to change before beta.
  • npm run typecheck and npm run build:local are clean.

Deploy aka why this is a draft

This repo's deploy.yml now mirrors freemocap_dot_org's proven pattern: manual workflow_dispatch only, i.e. never triggered by a push or merge. SamKirkland/FTP-Deploy-Action to a docs-scoped FTP account on Paul's VPS host. The two required secrets (DOCS_FTP_USERNAME,DOCS_FTP_PASSWORD) are required and have already been set.

That said, merging this safely (with minimum downtime, and without breaking the docs.freemocap.org/documentation/* content that's separately live today) needs a specific sequence. See DEPLOY-PLAN.md at the repo root for the full internal runbook: the GitHub Pages timing risk on merge, what's actually live today, a draft V1-to-V2 redirect mapping (three rows still need a pick), and the step-by-step cutover order. That file is temporary and gets deleted once the cutover is done.

As such, this PR was opened as a draft. This is ready for real review now, but shouldn't be merged or DNS updated until the DEPLOY-PLAN sequence is confirmed accurate and prepared:

  • Pages disabled
  • redirect rows decided
  • VPS content verified

Known non-blockers

  • V2's data model is still being finalized in alpha, meaning build-docs/ and a few data-model-adjacent pages carry an in-flux banner rather than being held back entirely.
  • The ground-plane calibration .mp4s from the legacy site (~24MB) aren't vendored into this repo yet, tracked in README.md known-issues list.
  • Two license fixes (skellydocs, skellypings) are sitting in local clones, and have not yet been opened as PRs against those repos.
  • /build/ is a stand-in/WIP pending the core freemocap repo's own docs consolidation and upgrade to beta.

Test plan - instructions to run a local build in README

  • npm run typecheck
  • npm run build:local
  • Walk through DEPLOY-PLAN.md's cutover sequence before merging
  • Resolve the three undecided redirect-mapping rows
  • Identify what actually serves docs.freemocap.org/documentation/* today, so it isn't silently orphaned by the cutover

paulmatthis and others added 30 commits August 19, 2026 15:55
Docusaurus aggregator delivered for the docs.freemocap.org V2 uplift, plus
the coordinate-conventions content, navigation, and homepage fixes from the
initial review session.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Navbar sections now expand on hover instead of requiring a click, with a
two-level flyout for Tutorials (tier, then page) since Docusaurus's stock
dropdown rejects nested dropdowns outright. Removes the dropdown carets and
the Skelly University sidebar entry (it's link-only via the homepage's
coming-soon card for now).

Replaces the footer with a full sitemap grid matching the navbar, a social
icon row, and the About section's links as plain text below it, following
the ethereum.org /learn footer pattern. The navbar dropdowns and the footer
both read from one new src/data/sitePages.ts instead of hand-duplicating the
same ~65 links in three places.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The on-site placeholder had nowhere real to send readers. Links directly to
github.com/freemocap/university instead, opened in a new tab, and the badge
shows the URL rather than repeating "Coming soon" under a heading that
already says it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The drawer (.navbar-sidebar) was collapsing to its own brand-row height on
mobile instead of filling the viewport, hiding every item below it. Forcing
height explicitly works regardless of why the implicit fixed-position
stretch wasn't.

Tutorials needed more than that: its hover-flyout component has no mobile
form, since Docusaurus only builds separate desktop/mobile renderings for
its own stock item types. It now reads the `mobile` prop Docusaurus passes
to every navbar item and renders a genuine two-level tap accordion for the
drawer, tiers then pages, using the same Collapsible primitive Docusaurus's
own sidebar uses, instead of the flat single-level dropdown a first pass
fell back to.

Also makes the mobile menu's expand/collapse caret visible as its own tap
target. Infima already gives it a rounded box and background, but only on
:hover, which never fires on touch, so the two-targets-per-row split (link
navigates, caret expands) was invisible on mobile.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The label became "About" a few sessions back, but the URL stayed
/community/, which was misleading and, per the fetched SkellyCam docs'
stale /community/roadmap reference, an actual broken link waiting to
happen once /community/roadmap moved. Renames docs/community/ to
docs/about/ (about.md to about-us.md specifically, so it doesn't route to
the redundant /about/about), updates every internal reference, adds V1
redirect targets and a /community/* -> /about/* bridge for anything that
already linked to the old paths, and fixes the hardcoded rewrite target in
fetch-external-docs.mjs that was pointing SkellyCam's roadmap link at the
old URL.

Also adds PREVIEW.md with quick-start instructions for reviewing this
branch in a browser.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was never a reason for docs.freemocap.org to have its own download
page: the real one, with OS/GPU detection and a release selector, already
lives at freemocap.org/download. The plan to "lift it wholesale" assumed
otherwise. Deletes the placeholder page and points the navbar's Download
item straight at the external URL instead, same pattern as the Code link.
Also fixes the archival redirect for the old interim site's
/freemocap/download, and extends fetch-external-docs.mjs's existing
link-rewrite mechanism to catch SkellyCam's own /download references,
which the build caught pointing at a page that no longer exists.

Also drops the "about-us exists twice" known issue: it's a non-issue, two
different sites are allowed to each have their own about page.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Four pages were stubs blocking real links: /start/, /concepts/what-is-freemocap,
/concepts/accuracy-and-limits, and /concepts/data-model. The latter two were
the sitemap's own self-identified highest-value gap ("the pages that decide
whether a researcher trusts this project"), and both had a direct source
sitting unused: Cherian's dissertation validation study (gait/balance/
prosthetic alignment against a marker-based reference) plus the array-shape
facts the sitemap had already extracted from skellymodels in code.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The homepage had four flat, equal-weight sections and no signal for a
first-time visitor to know they could stop reading, or for a returning one
to skip ahead, exactly the "too many docs" overwhelm problem the project
wants to stay clear of. Restructures around the curriculum DAG's own
1000/2000/3000 progression instead:

- TierPicker: three big Beginner/Intermediate/Advanced boxes right under
  the hero, the primary router, each jumping to its matching section.
- Each tier holds a fixed-width tile grid, one small box per page (icon,
  one-line blurb, and a "?" tooltip with a real bulleted table of contents
  for wherever it links), replacing the old per-section cards plus a
  separate flat "more links" list.
- The Advanced tier carries three specialization-track tags (Technology /
  Science / Art, matching the DAG's 3100/3200/3300 split) that link to the
  real per-track module content in freemocap/university, verified to
  exist via the GitHub API rather than guessed.
- Accent color switched from an unrelated light blue to the cross-org
  teal/green already defined in freemocap.org's own main.css, matched
  per-theme (green for light mode, teal for dark) since a single flat
  value read weak against both a white and a near-black background.

Adds react-icons (Feather set) for the per-tile icons, no other new
runtime dependencies.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… tooling

npm run lint:prose had never been run locally (vale wasn't installed).
Running it surfaced two tooling gaps rather than prose problems: the
domain vocab list was missing recurring terms (intrinsics, extrinsics,
realtime, posthoc, addon), and vale sync's locally-downloaded Google
style package was untracked and about to get committed by accident.
Gitignore it, CI's vale-action manages its own copy and never reads
this one.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ch. 2-4 of Cherian's dissertation (the same validation study behind
accuracy-and-limits.md and data-model.md) map directly onto the site's
remaining /concepts/ stubs: the field's history and landscape, the
four-stage pipeline, cameras and synchronization, pose estimation, and
calibration. All nine /concepts/ content pages the sitemap called for
now exist.

Calibration's math is deliberately kept conceptual, with a pointer to
triangulation.md's existing equations for anyone who wants the
derivation, rather than standing up a second equation-heavy page for
the sibling half of the same math.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
concepts/index.md now links all eleven /concepts/ pages instead of
sitting as a stub itself.

The four tutorials (multi-camera positioning, calibration best
practices, post-processing, choosing a tracker) round out the action
plan's suggested sequencing, sourced from the same dissertation.
Scoped deliberately not to duplicate what /concepts/ already explains:
better-calibration.md is the proactive counterpart to the existing
reactive troubleshooting guide, and choose-a-tracker.md points at
accuracy-and-limits.md's numbers rather than restating them a third
time.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The dissertation isn't the right source for software-usage pages, these
needed FreeMoCap's actual V1 Writerside docs and V2 architecture docs
instead. Both are reachable via `gh api` even though this site's
automated fetch script doesn't pull them yet (data/repos.yml sets the
core repo's docs_path to null on purpose, pending its own 34-page
consolidation).

custom-pipeline.md is deliberately shallow: the real architecture doc
is ~300 lines of backend internals (IPC flags, ONNX sessions), not
end-user tutorial material, so this points to it instead of
reproducing it at the wrong altitude. analyze-in-python.md had no doc
source at all ("NEW" in the sitemap); built instead from data-model.md's
already-verified schema, generic pandas against real column names
rather than a claimed API.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Same real-source approach as the previous commit. posthoc-mocap.md's
source is notably human-authored, not AI-drafted like everything else
pulled this session (its own frontmatter says so), so it keeps both of
its documented Alpha-build bugs verbatim rather than smoothing them
over. blender-export.md here is deliberately a short companion to the
fuller tutorials/blender.md rather than a second full copy that could
drift out of sync with it.

cite-freemocap.md resolves a real discrepancy: CITATION.cff's DOI field
(zenodo.1234) is an unfilled placeholder, not a working ID. Uses
Zenodo's own concept DOI instead, verified live against Zenodo's API,
with a note so nobody trusts the placeholder if they check CITATION.cff
directly. That placeholder is still worth fixing at the source
(freemocap/freemocap, a different repo) since every citation of this
software downstream inherits it until then.

see-your-results.md was still a stub despite being step 3 of the main
/start/ onboarding flow, one click from the homepage.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Went back through the full stub inventory and, this time, checked each
page against real source before assuming it needed one, rather than
just working down a list:

- recording-structure.md: same source as tutorials/find-your-data.md,
  rewritten as a terse spec instead of a walkthrough.
- rest-api.md, websocket-api.md: real source exists but is ~300+ lines
  of byte-level binary protocol and internal implementation detail
  aimed at this app's own frontend developers, mixed with an explicitly
  labeled "planned redesign" that isn't current. Wrong altitude and a
  real risk of documenting an API that doesn't exist yet as if it were
  current, wrote high-level orientation instead and pointed at the real
  source for anyone building against it.
- system-requirements.md: no single doc source, but enough
  already-verified facts across this session's other pages to assemble
  an honest one.
- export-formats.md: the stub's own title claimed FBX, BVH, and glTF.
  Checked the actual Blender addon source first: glTF is commented out,
  not implemented. Retitled to match reality instead of leaving the
  wrong title standing.
- reference/index.md, guides/index.md, about/index.md: trivial hubs.
- how-these-docs-are-written.md: documents the actual provenance
  frontmatter scheme and sourcing process this session used throughout,
  not a hypothetical policy.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Every page already carried provenance/reviewed/reviewed_against
frontmatter, but nothing rendered it, readers had no visible signal
about a page's sourcing at all. Swizzles DocItem/Content to inject a
banner above the content, reading the current page's frontmatter via
useDoc(), for any page that has a provenance value (external fetched
content like SkellyCam's docs doesn't, and is left untouched).

The banner is a small local component
(src/components/ProvenanceBanner), not skellydocs' AiGeneratedBanner:
that component hardcodes emoji into its icon set with no override prop,
and its three-valued GenerationType doesn't map cleanly onto this
site's two-valued provenance field anyway. The local version shows this
site's own provenance value directly and surfaces the actual
reviewed_against string when present, instead of a hardcoded assumption
that goes stale the moment a page gets a real review pass. Links to
/about/how-these-docs-are-written.

src/global.d.ts is a standard Docusaurus TS setup gap unrelated to the
banner itself: tsc can't resolve @theme/* type imports without ambient
declarations from @docusaurus/module-type-aliases and
@docusaurus/theme-classic, and nothing in this repo had swizzled a
component with a type-only import before now.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Standing style rule: no emoji anywhere. Found via a repo-wide scan
(first-recording.md's two pointer emoji, install.md's celebration and
troubleshooting emoji), removed with no other wording changes. Left
about-us.md's skull-and-sparkles line alone, explicitly exempted.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
lastVersion is 'current' and no other version has been cut yet (1.x
still isn't, on purpose, see HANDOFF), so the built-in 'unreleased'
banner's "see the latest version" link resolved to the exact page
already being read. Switched to banner: 'none' until 1.x actually
exists as something distinct to point to; the "2.0 (alpha)" navbar
label still communicates alpha status on its own.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…e background

Both were diagnosed in an earlier session and left unfixed. The
onBrokenAnchors check flags #beginner/#intermediate/#advanced as broken
on every build even though they work correctly, a confirmed limitation
with manually-added ids on custom React pages rather than MDX-generated
heading anchors. Set onBrokenAnchors: 'ignore' for that specific check,
onBrokenLinks stays at 'throw'. Build now produces zero warnings for
the first time this project.

Light mode rendered a transparent page background instead of white:
@freemocap/skellydocs only defines --ifm-background-color for
[data-theme='dark'], with no light-mode value anywhere including its
own :root. Added the missing light-mode value to this site's own
custom.css, which loads after the shared package's. #ffffff is
Infima's own standard light default, not a new color decision.
Verified with getComputedStyle rather than a screenshot, since
transparent-over-a-white-page and actually-white are visually
identical there.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
history: [{date, against}] replaces the single reviewed/reviewed_against
pair, newest entry first. Pages without the new array fall back to
reading their existing reviewed/reviewed_against as a one-entry history,
so none of the 75 already-shipped pages need migrating.

Also fixes a real bug hit while building this: gray-matter/js-yaml parses
bare YYYY-MM-DD frontmatter as a JS Date, not a string, which was
silently breaking the "Last reviewed" line sitewide (typeof !== 'string'
on every page). Normalizes Date values to ISO date strings instead of
silently dropping them.
…tructure the top nav

Version picker:
- Cut 1.x (legacy) as a real frozen version alongside 2.0 (alpha)
- current stays on banner: 'none' permanently, not just until 1.x exists:
  'unreleased' links to lastVersion, so as long as current IS lastVersion
  that banner is self-referential regardless of how many older versions
  exist. 1.x gets 'unmaintained' instead, which correctly points at a
  genuinely different, newer version.
- Restyled the stock version badge (was stark white-on-black on its own
  row) onto the breadcrumb row, right-aligned, using Infima's own
  emphasis-200/800 tokens so it inverts correctly in light mode too
- Restored Infima's own default caret for just the version dropdown,
  the one item in the bar with nothing else marking it as a switcher

Developer Docs section (new):
- /developers landing page with a polyrepo tree (SVG, generated from
  data/repos.yml's tier field, not hand-coded): Core alone on top,
  Pantheon connected by lines, Utility floating with no connectors
- New repos-data Docusaurus plugin (usePluginData) exposes repos.yml to
  browser-bundled components; data/repos.ts is the shared Node-side
  loader used by both it and docusaurus.config.ts
- Boxed "Developer Docs" navbar dropdown: Core/Pantheon/Utility/More,
  matching the tree's grouping and data source
- Every repo gets a real destination now, not a muted/unavailable state:
  the 4 utility repos got real routes in repos.yml, and all 7 repos
  without docs of their own yet got a short stub page (src/pages/<id>/)
  instead of being greyed out
- "Home > Developer Docs > ..." breadcrumb and a "Back to Developer
  Docs" sidebar link for /build/ and any repo instance with real docs
  (DocBreadcrumbs swizzle, driven by repos-data, not a hardcoded list)
- Hero copy: homepage tagline is now "User documentation for the
  FreeMoCap project.", developers page is "Developer documentation..."
- Footer: boxed "Developer Docs" link, right-aligned in the Get Started row

Nav restructuring:
- Concepts and Build no longer have their own top-level navbar dropdowns.
  Both are still separate Docusaurus instances under the hood (per-
  instance versioning for Concepts, Build standing in for a future
  fetched instance), but that's no reason for two more entry points.
- "Key Concepts" now lives inside the About dropdown/sidebar category,
  with the concepts pages as real sub-items, and sidebars/docs.ts and
  sidebars/concepts.ts are both generated from one shared tree
  (sidebars/sharedDocsTree.ts) so the sidebar's shape, order, and
  expand state never change crossing the docs/concepts boundary
- Build is reached through Developer Docs instead, its existing front door
Three short paragraphs plus two images between the tree and the closing
links row: a labeled composite image introducing the analogy, a
paragraph on independent-but-composed repos framed through it (without
naming the reference directly in the copy), and a paragraph on how
FreeMoCap tracks cross-repo compatibility in practice (data/repos.yml's
own tag-pinning convention), grounded in two external polyrepo-
architecture write-ups read directly rather than plagiarized. Closes
with a third image, centered below both paragraphs.
…ion reference

SkellyTracker, SkellyForge, SkellyBlender, SkellyLogs, SkellyPings, SkellyDocs,
and SkellySync all had docs_path: null in data/repos.yml, no docs site of
their own yet, so /developers pointed at short stub pages instead. Replaced
each stub with real developer documentation grounded directly in that
repo's own source (architecture, key modules/classes, how it's consumed by
the rest of the polyrepo), not ported from anywhere since nothing existed
to port. cli.md and configuration.md are the same move applied to two
gaps in the core freemocap repo's own reference docs: no CLI beyond one
console script, and deliberately minimal configuration surface, both
verified against the actual source rather than assumed.

Written by stealth/ox-alpha via OpenRouter, an experiment running a
tool-calling agent loop (read/list/write against the cloned repos) instead
of writing this content directly. See ../ox-alpha-docs-experiment/ASSESSMENT.md
for the full methodology, task-by-task attribution, and a performance
write-up covering both what worked and what needed correcting.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
roadmap.md pulls from the org's actual GitHub Projects boards (32 and 34),
counts snapshotted with an explicit date since they're a live source, not
a hand-maintained backlog. faq.md is the interim stand-in for the
Discord #help-requests export this project's docs have been blocked on:
sourced from real freemocap/freemocap GitHub Discussions Q&A, but not
transcribed as-is, each answer was checked against the current source
first and corrected or dropped where it described the pre-alpha release
rather than the current one (multi-person tracking and realtime support
both changed since the original answers were written). guides/index.md
gets a new "Quick answers" section linking to it.

Written by stealth/ox-alpha via OpenRouter; see
../ox-alpha-docs-experiment/ASSESSMENT.md for methodology and attribution.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Both pages were previously left as stubs on the reasoning that V2's data
model was being replaced and hadn't landed, so a precise reference would
describe something about to be thrown away. Revisited that call: rather
than continue waiting, read the actual current code to document what's
really there now, however messy, instead of guessing or staying silent.

Found two real systems coexisting, not one: SkellyTracker's
TrackerDefinition (what the frontend sees over the websocket handshake)
and SkellyForge's skellymodels ModelInfo (what actually names the columns
in output files), verified independently rather than assumed from a
stale HANDOFF note that treated one as legacy. In the process, found a
likely real bug worth a maintainer's attention (noted separately, not
fixed here): for RTMPose recordings, the aspect order used to slice
output arrays doesn't match the detector's actual emission order, so
hand and face data in the output files doesn't match its own labels.
Also documents a parquet filename that's declared canonical but never
actually written, and a reprojection_error column that's currently
always NaN.

Written by stealth/ox-alpha via OpenRouter; see
../ox-alpha-docs-experiment/ASSESSMENT.md for methodology and attribution.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
paulmatthis and others added 23 commits August 25, 2026 01:10
freemocap's own freemocap-docs/docs/architecture/ has 34 AI-drafted pages
(each carrying its own AiGeneratedBanner, meaning even the source isn't
independently human-verified) that data/repos.yml deliberately doesn't
aggregate live yet, pending this exact consolidation. Five pages here:
an orientation overview, backend (pub/sub, websocket server, calibration,
triangulation), frontend (providers, state management, styling), the
realtime/posthoc pipeline walkthrough, and building/packaging.

Cross-checked specific claims against the actual .py/.ts source rather
than porting the source docs verbatim, since they're AI-drafted and not
guaranteed current. Caught real drift in the process: the source docs'
claimed file line counts were stale (realtime_aggregator_node.py is 837
lines, not the ~621 claimed), the version number was stale
(v2.0.0-alpha.21 confirmed live in both the backend and frontend, not
the alpha.11/alpha.1 the source claimed), and the frontend has a
13th Redux slice (`connection`, with its own AppStateMessage server-state
sync pattern) that isn't documented in any architecture doc at all.

Written by stealth/ox-alpha via OpenRouter for architecture.md, directly
by Claude for the other four after two ox-alpha attempts hit budget/rate
limits; see ../ox-alpha-docs-experiment/ASSESSMENT.md for the full
breakdown and attribution.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…roposals

Five stubs the earlier pass missed. Three of them, the-map.md,
data-contracts.md, and repo-directory.md, turned out not to be writing
tasks: data/repos.yml's own header comment says they're meant to be
generated from that file, not hand-written ("Do not hand-write any of the
above. Change it here"), the same policy that already produces the
/developers polyrepo tree. Built three new components instead of prose:

- DataFlowDiagram (the-map.md): the data-contract chain (SkellyCam to
  SkellyBlender) derived generically from repos.yml's consumes/produces
  fields via a small topological sort, not hardcoded to today's 4-repo
  pipeline.
- DataContractsTable (data-contracts.md): the same data as a reference
  table, with a computed (not hand-entered) "consumed by" column.
- RepoDirectory (repo-directory.md): the full repo listing grouped by
  tier, including the utility repos the other two pages leave out.

All three follow the existing PolyrepoTree/usePluginData pattern. Required
widening the shared Repo TypeScript type in src/utils/repo.ts, which had
been trimmed to only the fields PolyrepoTree needed; the runtime data from
repos.yml already carried consumes/produces/domain/repo, so this is a
type-correctness fix, not a behavior change.

index.md and proposals/index.md are hand-written hubs. proposals/index.md
describes freemocap's one real in-progress design proposal (centroidal
kinematics / Reaction Mass Pendulum, extending the existing center-of-mass
tracking with real rotational dynamics), read from its actual source
rather than assumed from the filename, and links out to it rather than
vendoring a proposal that's still actively changing.

Written directly by Claude (ox-alpha was unavailable, a shared
upstream-provider rate limit rather than the account's own daily cap);
see ../ox-alpha-docs-experiment/ASSESSMENT.md for the full round writeup.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The generic "nothing here has been written yet" stub warning was
misleading for this specific page: the reason it's blank isn't that
nobody's documented an existing feature, it's that the feature doesn't
exist. Verified directly against the current source (no CLI flag, API
endpoint, or code path anywhere in the app), and framed carefully as
anticipated rather than confirmed, since there's no open issue,
discussion, or roadmap item actually committing to building it.

Found real prior art worth citing rather than presenting this as coming
from nowhere: a 2023-era V1 script, experimental/batch_process/batch_process.py,
did exactly this, looping recordings through processing headlessly. It
lived under an experimental/ path, never a supported feature, and didn't
carry into the V2 rewrite. Added two real workarounds for anyone who
lands on the page actually needing this today: scripting the REST API
per-recording, or processing one at a time through the UI as normal.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ran a full lint:prose pass across everything touched this session (24
files) and worked it down from 653 flags to 61, all individually checked
against source rather than bulk-suppressed. Most of the reduction is
here: legitimate technical vocabulary (library names, Python/JS terms,
domain-specific compounds) that Vale's base dictionary doesn't recognize,
added the same way intrinsics/extrinsics were added in an earlier
session, not by rewording working prose to dodge a spell-checker.

The remaining 61 aren't gaps, they're Vale rule limitations verified case
by case: two Vale.Terms categories that are correctly Title Case (page
titles, table headers, matching this project's own existing precedent for
that exception), real proper nouns/product names/enum values the Colons
and WordList checks don't recognize (React, JSON, Redux, Cloud Run, Cloud
Scheduler), headings that are already correctly sentence-cased but contain
an acronym or identifier, FAQ question headings correctly using first
person, a handful of misparsed non-list phrases, and one literal version
number the DateFormat check mistook for a date. Full breakdown in
../ox-alpha-docs-experiment/ASSESSMENT.md.

Also fixed several real regressions the cleanup scripts introduced along
the way (not included in this commit, folded into whichever earlier
commit already touched that file): broken links from casing scripts
touching URL path segments and file extensions outside backticks, and one
unrelated pre-existing MDX parse error in skellysync/index.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The 7 repos with no fetched docs source (SkellyTracker, SkellyForge,
SkellyBlender, SkellyLogs, SkellyPings, SkellyDocs, SkellySync) lived as
single bare pages under src/pages/, with no sidebar, breadcrumb, or
provenance banner. Move them into their own content-docs instances,
split along their existing sections so the sidebar is actually
navigable, matching the layout the core repo and SkellyCam already have.

Also widen the "Developer Docs" breadcrumb to show which repo a page
belongs to (e.g. "Developer Docs / SkellyForge / Data models" instead of
stopping at "Developer Docs"), consistent across build, fetched, and
these new local instances.
Replace the plain emoji PolyrepoTree rendered as SVG text with real
logos: the Skelly skull with an image matching each repo's emoji
pairing layered on top, based on SkellyCam's own existing logo design
(reused as-is, it already does exactly this). FreeMoCap core gets the
bare skull, no overlay. The other 6 repos' overlay icons (telescope,
wrench, clapperboard, scroll, satellite dish, book, sync arrows) come
from Lucide via react-icons, already a dependency here, matched one-for-
one against each repo's repos.yml emoji and licensed for this use
(ISC). The shared skull is the actual brand mark (logo-color-black-border.png,
inlined as a data URI so it survives being embedded via <image> inside
PolyrepoTree's own SVG, which sandboxes further external references).

The site's own navbar logo becomes the same skull-plus-book treatment,
reused for SkellyDocs.
Polyrepo tree now comes before the intro paragraph. Caption the
Skelly-Voltron image below it instead of above ("Sort of like this."),
matching normal figcaption placement, with the caption's spacing
flipped to match (margin-top instead of margin-bottom, now that it
trails the image instead of leading it).
--ifm-color-primary (custom.css) was 2.85:1 against white, below AA;
now 4.51:1, reusing the same darkened value freemocap.org's own
--accent-green-fill uses for the identical problem. Dark mode
untouched, it was already fine (8.87:1).

Separately, HomeSections.module.css's .buttonPrimary hardcoded the
same failing color independent of that variable, so the earlier fix
didn't reach it; same darkened value applied directly there, plus a
corrected hover shade (the old hover was actually lighter than the
new rest color, which would have inverted the hover-darkens
convention).

Verified live in both themes, typecheck and build:local clean.
@freemocap/skellydocs defines its whole --sk-* design-token set once
in :root, calibrated for a dark background (--sk-text near-white,
--sk-accent a light mint), with no light-mode variant anywhere in the
package. Against white: --sk-text 1.23:1, --sk-text-dim 2.17:1,
--sk-accent 1.52:1, --sk-purple 2.72:1, all failing AA badly. Consumed
~50 places in the shared theme.module.css plus locally in
ProvenanceBanner, which is where it was actually noticed (the
provenance flag text was "almost invisible").

Fixed with a local override in custom.css, not by editing the shared
package: --sk-text/--sk-text-dim darkened to match freemocap.org's
text-primary/text-muted (#000000/#5c5c5c), --sk-accent/--sk-purple
kept their own hue and darkened just enough to pass (4.5:1+), same
treatment as the site's other accent colors, not flattened to black.

Also removed ProvenanceBanner's .unchecked opacity: 0.6, which
compounded with even the fixed --sk-text-dim to still fail at 1.55:1;
the color tier alone now carries the de-emphasis.

Verified live in both themes (general dim text and the specific
unchecked-badge case), typecheck and build:local clean.
Previous fixes (this session) only addressed the specific spots
reported at the time; light mode as a whole was still "almost
uniformly too gray and unreadable." Root-caused properly this time
instead of continuing to patch one element per report:

- Almost every border (cards, buttons, pills, tooltip) and secondary
  text (dropdown headers, card descriptions, tags, footer links) in
  this codebase reads from Infima's --ifm-color-emphasis-0..1000
  scale. The stock light-mode scale was too light across the whole
  range actually used here, borders as low as 1.17:1 against white,
  text as low as 1.77:1, not just below AA but below the 3:1 non-text
  minimum in several cases. Recomputed the full scale for real: 100
  stays a light background-only tint (never used as a border here),
  200-400 (border use) now clear 3:1+, 500-700 (text use) clear
  4.5:1+ and pushed further since barely-passing still read as too
  gray in practice, 800-1000 were already fine. Infima-derived tokens
  like --ifm-footer-link-color inherit this automatically, confirmed
  live (footer links, search placeholder, dropdown headers all fixed
  with zero additional changes).

- --ifm-color-primary was fixed to green/teal earlier, but Infima
  auto-derives 6 shades (dark/darker/darkest/light/lighter/lightest)
  from a single base at build time, and overriding just the base
  doesn't touch them. Anything using a derived shade was still
  rendering skellydocs' original purple, a wrong hue, not just a
  contrast problem. Computed correct derivatives for both themes at
  the same ~8% HSL step Infima's own generator uses.

- Two more instances of the same bug already fixed once in
  ProvenanceBanner: an opacity multiplier compounding with an
  already-correct color to fail anyway (.cardMuted's 0.75, used only
  by the Skelly University "Coming Soon" card, taking its border back
  down to 2.19:1). Removed; the dashed border/color tier alone already
  signals "different," doesn't need opacity on top.

- The 7 composite repo logos (not the bare FreeMoCap skull, not
  SkellyCam's own real art) bake opacity="0.55" into their <image>,
  muting the skull by blending toward whatever's behind it. The
  containing box's fill is either theme-reactive
  (var(--ifm-color-emphasis-100)) or transparent, so in light mode
  that blend target is near-white and the skull washes out, "lightened"
  rather than staying dark. Added a fixed #0a0818 rect behind every
  logo (the exact dark background the composites were originally
  tuned against), so the muting looks the same in both themes.
  Fully-opaque images (the bare skull) render over it with zero
  visible difference.

Verified live in light mode across the homepage, developer docs tree,
and footer, screenshotted, typecheck and build:local clean.
The previous commit's blanket redefinition of the whole
--ifm-color-emphasis-0..1000 scale broke Infima's own navbar search
input: its background is emphasis-200, and darkening 200 for border
visibility turned the background dark while the (already-dark) text
stayed dark too, unreadable dark-on-dark. Confirmed the same conflict
exists in Infima's stock BackToTopButton and ColorModeToggle before
trusting this again (both background: emphasis-200). 0-400 are back to
Infima's stock light values; genuinely-visible borders now use a new,
dedicated --fmc-border-strong (4.54:1), applied only where this
project's own CSS explicitly opts in (HomeSections, PolyrepoTree), not
inherited through the shared scale. 500-900 stay as the darkened
values, grepped Infima's stock theme, skellydocs, and this site's own
components first this time to confirm nothing else uses that range for
backgrounds.

Three more reports, each real:
- Hyperlinks still read as "too light green" even at the previous
  4.51:1 fix. Darkened --ifm-color-primary further to #375a59 (7.58:1),
  same hue, recomputed its 6 auto-derived shades to match.
- Card text still read as "too light gray" even at the previous 9:1
  (--ifm-color-emphasis-700). Past-AA isn't the actual bar here;
  pushed to #333333 (12.63:1).
- The fixed-color rect behind muted logos (previous commit) stopped
  the wash-out but showed as a visible black box around the skull.
  Replaced with the same rect masked to the logo's own alpha channel
  (mask-type: alpha, not the default luminance*alpha, which would mask
  unevenly across the skull's own dark linework), so the dark fill only
  shows through the actual skull silhouette.

Verified live (fresh tabs, re-checked values after first reads kept
catching CSS transitions mid-flight rather than settled state):
search bg #ebedf0 text #2b2b2b again, hero link #375a59, card text
#333333, card border #767676, logo mask renders as the skull's real
shape with no visible box. Typecheck and build:local clean.
Byte-identical copy of logos/freemocap.svg (the bare skull, no
overlay), replacing the skull+book composite that matched
logos/skellydocs.svg. Copied at the file level rather than through an
edit, this file is a single-line SVG with a large embedded base64
PNG blob, not something to retype through a diff.
…urce

Every one of 139 pages checked against the actual polyrepo source and
corrected where wrong, closing the "not yet checked against current
software" gap every AI-generated page has carried since it was written.
98 pages got a real factual correction; the rest were confirmed already
accurate. Every page's frontmatter now carries a real history audit-trail
entry (date + what was actually re-checked) instead of the placeholder
reviewed/reviewed_against pair.

Run via an adapted OpenRouter stealth/ox-alpha harness for 114 pages,
until that model became permanently unavailable (zero live endpoints,
consistent with its promotional preview window ending); the remaining 25
were done directly using the same verification methodology by hand.

Full process, both prompts used verbatim, and an effectiveness assessment:
../ox-alpha-docs-experiment/LINE-BY-LINE-AUDIT-REPORT.md (outside this
repo). 29 real, non-documentation code bugs found across 6 repos along the
way, documented but not fixed here since that's out of scope for a docs
pass: ../ox-alpha-docs-experiment/CODE-BUGS-FOUND.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Readers of build-docs/ and the data-model-adjacent pages have no way to
tell those pages apart from the rest of the site, which just finished a
full line-by-line accuracy audit. Both areas are accurate today but are
known to be temporary: build-docs/ is a stand-in for the core freemocap
repo's own developer docs (still being consolidated there), and the
data-model pages describe the current V2 output format, still being
finalized during alpha ahead of a beta relabeling.

Reuses the existing ProvenanceBanner pattern rather than inventing a new
mechanism: a new InFluxBanner component, wired into the same DocItem/Content
swizzle, triggered by a new `inFlux` frontmatter string. Applied to all 14
build-docs/ pages and the 4 pages HANDOFF.md's "Still open" item 2 already
names as data-model-adjacent. Colors are real, checked contrast values
(7.09:1 light mode, 11.86:1 dark mode), not eyeballed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This site never had its own LICENSE file or a declared license field,
unlike every other repo in the polyrepo (all 9 confirmed to genuinely
ship real, complete AGPL-3.0 text, not just claim to). Found while
auditing licensing consistency across the org at the user's request,
which also caught a real mismatch in SkellyDocs (package.json said MIT
against its own correct AGPL-3.0 LICENSE file, fixed in that repo's local
clone, not yet a real PR) and a missing declaration in SkellyPings (also
fixed locally). LICENSE text copied verbatim from another repo's verified
copy rather than retyped, to avoid transcribing a legal document by hand.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rewords the banner's fixed lead-in ("This page is in flux.") and every
per-page note to one consistent template ("<Section> for FreeMoCap core
is a work in progress for version alpha. It will stabilize upon beta
release."), replacing two different framings (a "stand-in, will move"
message for build-docs/ and a separate "finalizing during alpha" message
for the data-model pages) with a single voice across all 18 pages. Also
syncs package-lock.json's own metadata after npm picked up package.json's
new license field on the last build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces the plain Voltron edit with the version that overlays each
repo's actual name and role icon (SkellyCam, SkellyTracker, SkellyForge,
SkellyBlender, FreeMoCap Core), matching the existing alt text without
needing a separate legend.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Data-contract labels (synchronized_frame_packages, keypoint_observations,
kinematic_models) were rendered in a fixed-width gap between boxes that
was narrower than the label text, so adjacent labels visually ran
together into one unreadable string. Each edge's gap now sizes to its
own label's width instead of a uniform constant, with box x-positions
computed cumulatively rather than on a fixed grid.

Separately, the first/last box's stroke was centered exactly on the
viewBox boundary, so half of it got clipped by the SVG's default
overflow:hidden, more visible at some render scales than others. Added a
small canvas margin so no box edge touches the boundary.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Navbar logo now uses skelly-docs-site-logo.png (a lighter skull+book mark)
instead of the old logo.svg. SkellyCam's polyrepo-tree card now uses the
same muted-skull-plus-Lucide-icon treatment as the other 7 repos (LuCamera)
instead of its own hand-drawn art, which didn't match; that real art is
kept as skelly-cam-site-logo.svg for wherever it's actually needed.
Also tightens the Skelly University card's blurb and notes it will offer
microcertification.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…PLAN

The prior deploy job was a speculative SSH/rsync draft to a VPS with
secrets (DOCS_VPS_HOST etc.) that never existed on this repo. Rebuilt it
to mirror freemocap_dot_org's own proven pattern instead: workflow_dispatch
only, never on push/merge, FTP-Deploy-Action to the same Plesk box but a
docs-scoped FTP user (DOCS_FTP_USERNAME/DOCS_FTP_PASSWORD, now set) whose
home directory is already the docs.freemocap.org document root.

DEPLOY-PLAN.md is a temporary, internal cutover runbook: the Pages/Jekyll
timing risk on merge, what's actually live at docs.freemocap.org today
(a placeholder plus a separate /documentation/* legacy site whose real
origin is still unidentified), a draft V1-to-V2 redirect mapping, and the
step-by-step sequence for a minimum-downtime cutover. Delete it once the
cutover is done; the README's own Deploy section covers the steady state.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
README had drifted from reality in several places: the /community/ route
was renamed to /about/ weeks ago, the utility-repo count was off by one
(four, not three), a dangling reference to a planning doc that lives
outside this repo, and a hardcoded rewrite count that will drift as
SkellyCam's upstream docs change. The "known issues" list still claimed
/guides/ was a stub and that the 3d_xyz/rigid_3d_xyz question was open;
both were resolved or declared moot weeks ago and saying otherwise here
is actively misleading to a public reader. Replaced with what's actually
still open (data-model alpha instability, curriculum tier reconciliation)
and folded the missing calibration-video note in as a numbered item
instead of its own oddly-framed section.

Also fixed: the download-page note conflated freemocap.org/download's
301-to-download.html redirect with this domain; reworded to be explicit
that docs.freemocap.org/download should never exist at all, the real
flow lives entirely on the main site.

PREVIEW.md (a temporary branch-preview guide) removed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Uses the 'ours' merge strategy: this commit records main as a parent so
GitHub will accept a pull request between the two branches, but the tree
is taken entirely from docs-v2, unchanged. No files from main are pulled
in. This PR is a full-site replacement, not an additive merge.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@philipqueen

Copy link
Copy Markdown

@paulmatthis Is this deployed anywhere right now? It would be nice to be able to scroll through the site as it will look.

@jonmatthis

Copy link
Copy Markdown
Member

@paulmatthis Is this deployed anywhere right now? It would be nice to be able to scroll through the site as it will look.

The README has instructions on how to build locally (tldr - npm i, npm start)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants