render per-dataset validation reports on dynamical.org#82
Draft
mrshll wants to merge 19 commits into
Draft
Conversation
- Add --radius-sm/md/lg tokens mirroring colors_and_type.css
- .hero-cta: drop uppercase, letter-spacing, and color transition
(BRAND.md bans uppercase + wide tracking; hover is instant);
align padding/font-size/radius to the ghost-button spec
- #latest-popup: 8px → --radius-md (4px) per spec
- Add og:image meta (icon-1024.png) and drop duplicate og:type
- Remove vendored brand assets in public/{favicon.ico,apple-touch-icon.png,
assets/{favicon,lockup,lockup-white,icon}.svg} — BRAND.md says link to CDN,
don't rehost. Site already references the CDN-hosted copies.
Nav lockup left on the <picture> light/dark swap: the brand spec suggests
neutral lockup.svg with currentColor, but currentColor doesn't propagate
into <img src>, so the swap is the correct working pattern.
Ports reformatters' src/scripts/validation/render.py pipeline into an 11ty page so /catalog/<id>/validation/ serves the same content as the standalone HTML on R2 — markdown-it (commonmark+tables) plus the five post-process transforms, sidebar TOC with per-variable checkbox toggle, image refs resolved against the report's baseUrl. Adds _data/validationReports.js that fetches validation_summary.md for each STAC dataset (skipping 404s silently), and surfaces both the on-site link and a "raw" fallback on the catalog dataset page.
The validation report page now extends base.njk and uses main.css for typography, links, and base table styling. The TOC moves from a fixed full-height overlay into the page flow as a sticky sidebar to the left of the report body — it stays on-screen as you scroll, and collapses to an in-flow block on narrow viewports. Drops the bespoke font/body/link CSS that duplicated main.css.
Deploying dynamical-org with
|
| Latest commit: |
ab30bcd
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://1050315a.dynamical-org.pages.dev |
| Branch Preview URL: | https://feat-onsite-validation-repor.dynamical-org.pages.dev |
The TOC now sits to the left of the centered max-width report body on wide viewports and stacks above it on narrow ones. Variable checkboxes and all/none controls are removed — the variable list in the TOC stays as plain anchor links. The toggle JS is gone with them.
Content body now uses the same max-width as every other catalog page (78rem, centered) so it sits in the same horizontal position. The TOC lives in a 'rail' anchored just outside the wrapper's right edge — it takes no space in the main column, stays sticky as you scroll, and collapses to an in-flow block above the content when there isn't room for it beside the body (~1180px breakpoint).
Rail anchors outside the wrapper's left edge again; TOC items are right-aligned so they sit flush against the content's left edge. Drops the H2 bottom-border underline and the variable section top-border that were running across the content area.
The site's main.css applies a perimeter border + horizontal margins to <article> (intended for blog/update posts), so the report body was picking up an unintended box. Use a plain <div> instead. Also drops the right-align on the TOC text — items render left-aligned as the user prefers.
Exports annotateHeadings(), buildTocHtml(), CSS, and JS. Given HTML already produced by a markdown renderer, annotateHeadings adds ids to every h2/h3 and returns the headings list in document order; buildTocHtml turns that into a nested <ul> with h3s grouped under their preceding h2. CSS handles the nested tree, collapse-when-inactive on h3 children, and a ▸ indicator on the active link with a reserved padding slot so toggling .active doesn't reflow neighbours. JS uses an IntersectionObserver with a top-30% active band to mark the deepest in-view heading active and expand its parent h2. Page templates put the article body inside .md-toc-content and the TOC inside .md-toc; the JS keys off those classes.
Slims validation.11ty.js to validation-specific work — png link target=_blank, per-variable plot injection, table-scroll wrapping, asset-URL rewriting against the report's baseUrl — and delegates the TOC build + scroll-spy + ▸ indicator to lib/markdown-toc. Variable headings are now annotated with normal H3 ids (the slug of the variable name), so they show up nested under 'Per-variable details' in the TOC like any other H3. The old special 'Variables' group and its custom anchor scheme are gone.
- Generate the page H1 from the catalog entry name ('<name> validation
report') and strip any H1 the rendered markdown produces. Anticipates
reformatters#614 which drops the H1 from validation_summary.md;
still looks right against the current (pre-#614) bucket output.
- Move the TOC rail inside .validation-body, after the breadcrumb and
H1. On wide viewports the rail still absolute-positions out of flow
into the left margin (containing block stays .validation-wrapper).
On narrow viewports it goes static and renders directly below the
H1 — not above the breadcrumb as before.
- Narrow mode drops the indicator and the nested subheaders: the TOC
becomes a flat list of H2 links right under the title. The scroll-
spy keeps running but its visual effects are CSS-suppressed; the TOC
is off-screen once you scroll past it anyway, so the spy isn't
useful there.
- TOC rail gets a right border to separate it from the body content.
- Long heading names ellipsis-truncate inside the narrow TOC column
(e.g., 'downward_short_wav…' instead of overflowing).
- TOC right border moves from .validation-toc-rail (full wrapper
height) to .md-toc itself, so the vertical line is only as tall as
the visible TOC content.
- TOC list items get font-weight: inherit so the global
'nav ul li:first-child { font-weight: 700 }' rule from main.css
(intended for the brand lockup in the site nav) no longer leaks into
the TOC and bold the first heading.
- Markdown tables now wrap in <div class="table-container">
<table class="data"> — same pattern as the catalog dataset page.
Drops the bespoke .table-scroll CSS in favour of main.css's shared
table styling, so validation tables look consistent with the rest of
the site.
… rail Audit + minimize CSS introduced for the validation page: - Replace .validation-wrapper with the site's existing .content class (already supplies max-width:78rem + centered margin). - Drop .validation-body, .validation-breadcrumb, and the .validation-body h2/h3 margin overrides — the site's base type rules handle these. - Move .md-toc-rail + .md-toc sticky/border/font-size + narrow-viewport collapse rules from validation.11ty.js into lib/markdown-toc.js so any future markdown-driven page that opts into .md-toc-content gets the rail behavior for free. - Stop wrapping markdown tables in .table-container (main.css gives it overflow-x:auto, which was clipping/scrolling the validation tables); just apply class="data" to the <table> so tables overflow naturally. Page-specific CSS shrinks to just the .plots block under per-variable H3s, which is the only truly validation-specific styling.
.table-container previously clipped wide tables to .content's 78rem max-width and scrolled inside even on wide viewports where the table could be shown in full. Switch to width:max-content + viewport-based max-width + relative+translateX(-50%) centering so: - Narrow viewport (table > viewport): scroll horizontally inside the container, same as before. - Wide viewport (table fits in viewport but not in .content): table renders at full width, visibly overflowing .content into the page margins. Restore the .table-container wrapper on validation report tables — the new wrapper behavior is what we want there too. TOC rail tweaks per request: - width 18rem -> 22rem - gap to article 2rem -> 4rem - right border uses --popup-border (lighter grey) instead of --border-muted-color so it reads as a quiet divider rather than a hard rule against the body text; padding-right 1rem -> 2rem to keep the toc text from sitting on top of the border.
It produced a worse outcome than the original problem: max-content sizing forced tables to render at their unwrapped natural width, so markdown tables with long URL values stretched all the way across the viewport instead of wrapping to fit the column. Back to plain overflow-x:auto. Tables wrap inside .content's 78rem and scroll horizontally when their content truly doesn't fit.
max-width: 100% is the same value default block sizing already gives, written explicitly so the intent — wrapper stays anchored to the article column (.content), scrolls horizontally when the table inside is wider — is obvious at the rule. This is the catalog small-screen scroll aesthetic for any table that's wider than .content: the wrapper clips at the column edge with native horizontal scroll, rather than the table breaking out past .content into the page margins.
.table-container now shows a 1px border + Bayer-style 1-bit dither shadow at any edge where content overflows. Uses the local/scroll background-attachment trick: content-anchored covers hide the viewport-anchored border and dither image when the content edge sits at the viewport edge. Shadow is baked into an inline SVG (14x4 tile, mirrored via SVG transform for the right edge) so the same trick applies without masks. Themed for light/dark via shadow-dither-l/-r custom properties.
The single-pass regex could reconstitute a tag from nested input like <scr<script>ipt> — flagged by CodeQL js/incomplete-multi-character- sanitization. Loop until no more replacements happen so the stripped text can't reintroduce a tag. No real exposure today (markdown-it commonmark mode disables raw HTML and the validation input is trusted), but the fix is cheap defense-in-depth.
The IntersectionObserver-based scroll-spy tracked transitions into a `passed` map. Jump scrolls (e.g. clicking a TOC link from far down the doc) move headings from above the viewport straight to below the active line without crossing the intersection area — IO's isIntersecting stays false, no callback fires, and stale `passed=true` flags survived. The last passed heading in document order wins, so the marker stuck on the section just before the user's prior position instead of moving to the clicked target. Compute the active heading directly from live bounding rects on each scroll instead. Same top-30% active-line model, no transition tracking.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
src/scripts/validation/render.pypipeline into an 11ty page sodynamical.org/catalog/<id>/validation/serves the same content as the standalone HTML on R2._data/validationReports.jsto fetchvalidation_summary.mdfor each STAC dataset (silently skipping 404s; only datasets with a published report get a page).validation_report_hreffrom STACassets.validation_reportthrough_data/catalog.jsfor the deeper fallback path.Test plan