Skip to content

Fixups - #27

Open
CS-5 wants to merge 20 commits into
overhaul/10-seofrom
overhaul/10b-carson-fixes
Open

Fixups#27
CS-5 wants to merge 20 commits into
overhaul/10-seofrom
overhaul/10b-carson-fixes

Conversation

@CS-5

@CS-5 CS-5 commented Sep 6, 2026

Copy link
Copy Markdown
Member

No description provided.

CS-5 and others added 17 commits September 1, 2026 15:36
Drop oxlint, oxfmt, the vendored nkzw and anti-slop rule sets, and tsgo.
ESLint (strictTypeChecked + stylisticTypeChecked, astro jsx-a11y-strict)
now lints every .ts/.js/.astro file and Prettier formats everything,
Markdown included. functions/ and tools/ typecheck with tsc. ADR 0012
records the decision and supersedes 0001.

tools/**/*.mjs become TypeScript run directly by Node; a tools/tsconfig
enforces erasable syntax. Shared walk() lives in tools/lib/fs.ts.

CI collapses to one workflow with a shared setup action and three
parallel jobs: check (every step reports, ESLint findings annotate the
PR), build (metadata + link check, dist artifact), lighthouse (scores
and failed assertions in the job summary). mise.toml keeps only the
toolchain pins and the Chrome tasks; .vscode points at ESLint/Prettier.

Astro idioms: JSX comments -> HTML comments, htmlFor alias renamed,
fragment removed, time zone and EIN read from site data. Duplicated
markup extracted into VideoLink and SocialLinks; PostalAddress built
once in jsonld.ts; dead functions/api/test.ts removed.

Comments and docs lose phase/decision-ID narration and stale paths.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018hkX8tZ5Z745EsLeoxz3R5
Restore tools/lint/anti-slop and load it through a small compat layer:
defineRule maps oxlint's createOnce onto ESLint's create, and estree.ts
aliases the oxlint AST names onto typescript-estree's. The rule source
differs from upstream only where the two ASTs differ; VENDOR.md lists
every deviation. @typescript-eslint/utils becomes a direct devDependency
(ADR 0013).

All fifteen rules are errors for .ts, .js, and .astro frontmatter. The
findings they raised on existing code are fixed at the source: an
isImageMetadata type guard replaces typeof narrowing in Seo, eventRoutes
is a ReadonlyMap instead of an open Record, and verify-meta parses
JSON-LD with a zod schema instead of unknown-typed checks.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018hkX8tZ5Z745EsLeoxz3R5
…t docs

The cn font-size check is removed from pnpm check, CI, and tools/checks;
AGENTS.md, cn.ts, and the primitives README now carry the rule that the
font-size group and the --text-* tokens change together in one commit.

docs/tooling.md states the TypeScript 6 pin and what unlocks 7. AGENTS.md
and ADR 0012 no longer describe oxlint/oxfmt as scheduled to return; a
move back to oxc is its own decision.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017X63pwDSjHaNH39oLWNM8N
The woff2 files the site serves move into src/styles/fonts/ with their
OFL license texts. fonts.css points every face there, the four
@fontsource packages and their knip exceptions go, and og-fonts.ts
reads the committed Orbitron file.

tools/assets/font-subset.ts and pnpm assets:fonts are removed; the
trimmed Inter stays as a file with its provenance and the fonttools call
that produced it recorded in ADR 0014, which amends 0011.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017X63pwDSjHaNH39oLWNM8N
og-cards.ts builds the card as a Satori element tree, resvg rasterizes
it, and sharp writes the JPEG. Orbitron is passed as bytes from a
vendored static TTF (Google Fonts' 700 instance, OFL) in
tools/assets/fonts, so nothing is looked up on the machine.

og-fonts.ts, pnpm assets:og-fonts, and the fc-cache knip exception are
removed. satori and @resvg/resvg-js become dev dependencies (ADR 0015,
amending 0010); tools/tsconfig skips lib checks for satori's
declarations. The seven cards are regenerated with measured line breaks.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017X63pwDSjHaNH39oLWNM8N
tools/assets/optimize-sources.ts walked src/assets with a size threshold
and a minimum-gain guard so repeat runs would converge. A photograph is
prepared once, so the tree walk and its guards go: docs/content.md gives
the pinned pnpm dlx sharp-cli command for a new master, and ADR 0016
records the decision.

tools/lib/fs.ts had one remaining consumer; verify-meta carries its own
walk.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017X63pwDSjHaNH39oLWNM8N
The page ground and tint bands carry a sparse monochrome grain tile so the
sheet reads as a surface instead of a flat hex; pockets stay smooth so the
recess reads against it. Ambient pools rise to a range that is visible on a
real monitor. Ghost numerals anchor to the heading's top edge and rise into
the section padding instead of colliding with the first word. DESIGN.md §2
amended to match.

Also ignores the chrome-devtools browser download and the machine-local
Claude settings file in the lint and format checks.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
FeatureCard renders the photo when it has one and the icon only when it
does not. The icon's filled 48px tile becomes a 36px stamped plate in the
spec-chip anatomy, so the header row speaks one register instead of two.
Photo cards on the home page and program hub drop their icon props.
DESIGN.md §8 amended.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Every text link carries a hand-drawn underline as a repeating stroke tile
that follows the text across line breaks; program themes re-declare the
tile in their own accent. Hover shades the text and leaves the stroke in
place. Chrome links keep the stroke for hover only. A link with a swipe is
a featured link; swipes and ovals alone stay emphasis, so the inline
emphasis underline retires and the FRC hero phrase becomes a swipe.

The standalone underlined-text button is retired: the FIRST logo is now
the link with a REF callout naming the destination, More than Robots is an
in-prose link, and the contact page's directions link is a plain anchor.
Anchors that are not text (buttons, framed media, the skip link) reset the
stroke with bg-none.

Grain recipe swapped for a 600px film-grain tile after the 240px turbulence
tile showed a visible repeat. DESIGN.md §2, §8 amended.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Link underline is a quick pen stroke — nearly straight, slight bow — and
sits lower under the text. Chrome links (nav, footer, card footers) are a
different layer and take a straight machined hairline on hover, never the
hand stroke. Hand-markup strokes draw on when they scroll into view via a
small IntersectionObserver, over 1100ms instead of 500ms; without JS the
stroke is simply present. Card badges sit on the title line, so a photo
card is photo, title, rule, copy. Ambient pools centre on the heading and
fade inside the section instead of being cut by its top edge. Registration
marks are set 12px in from the pocket corners. Ruler dividers gain two
standing uses: above the footer title block and above each page's closing
CTA band. DESIGN.md amended throughout.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The stroke is a 240px tile holding a single smooth sag, ~2.3px, so a
typical link shows one whole curve and a long one a slow scallop. No
jitter, no wave, no ruled line: the hand is in the curve. Text anchors gain
a little bottom padding so the line sits ~0.2em under the baseline; buttons
and framed media reset it with pb-0. DESIGN.md §2 says the same.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The stroke SVG has no intrinsic size and stretches to the link's width
(and, with box-decoration-break: clone, to each wrapped line), so a link
of any length shows exactly one smooth sag and never a seam where a tile
met itself. non-scaling-stroke keeps it 2.3px. Bottom padding grows to
0.16em and the curve sags away from the text, so it never touches
descenders. DESIGN.md §2.14 says the same.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The Lighthouse gate has failed on every run since it was added, on the
LCP assertion alone, by 40 to 200 ms, while the same build lands at
1.8 s locally. The summary now explains a run instead of scoring it:
Lighthouse and Chrome versions with the benchmark index, then per URL
the LCP element, its four phases, and the request waterfall Lighthouse
observed. It goes to stdout as well as the step summary, so a failed
run's reasons are readable through the Actions API without downloading
the report artifact.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vaq66ucygSHc84MJXz1cac
…adder step

The Lighthouse gate had failed on every CI run since Phase 09 added it,
on LCP alone, by 40 to 200 ms on four of the six URLs. Two causes, both
now recorded in docs/adr/0018-lighthouse-over-http2.md.

The runner's Chrome 152 fetches every lazy image within about three
viewports during the initial load, which Chrome 141 did not, and
Lighthouse's simulation counts every request that ends before the paint
against LCP. And astro preview serves HTTP/1.1, where the simulation
charges a handshake per parallel connection; Cloudflare serves HTTP/2.
The same build measures 450 ms less LCP over the transport visitors get.

tools/ci/serve.ts serves dist/ over HTTP/2 and TLS with a self-signed
certificate it makes with openssl, gzip on the text types, and
lighthouserc.json starts it in place of astro preview. The four latin
faces are subset to the characters English copy uses, 12 KB off the
fonts every page loads (docs/adr/0017-font-subset.md), with tabular
figures kept for the numerals. Photographs 92vw wide on a phone gain a
672px variant, which a 360px screen at 2x and Lighthouse's 412px at 1.75x
both pick instead of 768 or 840.

Chrome 152, median of three, before and after: / 2138 -> 1577 ms,
/about/ 2117 -> 1429, /programs/frc/robots/ 2121 -> 1428, /sponsors/
2040 -> 1503. Font preloads were re-measured over HTTP/2 and change
nothing; ADR 0008 stands.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vaq66ucygSHc84MJXz1cac
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vaq66ucygSHc84MJXz1cac
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.

2 participants