feat: redesign the home page with different design and color#32
Closed
dineshbyte wants to merge 35 commits into
Closed
feat: redesign the home page with different design and color#32dineshbyte wants to merge 35 commits into
dineshbyte wants to merge 35 commits into
Conversation
… lesson Demonstrates the fix for "fix one page, break all": every duplicated chrome element (the whole <head>, theme scripts, analytics include, hubbar, masthead, topic chips, feedback widget, closing endnote, quiz JS) moves into two shared layouts. A lesson page is now just a schema-validated `meta` object plus its bespoke body — change the masthead once and every lesson updates. - astro-poc/ is isolated (its own package.json) so the existing CommonJS scripts/*.js keep working; builds to ../dist, never docs/. - build.format:'file' + site/base preserve the exact .html URLs and canonical/ OG tags, so the GitHub Pages "main -> /docs" deploy model is unchanged. - src/schema/lesson.ts is the lesson contract; bad/missing metadata is a build error, replacing the hand-rolled checks the inject-*.py scripts patch in. Build instructions and the migration plan are in README-ASTRO-POC.md. npm is blocked in the authoring sandbox, so the `npm install && npm run build` verification step runs on the maintainer's machine.
- switch the POC to pnpm; add Prettier with prettier-plugin-astro (tabWidth 4, matching .editorconfig) plus `format` / `format:check` scripts - .gitignore: anchor the EPUB reader's local-only /package.json and /pnpm-lock.yaml to the repo root so subdirectory manifests (astro-poc/) track normally — removes the broad package.json/lock ignores and the negation hack, without exposing the local-only reader files
…URLs were missing a slash)
…-LD), Sources, Rehearse, Steps; Quiz id optional
…eserve analytics hooks)
The Engineering Vault site now builds end-to-end under Astro: 49 pages (the hub + 48 teaching pages), output to dist/, faithful to the live design. Deploy model is unchanged (static HTML → GitHub Pages main → /docs once outDir is flipped). Hub (src/pages/index.astro + components): - The 15 hardcoded track cards become ONE typed `tracks` source (src/data/tracks.ts, Zod-validated) that feeds the grid, hero count, filter counts, search index, no-results catalog and card sheet — no more drift across 5 hand-maintained copies. - Chrome → components: SiteHeader, Hero, WhatIsBand, FilterChips, TrackCard, TrackGrid, SearchResults, CardSheet, SiteFooter + shared atoms (ThemeToggle, SocialLinks, GithubStar). The hub client JS is ported verbatim (search, filter, progress->Continue, card sheet, NEW pill); SEARCH_INDEX/CARD_DETAIL derived from `tracks`. Fixed the progress_reset double-fire; dropped the pinch-zoom- blocking viewport. Lessons (src/content/lessons/**.mdx + [...slug] route): - 48 teaching pages → an MDX content collection with schema-validated frontmatter (quiz/interview/sources/mc/steps), rendered through LessonLayout via a route that preserves the exact .html URLs. - Recurring widgets are shared components (Quiz/Interview/Sources/Rehearse/Steps/ MemoryCheck); bespoke SVGs are co-located figure components; the FAQ JSON-LD derives from the interview array (can't drift). - Per-page inline CSS consolidated into lesson.css (#main-scoped); two heavily bespoke lessons keep co-located _*.css imports. Tooling / safety net: - scripts/check-hub-hooks.js asserts all 19 analytics + ARIA hooks on the built hub (PASS — preserves GA4 events with no CI gap). - astro-poc/scripts/check-mdx.mjs + check-frontmatter.mjs validate every lesson's MDX body and YAML frontmatter (48/48 each).
The hub search index is now generated at build from the `lessons` content
collection (one source), restoring deep full-text search that the title+blurb-
only inline derivation had dropped.
- New prerendered endpoint src/pages/assets/search-index.js.ts emits
window.SEARCH_INDEX as /assets/search-index.js. Each lesson entry's searchable
`x` is the lowercased title + chips + quiz questions + interview Q&A + sources
+ the stripped MDX body prose (imports/JSX/HTML/entities/markdown removed).
- index.astro: dropped the inline SEARCH_INDEX derivation; loads the endpoint via
a plain inline-src <script> before the IIFE (CARD_DETAIL stays inline). Deleted
the stale prebuilt public/assets/search-index.js (collided with the route).
- 83 entries: 48 full-text lessons + 35 track reference pills. Verified a
body-only phrase ("exaggerates presence") now matches; entry shape {t,u,g,k,x,c}
unchanged so the ported run() search is untouched.
Scope: the 11 interview-bank pages + reference/glossary pages aren't in the
`lessons` collection yet (not migrated), so they're not indexed — same coverage
as the prior Astro derivation. Build green (49 pages), hub-hooks PASS (19),
check-mdx + check-frontmatter 48/48.
…g <Interview>); BaseLayout extraCss prop; [...slug] route multiplexes collections — 60 pages build green
…ayout, 3 CSS skins) — 70 pages build green; route multiplexes lessons+interview+reference
…ons (retires pandoc build-reference-pages.py); no-dep rehype heading-id plugin gives exact anchor parity — 90 pages build green
…y — 96 pages, FULL docs/ parity
…thored site `astro build` (outDir ../docs, emptyOutDir, build.format:'file') now GENERATES the published site into docs/; GitHub Pages serves it unchanged (main -> /docs). Full parity: all 96 URLs byte-identical, 0 real broken internal links, hub analytics/ARIA hooks intact (19/19), search index 94 entries incl. the 11 interview banks. Removed from docs/ (now generated, or sourced inside the Astro project): - hand-authored .html pages -> regenerated by Astro from src/content + components. - GLOSSARY/RESOURCES/README .md -> source of truth is now src/content/. - EPUB book build sources (docs/*/epub/**) -> EPUB generation is retired. Per-track diagram PNGs were recovered into public/*/diagrams/ so Astro re-emits them at the same URLs (the deep-dive/book pages reference them). Carried into the Astro project: robots.txt + sitemap.xml (public/); the interview banks folded into the search-index endpoint. Kept LOCAL-ONLY (recovered to notes/, gitignored): per-track MISSION.md / NOTES.md / learning-records/ and the deep-dive/fundamentals .md sources. The book lessons are now sourced from their converted .mdx; the .md are backed up locally in case the cleaner markdown is wanted as the future source. Project stays in astro-poc/ (source) -> docs/ (output). Note: check-broken-links.js still assumes relative links, so its base-absolute "misses" (/engineering-learning-hub/…) are GitHub-Pages-valid — follow-up to make it base-aware.
The Astro project moved from astro-poc/ to the repo root (package.json, astro.config.mjs with outDir now ./docs, src/, public/, tsconfig, pnpm files, scripts). docs/ stays the build output — GitHub Pages serves main -> /docs unchanged, output byte-identical (verified). - Removed the obsolete EPUB-reader cruft (reader.html, server.js, the root package.json/pnpm-lock — gitignored local) and dropped the /package.json + /pnpm-lock.yaml ignore anchors so the Astro manifests track at root. - Retired migration-superseded tooling: inject-analytics.js, inject-a11y.py, inject-lesson-feedback.py, inject-lesson-endnote.py (the layouts do this now), build-reference-pages.py (pandoc -> Astro glossary/resources collections), build-card-detail.js + wire-og-cards.js (old hub card system), README-ASTRO-POC.md. - Renamed the CommonJS validators to .cjs (check-broken-links, check-hub-hooks, validate-content) — required now that the root package.json is "type":"module". Build from root: `pnpm install && pnpm build` -> docs/ (96 pages, 0 real broken links, hub hooks PASS 19/19, mdx + frontmatter 48/48). Kept scripts: check-mdx.mjs, check-frontmatter.mjs, check-hub-hooks.cjs, check-broken-links.cjs, validate-content.cjs, build-og-cards.py.
Replaces the "Quietype Indigo" palette with an engineering-notebook
identity across both dark and light themes:
tokens.css (public/assets/ source + docs/assets/ output):
- Dark: obsidian surfaces (#0B1020), amber primary accent (#F59E0B),
cyan secondary (#22D3EE), sky-blue links (#38BDF8)
- Light: slate-white surfaces (#F8FAFC), dark amber (#D97706), teal secondary
- New canonical token names (--surface, --text, --border, --link, --code-bg…)
- Old names (--card, --ink, --line, --chip, --good, --bad, --warn) kept as
migration aliases — all 96 pages resolve with zero markup edits
index.astro: 10 hardcoded hex values replaced with tokens or brand constants:
hero gradient → always-dark obsidian, topbar blur → var(--bg), badges/pills
→ warning/bg tokens, OG card gradient → amber+cyan, active chip → var(--bg)
lesson.css: figure bg #fffff8 → var(--surface); links a{} → var(--link)
with hover state using var(--link-hover)
validate-content.cjs: exclude 404.html from indexable/sitemap gate
BaseLayout.astro: additive robots prop (default index,follow; 404 uses noindex)
SiteFooter.astro: avatar src base-absolute (was bare-relative, would 404 on nested pages)
src/pages/404.astro: branded 404 page (noindex, obsidian/amber themed, base-absolute links)
URLs like /ai-agents/lessons/0001-ai-agents-from-first-principles.html are replaced by /ai-agents/lessons/ai-agents-from-first-principles.html. Physical MDX filenames are unchanged (ordering preserved); only the routed path, cross-references, figure dirs, and sitemap are updated. Also fixes check-broken-links.cjs to resolve root-relative /engineering-learning-hub/ paths against docs/ (the site root).
Raw relative hrefs like "ai-agents/lessons/..." resolved from the document root when the hub page URL lacked a trailing slash, producing /ai-agents/... paths that 404 in both dev and production. All three link sites (lchip, start button, reference pills) now emit base-absolute paths.
…ping content in <p> Multi-line <sup><a ...>\n N\n</a></sup> patterns caused MDX to wrap the footnote number in a <p> block, making it render as a standalone block element instead of an inline superscript. Collapsed all 197 occurrences across all content files to single-line form.
- Add .github/workflows/deploy.yml: builds Astro site with pnpm, runs validate-content + check-broken-links, deploys to GitHub Pages on push to main (PRs get build+validate only, no deploy). - Add docs/ to .gitignore and untrack the 300+ generated HTML files — the build output is now produced by CI, not committed to the repo. - Remove content-validation.yml and link-check.yml — both are now superseded by the build job in deploy.yml (validation runs post-build on every push/PR, against the freshly built docs/ rather than committed files). After merging, update GitHub Pages source from Settings → Pages → Source: "Deploy from a branch" to Source: "GitHub Actions"
Make the site read as a calm, technical engineering knowledge base rather than an amber-heavy dashboard. Amber now signals only genuine highlights; slate carries structure and cyan carries the technical/per-track identity. Hub cards (src/pages/index.astro): - .tile left border: amber (--tc) -> neutral (--line); only the curated START HERE card ([data-here]) keeps the amber edge. - .start button: was a solid amber block on every card; now a quiet amber ghost (outline) by default, fills on hover. The two cards that ARE the primary action -- START HERE and in-progress Continue -- stay filled. - .tag keyword chips + .cnt lesson-count pill: amber-tinted -> neutral slate (--bg-soft / --chip / --line). - a.lchip i lesson-number badge: amber fill -> neutral chip with cyan numeral. Topic chips (lesson.css + Reference/Interview/Roadmap layouts): - .ltags .lt: amber fallback -> neutral slate. Drops the 6-color rainbow nth-child cycle in ReferenceLayout (was the loudest non-amber offender). Per-track tokens (tokens.css): - All 15 --track-* unified from amber to the secondary cyan accent, so card icon tints read as one cohesive technical identity, not a rainbow. No layout/markup changes, no new deps. Lesson body links already used --link (cyan). Build green; validate-content + check-broken-links both pass.
check-mdx.mjs and check-frontmatter.mjs were sweep tools for the bulk MDX conversion -- they report all syntax/frontmatter errors in one pass instead of build's one-at-a-time. The migration is done and the site builds green, so `astro build` (which parses MDX and frontmatter with the same compilers) now fully covers what they checked. Neither was wired into CI or package.json; they only referenced each other in comments. Kept: build-og-cards.py (regenerates committed OG card PNGs) and check-hub-hooks.cjs (the only guard that analytics/ARIA DOM hooks survive a component refactor). No CI change. Actions minutes are free on this public repo regardless.
Run `prettier --write .` across the tracked source so the about-to-be-added pre-commit hook starts from a clean baseline (otherwise the first edit to each stale file would carry an unrelated reformat blast). Markup/frontmatter only — the dense Tufte CSS lives in JS template strings (set:html), which Prettier does not touch, and public/assets + src/content + figures stay .prettierignore'd. Build green; validate-content + broken-links pass.
Adds a fast, format-only pre-commit gate so committed source stays
consistently formatted without anyone remembering to run `pnpm format`.
- husky: installs the git hook reproducibly via the `prepare` script, so a
fresh `pnpm install` wires it up automatically (no manual setup per clone).
- lint-staged: runs `prettier --write` on ONLY the staged files of the
formattable types ({js,cjs,mjs,ts,astro,json,md,yml,yaml}) and re-stages
them. Sub-second; never blocks a commit over whitespace.
Scope is deliberate: the heavy gates (astro build, validate-content,
check-broken-links) stay in CI — they need a built docs/ and are too slow to
run on every commit. .prettierignore now also excludes the generated docs/
outDir and the machine-managed pnpm-lock.yaml.
`prepare` runs on every `pnpm install`, so husky was being set up in CI too, where the pre-commit Prettier hook is pointless — CI never commits, and formatting is a local concern (CI validates the built site, it does not format source). Route `prepare` through .husky/install.mjs, which exits early when the CI env var is set. GitHub Actions exports CI=true automatically, so deploy.yml needs no change: `pnpm install --frozen-lockfile` simply no-ops the hook setup in CI and installs hooks as normal on local machines.
Adds a commit-msg git hook that lints every local commit message against @commitlint/config-conventional. The repo already follows this convention (feat / fix / chore / refactor / style / docs, optional (scope), trailing ! for breaking changes) — this makes it non-optional so the history stays machine-readable (changelog/release tooling, easy scanning). - commitlint.config.js extends config-conventional with no custom rules; defaults fit (header <= 100, known type, non-empty subject). Scopes stay free-form so it guides without nagging. - .husky/commit-msg runs `commitlint --edit "$1"`. Local-only: CI never commits and husky is not installed in CI (install.mjs CI guard), so deploy.yml is untouched.
Squash merges use the PR title as the commit subject, so a non-conventional title would land an off-convention commit on the default branch even though local commits are linted. This adds a lightweight workflow that runs the repo's own commitlint config against the PR title. - Separate from deploy.yml on purpose: it must fire on the `edited` event (title fixes), and adding that to the build workflow would rebuild the whole site on every title/description edit. `synchronize` is included so the check re-stamps each head SHA (needed if it becomes a required status check). - The title is attacker-controlled, so it is passed via the PR_TITLE env var and never interpolated into the shell command (no injection surface). - Reuses commitlint.config.js — one source of truth for local commits AND PR titles. Self-skips nothing in CI: husky isn't installed (CI guard), and this job only runs `commitlint`, not the build.
…text Small follow-up pass on the Obsidian+Amber+Cyan palette. Most of the prompt's targets (neutral card borders with amber only on the START HERE card, cyan links, neutral tags, cyan hero tagline) were already in place from the prior refinement; this fixes only the three things still off: - Active filter chip (.fchip.is-active): dark ink (#111827) instead of white on the amber fill — calmer, not glowing, and fixes a real light-theme AA failure (white-on-amber was ~2.9:1). One value works in both themes, so the per-theme override is dropped; explicit box-shadow:none so it never reads as bulky. Adds a softer --accent-soft focus ring on the chips. - Normal Start button (.start ghost): was muddy/brown — amber 12% fill over the navy surface. Now brighter --accent-soft text with a lighter fill (9%) and border (26%) so it reads as a clean outlined CTA. Hover/featured/Continue fills are unchanged. - Dark-theme muted text: --text-muted #A7B0C0 -> #B6C0D1, --text-soft #7C8798 -> #8D98AB. Card descriptions/secondary text read easier while staying secondary; light theme untouched. No layout/content/markup changes. Build green; validate-content + broken-links pass.
The bottom sheet (openSheet) reads each lesson chip's literal href attribute
and looks it up in window.CARD_DETAIL to show the lesson's blurb. After lesson
hrefs gained the GitHub-Pages base prefix (TrackCard renders
`${base}${lesson.href}`), the DOM href became
"/engineering-learning-hub/<track>/lessons/<slug>.html" while CARD_DETAIL was
still keyed by the base-less "<track>/lessons/<slug>.html" — so every
DETAIL[href] lookup missed and no .cs-d description was appended.
Key cardDetail with the same `${base}${lesson.href}` the DOM uses, so the key
space matches the chip hrefs. Verified the built CARD_DETAIL key and the
a.lchip href are now identical. Single inline source (derived from tracks)
unchanged otherwise. Build + validate-content + broken-links green.
The card-detail sheet shows a per-lesson blurb only for lessons present in CARD_DETAIL (derived from lessons[].blurb). The 6 single-lesson AI-eng tracks (ai-evaluation, production-ai-architecture, ai-security, ai-infrastructure, domain-agent-design, advanced-ai-systems) never had a blurb — not a migration regression (the old prebuilt map had no lesson keys for them either), but it left each of those cards showing one lesson row with no description. Add a blurb to each, sourced verbatim from that lesson's own frontmatter `description` (the same kind of text every other blurb already uses — no new copy invented). Every lesson chip now resolves to a blurb: built CARD_DETAIL has 48 keys for 48 lesson chips, 0 missing. Build + both gates green.
public/assets/card-detail.js was the old pre-built CARD_DETAIL map (stale 0NNN--prefixed keys). Nothing loads it — index.astro derives window.CARD_DETAIL inline from lessons[].blurb — yet it still shipped to docs/assets/ as dead weight. Remove it. Fix the comments that still pointed at it: - track.ts (x2): blurb is emitted into CARD_DETAIL from lessons[].blurb inline, not "folded in from card-detail.js". - tracks.ts: drop the card-detail.js reference and the now-false claim that the 6 single-lesson tracks carry no blurb (they all do now). The one surviving mention (index.astro) correctly says there is NO card-detail.js asset, so it stays. Build + validate-content + broken-links green.
Follow-up to removing the orphan card-detail.js: the doc comments still said blurb was "folded in from card-detail.js" and that the 6 single-lesson tracks carry no blurb. Both are now false — blurb is authored in lessons[].blurb and emitted into window.CARD_DETAIL inline by index.astro, and every lesson now has one. (These two files were missed by the prior commit because the `git rm` pathspec aborted the combined `git add`.)
The 5-volume backend-mastery series was labelled "Book 1"…"Book 5" in roadmap
titles, lesson kickers/metalines, cross-references, diagram captions and the
EPUB/deep-dive cover art. That collided with the site's existing term "Track"
(a subject area — the hub has ~15), and the covers literally read
"A GUIDED LEARNING TRACK · BOOK 4". Rename the volume axis to "Part N" so the
two levels stay distinct and consistent: Track = subject, Part = volume,
Lesson = chapter within.
Scope (35 files): numbered "Book N"/"Books N" and all-caps "BOOK N" → Part/PART,
plus the navigational lowercase references (roadmap intros "this book →
this part", "next book → next part", "five-book series", "four books of theory").
Deliberately NOT touched: the calendar verb ("Book 30 min with Sam"), EPUB
filenames (book-N-….epub), facebook/rocksdb URLs, the REST hotel-booking
domain, runbook/bookmark/textbook, real books (the Google SRE Book, REST API
design books), idioms ("oldest bug in the book", "open-book exam"), librarian
world-analogies, and in-prose rhetorical metaphors ("holds the whole book")
where "Part" would read worse.
Supersedes the earlier buggy Book→Lesson find-replace (discarded — it collided
"Book 1, Lesson 8" into "Lesson 1, Lesson 8" and clobbered the calendar verb).
Build + validate-content + broken-links green.
Replace implicit array-position ordering with a deterministic, documented
hierarchy in one place (src/data/sortTracks.ts), so the grid and lesson lists
never drift and publish date is never the primary key.
Order:
- Tracks (sortTracksForHub): startHere first → manual `order` asc →
publishedAt desc → title asc (stable fallback).
- Lessons (sortLessons): `order` asc → publishedAt asc → title asc; an unset
`order` keeps the authored array position, which is already the learning
sequence — so lessons stay learning-first, never newest-first.
- sortByLatest (publishedAt desc → updatedAt desc → title) is provided for a
future date-first "Latest" section; no such section exists today.
Data model (src/schema/track.ts):
- Add `order` (optional int) to tracks and lessons — the manual sort key,
decoupled from array source position.
- Rename track `added` → `publishedAt` (first-published date). The DOM
attribute stays `data-added`, so the NEW-pill/analytics contract is unchanged
(TrackCard now emits data-added={track.publishedAt}).
- Add optional `updatedAt` (freshness) for the Latest sort.
- publishedAt is a TIEBREAK only and is never used to drive learning sequence.
tracks.ts: seed explicit order 1..15 (matching prior visual order) and set
Context Engineering startHere:true so both recommended entry points float first
(matches the hero copy that recommends both; previously only AI Agents was
flagged). Lessons keep authored order — no per-lesson churn.
Every comparator ends in a title compare, so ordering is fully deterministic
and stable regardless of engine sort. Build + validate-content + broken-links
green; verified render order (ai-agents, context-engineering, then order 3..15)
and learning-first lessons (★ fundamentals first in deep-dive tracks).
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.
No description provided.