fix(website): nav contrast, accessibility, and colour consistency#841
Conversation
Ports all catalogue data from the prototype into typed TypeScript modules, wires up the resources.ts stub with real items, and builds out all the missing Awesome GitHub pages from scratch. Data layer: - src/lib/catalogue.ts — 110+ ITEMS across 8 categories, URL builders, type info - src/lib/learn.ts — 4 LEARN_TRACKS with 10 lessons, 3 COOKBOOK_RECIPES - src/lib/glossary.ts — 5 GLOSSARY_GROUPS (37 terms), 6 REFERENCE_GROUPS - src/lib/resources.ts — now returns real data via catalogue New pages: - /awesome-github/getting-started — 6-step onboarding with copy-to-clipboard - /awesome-github/learn/ — 4-track learning centre - /awesome-github/learn/[track]/ — per-track overview with lesson list - /awesome-github/learn/[track]/[lesson] — lesson reader with prev/next nav - /awesome-github/glossary/ — grouped term index with sidebar - /awesome-github/glossary/[term] — term detail with related terms - /awesome-github/cookbook/ — recipe index with kind badges - /awesome-github/cookbook/[slug] — recipe detail with GitHub link Updated: - index.astro — uses real catalogue counts (was hardcoded) - AwesomeGithubNav — adds Learn, Cookbook, Glossary links Build: 251 pages, 0 errors https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH
…tons - Add Svelte SearchPalette component (Cmd/Ctrl+K, custom DOM event, keyboard nav) - Mount palette with client:only="svelte" in AwesomeGithubLayout to avoid SSR window errors - Update nav: add Learn, Cookbook, Glossary links + data-search-open on search button - Rewrite [slug].astro detail page: action buttons (Install VS Code, copy URL, copy file, View on GitHub), applyTo/run/validates/duration metadata rows, pre-formatted body block, fallback no-body section, related items grid - Add all missing CSS classes: ag-actions, ag-action-btn variants, ag-apply-to, ag-body-pre, ag-no-body, ag-gh-link, ag-path-code, ag-resource-version, ag-type-note https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH
- Add /awesome-github/why/ editorial page explaining the control plane philosophy - Expand footer: brand column + three nav columns (Explore, Learn, About) + bottom bar - Add mobile hamburger to nav: slide-in drawer at ≤768px, animated ↔ X icon, keyboard Escape support, aria-expanded, aria-controls wired to menu element - Hide search button on mobile (accessible via keyboard shortcut Cmd/Ctrl+K) https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH
- fix(learn): guard getAdjacentLessons against idx === -1 (findIndex miss
returned track.lessons[0] as next when lesson not found)
- fix(search-palette): add aria-activedescendant on input and id="sp-option-{i}"
on each listbox option so screen readers announce keyboard selection
- fix(nav): add visibility:hidden/visible to mobile drawer so off-screen
links are not tab-reachable or screen-reader-readable when closed
- fix(detail): add loading ("⏳ Copying…"), error ("❌ Failed"), and
disabled state to copy-file button while fetch is in progress
https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Ash Shaw <ashley@lightspeedwp.agency>
- fix(catalogue): plugin-structure path was .github/instructions/... → instructions/... - fix(catalogue): labeling path was instructions/labeling.instructions.md (does not exist) → docs/LABELING.md (actual file) - fix(detail): hide 'Copy raw URL' for tree items (directory URLs return 404 from raw.githubusercontent.com) - fix(learn-track): remove nested <a> inside lesson card link (invalid HTML); source link moved outside as a sibling element below the card - fix(resources): remove unused ITEMS and CATEGORIES imports https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH
- Detail pages: ⎇ branch toggle persists main/develop choice in localStorage and rewrites all GitHub/raw/VS Code action URLs on click - Learn: lesson pages auto-mark themselves as read in localStorage; track index displays "X of Y completed" and highlights done lessons - New /awesome-github/references/ page with external sources, acknowledgments, and GPL v3 licence attribution - Footer: added References link; corrected licence text (GPL v3, not MIT) - SearchPalette: moved role=combobox/aria-expanded to <input> per ARIA spec - [slug].astro: removed unused AwesomeGithubButton import - resources.ts: fixed UK spelling "Organisation-wide" https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH
All Awesome GitHub pages previously nested under /awesome-github/ are now at the root of the site, matching the github.lightspeedwp.agency domain structure: /awesome-github/c/agents/ → /c/agents/ /awesome-github/learn/ → /learn/ /awesome-github/references/ → /references/ /awesome-github/why/ → /why/ /awesome-github/ → / Updated all internal route references, nav/footer links, and SearchPalette navigation URLs. Fixed relative import paths for each depth level after the directory move. Removed superseded old pages (references/, getting-started/, legacy cookbook index). Build: 244 pages, 0 errors. https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH
- Nav background: raise opacity from 0.60 to 0.97 in both light and dark modes so the header is never washed-out regardless of the content below - Nav links: boost default colour from slate-500 to slate-700 in light mode for WCAG AA compliance - Nav active link: use accent colour (brand-blue / light-blue) and semi-bold weight to make the current page immediately identifiable - Layout: add visually-hidden skip-to-main-content link for keyboard accessibility (focuses main with id="main-content") - Remove stale mobile margin-top: 72px from hero sections across 9 pages; this was a leftover from when the nav was fixed-positioned and now creates an unwanted gap above the hero on mobile - Fix breadcrumb Home URL in category list page (was "awesome-github", now correct root href) - Replace hardcoded var(--c-light-blue) text colours with var(--accent) in non-hero content areas (resource tags, version badges, lesson numbers, track progress counts) — accent is theme-aware: brand-blue in light mode, light-blue in dark mode, ensuring WCAG AA in both - Reduce content-section padding from --space-40 (160px) to --section-y (96px) to improve vertical rhythm on category, detail, and related-item sections https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH
|
Warning Review limit reached
More reviews will be available in 2 minutes and 34 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository YAML (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (16)
📝 WalkthroughWalkthroughThis PR comprehensively rebuilds the "Awesome GitHub Site" from a React/Babel prototype into a production-ready Astro 5 static site. It introduces TypeScript data modules for catalogues, glossary terms, learning tracks, and cookbook recipes, alongside a new search palette with keyboard navigation. The site now uses static generation for all resource, learning, glossary, and editorial pages, with responsive navigation, clipboard actions, and localStorage-backed progress tracking. ChangesAwesome GitHub Site Rebuild
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly Related PRs
Suggested Labels
Suggested Reviewers• krugazul 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
✅ Template check passed after update. Thanks for fixing the PR description. |
There was a problem hiding this comment.
Code Review
This pull request transitions the Awesome GitHub site into a production-ready Astro 5 static site, introducing a typed TypeScript data layer, a Svelte-based search palette, and various statically-generated pages. The code review comments provide highly actionable feedback to improve the codebase, specifically suggesting focus trapping in the search modal for WCAG AA compliance, wrapping 'localStorage' access in 'try/catch' blocks to prevent crashes in private browsing, using event delegation for search triggers, and refactoring a verbose inline type signature to use the imported 'CatalogueItem' interface.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if (e.key === "Escape") closePalette(); | ||
| if (e.key === "ArrowDown") { e.preventDefault(); selected = Math.min(selected + 1, filtered.length - 1); } | ||
| if (e.key === "ArrowUp") { e.preventDefault(); selected = Math.max(selected - 1, 0); } | ||
| if (e.key === "Enter" && filtered[selected]) navigate(filtered[selected]); | ||
| } |
There was a problem hiding this comment.
To comply with WCAG AA accessibility guidelines for modal dialogs, the search palette should trap keyboard focus when open. Currently, pressing Tab can move focus out of the modal into the background page. Adding a simple focus trap inside the keydown handler ensures keyboard navigation remains contained within the search palette.
if (e.key === "Escape") closePalette();
if (e.key === "ArrowDown") { e.preventDefault(); selected = Math.min(selected + 1, filtered.length - 1); }
if (e.key === "ArrowUp") { e.preventDefault(); selected = Math.max(selected - 1, 0); }
if (e.key === "Enter" && filtered[selected]) navigate(filtered[selected]);
if (e.key === "Tab" && dialogEl) {
const focusable = dialogEl.querySelectorAll('input, button, [tabindex="0"]');
if (focusable.length > 0) {
const first = focusable[0] as HTMLElement;
const last = focusable[focusable.length - 1] as HTMLElement;
if (e.shiftKey && document.activeElement === first) {
e.preventDefault();
last.focus();
} else if (!e.shiftKey && document.activeElement === last) {
e.preventDefault();
first.focus();
}
}
}
| let branch = localStorage.getItem("github_branch") || "main"; | ||
|
|
||
| function applyBranch(b: string) { | ||
| const urls = computeUrls(path, cat, isTree, b); | ||
| document.querySelectorAll<HTMLAnchorElement>("[data-vscode-link]").forEach((el) => { el.href = urls.vscode; }); | ||
| document.querySelectorAll<HTMLButtonElement>("[data-copy-url]").forEach((el) => { el.dataset.copyUrl = urls.raw; }); | ||
| document.querySelectorAll<HTMLButtonElement>("[data-copy-content]").forEach((el) => { el.dataset.copyContent = urls.raw; }); | ||
| document.querySelectorAll<HTMLAnchorElement>("[data-gh-link]").forEach((el) => { el.href = urls.blob; }); | ||
| const label = toggle.querySelector(".ag-branch-label"); | ||
| if (label) label.textContent = b; | ||
| toggle.setAttribute("aria-label", `Switch to ${b === "main" ? "develop" : "main"} branch`); | ||
| toggle.title = `Currently on ${b}. Click to switch to ${b === "main" ? "develop" : "main"}.`; | ||
| } | ||
|
|
||
| applyBranch(branch); | ||
|
|
||
| toggle.addEventListener("click", () => { | ||
| branch = branch === "main" ? "develop" : "main"; | ||
| localStorage.setItem("github_branch", branch); | ||
| applyBranch(branch); | ||
| }); |
There was a problem hiding this comment.
Accessing localStorage directly can throw a SecurityError in certain browser configurations (e.g., strict private browsing modes or when third-party cookies/storage are blocked). Wrapping localStorage.getItem and localStorage.setItem in try/catch blocks prevents the script from crashing and ensures the page remains functional.
let branch = "main";
try {
branch = localStorage.getItem("github_branch") || "main";
} catch (e) {
/* localStorage disabled or blocked */
}
function applyBranch(b: string) {
const urls = computeUrls(path, cat, isTree, b);
document.querySelectorAll<HTMLAnchorElement>("[data-vscode-link]").forEach((el) => { el.href = urls.vscode; });
document.querySelectorAll<HTMLButtonElement>("[data-copy-url]").forEach((el) => { el.dataset.copyUrl = urls.raw; });
document.querySelectorAll<HTMLButtonElement>("[data-copy-content]").forEach((el) => { el.dataset.copyContent = urls.raw; });
document.querySelectorAll<HTMLAnchorElement>("[data-gh-link]").forEach((el) => { el.href = urls.blob; });
const label = toggle.querySelector(".ag-branch-label");
if (label) label.textContent = b;
toggle.setAttribute("aria-label", `Switch to ${b === "main" ? "develop" : "main"} branch`);
toggle.title = `Currently on ${b}. Click to switch to ${b === "main" ? "develop" : "main"}.`;
}
applyBranch(branch);
toggle.addEventListener("click", () => {
branch = branch === "main" ? "develop" : "main";
try {
localStorage.setItem("github_branch", branch);
} catch (e) {
/* localStorage disabled or blocked */
}
applyBranch(branch);
});
| // Wire nav search button to open search palette | ||
| const searchBtn = document.querySelector("[data-search-open]"); | ||
| if (searchBtn) { | ||
| searchBtn.addEventListener("click", () => { | ||
| document.dispatchEvent(new CustomEvent("search-palette-open")); | ||
| }); | ||
| } |
There was a problem hiding this comment.
Binding the click event listener directly to a single element found via document.querySelector can be fragile if multiple search buttons exist (e.g., in mobile vs. desktop headers) or if View Transitions are introduced. Using event delegation on document is more robust and automatically handles dynamically rendered elements.
// Wire nav search button to open search palette using event delegation
document.addEventListener("click", (e) => {
if (e.target instanceof Element && e.target.closest("[data-search-open]")) {
document.dispatchEvent(new CustomEvent("search-palette-open"));
}
});
| // Stub implementation - returns null for now | ||
| // In production, this would load from Astro content collections | ||
| return null; | ||
| function catalogueItemToResource(catalogueItem: { id: string; cat: string; slug: string; name: string; description: string; type: string; tags: string[]; version: string; updated: string; applyTo?: string; path?: string; tree: boolean; body?: string | null; run?: string | null; validates?: string | null; dest?: string | null; duration?: string | null; action?: string | null }): Resource { |
There was a problem hiding this comment.
The inline type signature for catalogueItem is extremely verbose and duplicates the CatalogueItem interface already defined in ./catalogue. Importing or referencing CatalogueItem directly simplifies the signature and improves maintainability.
| function catalogueItemToResource(catalogueItem: { id: string; cat: string; slug: string; name: string; description: string; type: string; tags: string[]; version: string; updated: string; applyTo?: string; path?: string; tree: boolean; body?: string | null; run?: string | null; validates?: string | null; dest?: string | null; duration?: string | null; action?: string | null }): Resource { | |
| function catalogueItemToResource(catalogueItem: import("./catalogue").CatalogueItem): Resource { |
…, event delegation, type cleanup - SearchPalette: add Tab focus trap so keyboard navigation cannot escape the modal dialog (WCAG 2.1 SC 2.1.2 — No Keyboard Trap) - branch toggle: wrap localStorage.getItem/setItem in try/catch to prevent SecurityError crash in private browsing or when storage is blocked by browser policy - layout: replace querySelector + direct listener for search button with event delegation on document, making it robust to multiple instances and View Transitions - resources.ts: replace verbose 200-char inline type signature with the imported CatalogueItem interface already defined in catalogue.ts https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1b2e082b8e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @@ -1,385 +0,0 @@ | |||
| --- | |||
There was a problem hiding this comment.
Restore redirects for removed nested routes
Deleting this route leaves existing in-site CTAs pointing at pages that no longer exist; repo-wide search shows /getting-started/implementation-roadmap/ and /getting-started/why-github-matters/ are still linked from website/src/pages/talk/index.astro, website/src/pages/talk/slides/index.astro, website/src/pages/agents/index.astro, and website/src/pages/agents/[slug].astro. In the static output those links now 404, so either keep redirect stubs for the removed routes or update all of the callers as part of this route move.
Useful? React with 👍 / 👎.
| blurb: "Templates and forms that capture structured data from contributors.", | ||
| items: [ | ||
| { p: ".github/ISSUE_TEMPLATE", d: "Issue template directory", tree: true }, | ||
| { p: ".github/PULL_REQUEST_TEMPLATE.md", d: "PR template" }, |
There was a problem hiding this comment.
Correct the PR template reference path
This new reference builds a GitHub URL for .github/PULL_REQUEST_TEMPLATE.md, but that file does not exist in this repository; the actual default template is .github/pull_request_template.md and the template directory is .github/PULL_REQUEST_TEMPLATE/. Because GitHub blob paths are case-sensitive, the References page's “PR template” link will 404 until this path is corrected.
Useful? React with 👍 / 👎.
…en sub-route links - glossary.ts: correct PR template path from PULL_REQUEST_TEMPLATE.md (wrong casing, would 404 on GitHub) to pull_request_template.md - agents/index.astro, agents/[slug].astro, talk/index.astro, talk/slides/index.astro: replace 5 dead links to removed sub-routes /getting-started/implementation-roadmap/ and /getting-started/why-github-matters/ with /getting-started/ — both sub-pages were removed in the route restructure but callers were not updated, causing 404s in the static output https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH
There was a problem hiding this comment.
Pull request overview
This PR updates the Awesome GitHub Astro site’s navigation, accessibility, and colour usage, while also restructuring several routes/pages (moving away from legacy /awesome-github/* and /references/* pages towards new top-level pages like /, /learn/, /glossary/, /references/, /why/).
Changes:
- Introduces/updates site-level UI and navigation: improved sticky header styling, mobile hamburger menu, and global search palette (Cmd/Ctrl+K) plus skip-to-content support.
- Reworks key content routes by adding new top-level pages (Why, References, Learn, Glossary, Getting Started, Cookbook detail) and removing older “references” and “awesome-github” page implementations.
- Adds typed data sources for “Learn”, “Cookbook”, and “Glossary”, and updates resource utilities to source catalogue items from the TypeScript catalogue.
Reviewed changes
Copilot reviewed 36 out of 36 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
website/src/pages/why.astro |
Adds a new “Why This Exists” editorial page under the Awesome GitHub layout. |
website/src/pages/references/sources/index.astro |
Removes legacy “Sources & Tools” references page (BaseLayout-era implementation). |
website/src/pages/references/index.astro |
Removes legacy references hub page (BaseLayout-era implementation). |
website/src/pages/references/glossary/index.astro |
Removes legacy glossary page under /references/glossary/. |
website/src/pages/references.astro |
Adds a new top-level references/attribution page under the Awesome GitHub layout. |
website/src/pages/learning-hub/index.astro |
Updates accent usage (replacing --c-light-blue with --accent in key UI elements). |
website/src/pages/learn/index.astro |
Adds a new top-level “Learning Centre” landing page powered by LEARN_TRACKS. |
website/src/pages/learn/[track]/index.astro |
Adds per-track pages, including localStorage-based progress UI. |
website/src/pages/learn/[track]/[lesson].astro |
Adds per-lesson pages, marking progress in localStorage and linking to GitHub source. |
website/src/pages/index.astro |
Replaces the previous homepage with an Awesome GitHub landing page driven by catalogue data. |
website/src/pages/glossary/index.astro |
Adds a new top-level glossary index page using grouped glossary data. |
website/src/pages/glossary/[term].astro |
Adds per-term glossary detail pages with related-term navigation. |
website/src/pages/getting-started/why-github-matters/index.astro |
Removes a legacy getting-started subpage (BaseLayout-era implementation). |
website/src/pages/getting-started/index.astro |
Removes the legacy getting-started index (replaced by top-level getting-started.astro). |
website/src/pages/getting-started/implementation-roadmap/index.astro |
Removes a legacy implementation roadmap page (BaseLayout-era implementation). |
website/src/pages/getting-started.astro |
Adds a new top-level Getting Started page with copy-to-clipboard UX. |
website/src/pages/cookbook/index.astro |
Refactors cookbook listing to use typed COOKBOOK_RECIPES and adds richer card UI. |
website/src/pages/cookbook/[slug].astro |
Adds cookbook detail pages that deep-link to GitHub markdown sources. |
website/src/pages/c/[type]/index.astro |
Fixes base paths and routes (removing awesome-github prefix) and updates styling/tags. |
website/src/pages/awesome-github/index.astro |
Removes the legacy /awesome-github/ landing page (replaced by /). |
website/src/lib/resources.ts |
Switches resource retrieval from stubs to the TypeScript catalogue (getItemsByCategory, getItemBySlug). |
website/src/lib/learn.ts |
Adds typed Learning Centre + Cookbook metadata and helper functions. |
website/src/lib/glossary.ts |
Adds typed glossary + reference-group data and helper functions. |
website/src/layouts/AwesomeGithubLayout.astro |
Adds skip link, integrates Svelte SearchPalette, and wires search-open events. |
website/src/components/AwesomeGithub/SearchPalette.svelte |
Adds Cmd/Ctrl+K searchable command palette for catalogue items. |
website/src/components/AwesomeGithub/AwesomeGithubNav.astro |
Improves nav contrast, adds active-link styling, adds hamburger menu and search button wiring. |
website/src/components/AwesomeGithub/AwesomeGithubFooter.astro |
Expands footer into multi-column navigation + licensing/attribution links. |
CHANGELOG.md |
Adds a changelog entry describing the Astro rebuild and new site capabilities. |
| const catalogues = CATEGORIES.map((cat) => ({ | ||
| id: cat.id, | ||
| name: cat.label, | ||
| blurb: cat.blurb, | ||
| icon: cat.icon, | ||
| href: `${base}c/${cat.id}`, | ||
| count: counts[cat.id] || 0, |
| <AwesomeGithubButton variant="primary" href={`${base}getting-started/`}> | ||
| Start here | ||
| </AwesomeGithubButton> | ||
| <AwesomeGithubButton variant="secondary" href={`${base}c/agents`}> | ||
| Browse catalogues | ||
| </AwesomeGithubButton> |
| $: if (filtered) selected = 0; | ||
|
|
||
| function openPalette() { | ||
| open = true; | ||
| query = ""; | ||
| selected = 0; | ||
| setTimeout(() => inputEl?.focus(), 50); | ||
| } | ||
|
|
||
| function closePalette() { | ||
| open = false; | ||
| query = ""; | ||
| } |
| <a href="#main-content" class="ag-skip-link">Skip to main content</a> | ||
| <AwesomeGithubNav base={base} pathname={pathname} /> | ||
| <main> | ||
| <SearchPalette client:only="svelte" items={searchItems} base={base} /> | ||
| <main id="main-content"> |
…toration - index.astro: add trailing slashes to all catalogue card hrefs and the 'Browse catalogues' CTA (e.g. c/agents → c/agents/) to prevent 404s on GitHub Pages static output where directory URLs are canonical - SearchPalette: store previously focused element on open and restore focus on close (Esc or backdrop click) — prevents keyboard and screen-reader users losing their position in the page (WCAG 2.4.3) https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
website/src/lib/resources.ts (1)
14-23:⚠️ Potential issue | 🟠 Major | ⚡ Quick winType registry drift:
pluginsjoined the party, but the public type/actions map didn’t.Line 55 adds
pluginsas a first-class type, but Lines 14-23 and 140-150 still model old categories.
That creates a contract mismatch and can silently drop plugin actions at runtime.🔧 Suggested alignment patch
export type ResourceType = | "agents" | "instructions" | "skills" - | "cookbook" - | "learn" | "hooks" | "workflows" | "prompts" - | "tools"; + | "tools" + | "plugins"; export function getAvailableActions(type: string): ResourceAction[] { const actionMap: Record<string, ResourceAction[]> = { agents: ["copy", "download", "github", "vscode"], instructions: ["copy", "download", "github"], skills: ["copy", "download", "github", "vscode"], - cookbook: ["copy", "download", "github"], - learn: [], hooks: ["copy", "download", "github"], workflows: ["copy", "github"], prompts: ["copy", "github"], + plugins: ["copy", "download", "github", "vscode"], tools: ["copy", "download", "github"], };Also applies to: 48-57, 139-153
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@website/src/lib/resources.ts` around lines 14 - 23, ResourceType's union is missing "plugins", causing a mismatch with the new first-class type added elsewhere; update the ResourceType union to include "plugins" and also add "plugins" to the public type→actions mapping used later in the file (the map that enumerates resource types to public actions), ensuring both the ResourceType declaration and the public type/actions map include "plugins" so plugin actions are not dropped at runtime.
🧹 Nitpick comments (2)
website/src/components/AwesomeGithub/SearchPalette.svelte (2)
126-133: 💤 Low valueMinor combobox ARIA refinement.
The
aria-expandedattribute is hardcoded to"true"(line 126), but the listbox (#sp-results) is only rendered whenfiltered.length > 0. For strict ARIA combobox compliance,aria-expandedshould reflect whether the listbox is actually present. Consider:- aria-expanded="true" + aria-expanded={filtered.length > 0} aria-haspopup="listbox"This is a minor refinement—the current implementation works in practice since the palette only appears when intentionally opened.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@website/src/components/AwesomeGithub/SearchPalette.svelte` around lines 126 - 133, Update the combobox ARIA state so aria-expanded reflects whether the results listbox is actually present instead of being hardcoded to "true": in SearchPalette.svelte change the aria-expanded usage on the input (the element that uses aria-activedescendant and aria-controls) to compute its value from the same condition that renders the list (`#sp-results`), i.e. use the filtered.length > 0 condition (or the shared isOpen state if one exists) so aria-expanded is true only when the results are rendered.
42-45: ⚡ Quick winConsider restoring focus when closing the search palette.
When the palette closes, focus is not explicitly restored to the previously focused element. Users who opened it via
Cmd+Kmight find their focus orphaned. Consider trackingdocument.activeElementbefore opening and restoring it on close:let previousFocus: HTMLElement | null = null; function openPalette() { previousFocus = document.activeElement as HTMLElement; open = true; query = ""; selected = 0; setTimeout(() => inputEl?.focus(), 50); } function closePalette() { open = false; query = ""; previousFocus?.focus(); previousFocus = null; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@website/src/components/AwesomeGithub/SearchPalette.svelte` around lines 42 - 45, The closePalette function currently clears open and query but does not restore keyboard focus; add a module-scoped variable (e.g., previousFocus) to capture document.activeElement before opening in openPalette, set previousFocus when openPalette runs, move focus to the palette input after opening (as you already do), and in closePalette call previousFocus?.focus() and then null out previousFocus; update openPalette and closePalette (and any related inputEl usage) to use these symbols so focus is reliably returned when the palette closes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@CHANGELOG.md`:
- Line 30: The Unreleased changelog entry "Awesome GitHub Site: Complete Astro
Rebuild" is missing the required PR and issue links; update that entry under the
[Unreleased] section by appending the PR and issue references (e.g., "(`#1234`)"
and "(`#5678`)" or full link format) so the line for "Awesome GitHub Site:
Complete Astro Rebuild" includes both a PR link and an issue link as mandated by
the changelog rules.
In `@website/src/layouts/AwesomeGithubLayout.astro`:
- Line 62: Add tabindex="-1" to the main element with id "main-content" so the
skip link can programmatically focus it; update the <main id="main-content">
element in AwesomeGithubLayout.astro to include tabindex="-1" (ensuring you only
add it once and don’t introduce duplicate tabindex attributes).
In `@website/src/pages/c/`[type]/[slug].astro:
- Around line 253-255: The saved branch value read from localStorage into the
variable branch is used without validation and can produce broken links;
validate/sanitize it right after reading (e.g., only accept "main" or "develop"
and otherwise set branch = "main") before any usage, and apply the same
validation where branch is read/used later (the other occurrence around line
269) so only allowed branch names are ever applied to link construction.
In `@website/src/pages/cookbook/index.astro`:
- Around line 147-148: The badge contrast is too low; update the CSS rules for
.kind--example and .kind--checklist to use darker foreground colors (and ensure
matching darker variants for dark-mode) so the text/background combinations meet
WCAG 2.2 AA contrast; locate the .kind--example and .kind--checklist definitions
in website/src/pages/cookbook/index.astro (and any duplicated instances later in
the file) and replace the current light color values with higher-contrast color
tokens or hex values that meet AA for small text, and ensure the dark-mode rules
are adjusted to maintain parity.
In `@website/src/pages/getting-started.astro`:
- Around line 77-84: The copy button uses a fixed aria-label which stays "Copy
to clipboard" while the visible text is changed to "Copied!" (button with class
"gs-copy-btn" and data-copy attribute), causing an accessibility mismatch;
update the click/copy handler that currently changes the button text to also
update the button's aria-label to the same value (e.g., set
button.setAttribute('aria-label', newLabel) when toggling to "Copied!" and
back), or remove the hard-coded aria-label and expose the visible text as the
accessible name (or use an aria-live region) so assistive tech receives the same
feedback as sighted users.
In `@website/src/pages/glossary/index.astro`:
- Around line 30-31: The sidebar anchor links jump to headings that get hidden
behind the sticky UI; add a scroll-margin-top to the target headings so hash
navigation lands below the sticky header by applying a CSS rule to the elements
using the same id targets (e.g. headings that receive {group.id}) or the wrapper
class used for sections (reference: group.id and .glossary-sidebar-link);
implement a rule like `h2[id], .glossary-section { scroll-margin-top:
var(--sticky-header-height, 80px); }` (or use the actual sticky header height
variable) so all hash jumps have appropriate headroom.
In `@website/src/pages/index.astro`:
- Around line 21-24: The stats array currently hardcodes the category count
("8") which can become stale; update the stats entry in the stats constant to
derive the value from CATEGORIES.length (e.g., use String(CATEGORIES.length)) so
the "Categories" stat always reflects the actual CATEGORIES array; locate the
stats declaration and replace the literal "8" for the "Categories" label with a
stringified CATEGORIES.length.
In `@website/src/pages/learn/`[track]/index.astro:
- Line 83: The primary CTA currently assumes track.lessons[0] exists
(href={`${base}learn/${track.id}/${track.lessons[0].slug}/`}); add the same
empty-track guard used elsewhere by checking that track.lessons &&
track.lessons.length > 0 before constructing or rendering this href (or render a
fallback/disabled CTA when no lessons exist) so the page won't crash for empty
tracks.
- Line 370: The selector interpolation uses slug directly in
document.querySelector (`const item =
document.querySelector([data-lesson-slug="${slug}"])`), which can throw for
slugs with CSS-special characters; update the code to escape the slug before
building the selector (use CSS.escape(slug) where available, with a small
fallback if needed) and then query with the escaped value so `item` lookup and
the completion UI update won't be skipped when keys contain selector characters.
In `@website/src/pages/learn/index.astro`:
- Line 66: The CTA currently dereferences track.lessons[0].slug which will throw
when lessons is empty; update the render to check that track.lessons exists and
has length > 0 before building the href (e.g., only render the anchor or compute
href when track.lessons.length > 0), and fall back to a safe alternative
(disable/hide CTA or link to the track overview) when no first lesson exists;
target the template expression using base and track.lessons[0].slug to implement
this guard and optionally add a runtime/assertion in the learn data validation
to enforce non-empty lessons.
---
Outside diff comments:
In `@website/src/lib/resources.ts`:
- Around line 14-23: ResourceType's union is missing "plugins", causing a
mismatch with the new first-class type added elsewhere; update the ResourceType
union to include "plugins" and also add "plugins" to the public type→actions
mapping used later in the file (the map that enumerates resource types to public
actions), ensuring both the ResourceType declaration and the public type/actions
map include "plugins" so plugin actions are not dropped at runtime.
---
Nitpick comments:
In `@website/src/components/AwesomeGithub/SearchPalette.svelte`:
- Around line 126-133: Update the combobox ARIA state so aria-expanded reflects
whether the results listbox is actually present instead of being hardcoded to
"true": in SearchPalette.svelte change the aria-expanded usage on the input (the
element that uses aria-activedescendant and aria-controls) to compute its value
from the same condition that renders the list (`#sp-results`), i.e. use the
filtered.length > 0 condition (or the shared isOpen state if one exists) so
aria-expanded is true only when the results are rendered.
- Around line 42-45: The closePalette function currently clears open and query
but does not restore keyboard focus; add a module-scoped variable (e.g.,
previousFocus) to capture document.activeElement before opening in openPalette,
set previousFocus when openPalette runs, move focus to the palette input after
opening (as you already do), and in closePalette call previousFocus?.focus() and
then null out previousFocus; update openPalette and closePalette (and any
related inputEl usage) to use these symbols so focus is reliably returned when
the palette closes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 054cd1f2-3482-4878-82b7-ba43b33414c4
📒 Files selected for processing (32)
CHANGELOG.mdwebsite/src/components/AwesomeGithub/AwesomeGithubFooter.astrowebsite/src/components/AwesomeGithub/AwesomeGithubNav.astrowebsite/src/components/AwesomeGithub/SearchPalette.sveltewebsite/src/layouts/AwesomeGithubLayout.astrowebsite/src/lib/catalogue.tswebsite/src/lib/glossary.tswebsite/src/lib/learn.tswebsite/src/lib/resources.tswebsite/src/pages/awesome-github/c/[type]/[slug].astrowebsite/src/pages/awesome-github/index.astrowebsite/src/pages/c/[type]/[slug].astrowebsite/src/pages/c/[type]/index.astrowebsite/src/pages/cookbook/[slug].astrowebsite/src/pages/cookbook/index.astrowebsite/src/pages/getting-started.astrowebsite/src/pages/getting-started/implementation-roadmap/index.astrowebsite/src/pages/getting-started/index.astrowebsite/src/pages/getting-started/why-github-matters/index.astrowebsite/src/pages/glossary/[term].astrowebsite/src/pages/glossary/index.astrowebsite/src/pages/index.astrowebsite/src/pages/learn/[track]/[lesson].astrowebsite/src/pages/learn/[track]/index.astrowebsite/src/pages/learn/index.astrowebsite/src/pages/learning-hub/index.astrowebsite/src/pages/references.astrowebsite/src/pages/references/evidence/index.astrowebsite/src/pages/references/glossary/index.astrowebsite/src/pages/references/index.astrowebsite/src/pages/references/sources/index.astrowebsite/src/pages/why.astro
💤 Files with no reviewable changes (9)
- website/src/pages/awesome-github/index.astro
- website/src/pages/references/sources/index.astro
- website/src/pages/getting-started/why-github-matters/index.astro
- website/src/pages/references/evidence/index.astro
- website/src/pages/references/index.astro
- website/src/pages/references/glossary/index.astro
- website/src/pages/awesome-github/c/[type]/[slug].astro
- website/src/pages/getting-started/index.astro
- website/src/pages/getting-started/implementation-roadmap/index.astro
📜 Review details
🧰 Additional context used
📓 Path-based instructions (5)
**/*.md
📄 CodeRabbit inference engine (.github/instructions/markdown.instructions.md)
**/*.md: Use one H1 (#) per file; keep heading levels sequential (never skip from H2 to H4)
Use fenced code blocks with explicit language tags (bash,yaml,markdown, etc.)
Keep links relative for in-repo files; verify they resolve before merging
Use1.for ordered lists and-for unordered lists
Keep all wording in UK English (optimise, organisation, colour, behaviour, analyse)
Do not add areferences:frontmatter field — use inline links or a footer section instead
Blank lines before and after headings, code blocks, and block-level elements
Maximum line length: 120 characters (soft limit; prefer wrapping at natural sentence boundaries)
All.mdfiles in this repository should include YAML frontmatter with required fields: file_type, title, description, version, last_updated, owners, tags, status, stability, domain
Every image (![]()) must have descriptive alt text explaining the image's purpose, not its appearance. Empty alt (![ ]()) is valid only for purely decorative images
Link text must describe the destination — never use 'click here', 'read more', or bare URLs as visible text
Every table must have a header row (| Header |). Avoid merged cells
Use headings to communicate document structure, not for visual styling
Do not rely on colour alone to convey information in diagrams or callout blocks
Mermaid diagrams must includeaccTitleandaccDescrattributes for accessibility
Specify language in frontmatter; use plain language, avoid jargon where possible
Files:
CHANGELOG.md
CHANGELOG.md
⚙️ CodeRabbit configuration file
CHANGELOG.md: Review CHANGELOG.md:
- Confirm entries follow Keep a Changelog 1.1.0 format.
- Each entry under [Unreleased] must include a PR link and issue link.
- Verify entries use the correct section headings (Added, Changed, Fixed, Deprecated, Removed, Security, Documentation, Performance).
- Check UK English spelling throughout.
Files:
CHANGELOG.md
**/*.{php,js,jsx,ts,tsx,css,scss,html}
📄 CodeRabbit inference engine (AGENTS.md)
Follow WordPress Coding Standards (CSS, HTML, JavaScript, PHP) and inline-documentation standards at all times
Files:
website/src/lib/glossary.tswebsite/src/lib/learn.tswebsite/src/lib/catalogue.tswebsite/src/lib/resources.ts
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{js,ts,jsx,tsx}: Follow ESLint/Prettier standards for JavaScript and TypeScript files
Avoid unnecessary JavaScript, defer/lazy-load where possible, and prefer native blocks
Files:
website/src/lib/glossary.tswebsite/src/lib/learn.tswebsite/src/lib/catalogue.tswebsite/src/lib/resources.ts
**/*.{js,ts}
⚙️ CodeRabbit configuration file
**/*.{js,ts}: Review JavaScript/TypeScript:
- Ensure code is linted and follows project style guides.
- Check for dead code, unused variables, and clear function naming.
- Validate accessibility and performance optimisations.
- Ensure tests are isolated and do not depend on external state.
- Check for descriptive test names and clear test structure.
Files:
website/src/lib/glossary.tswebsite/src/lib/learn.tswebsite/src/lib/catalogue.tswebsite/src/lib/resources.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: lightspeedwp/.github PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-06-03T17:57:58.761Z
Learning: Applies to **/*.{php,html,css,scss} : Ensure WCAG 2.2 AA minimum accessibility compliance with semantic HTML, keyboard support, and sufficient contrast
📚 Learning: 2026-06-03T17:57:58.761Z
Learnt from: CR
Repo: lightspeedwp/.github PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-06-03T17:57:58.761Z
Learning: Place repo-local Copilot and agent instructions in `.github/instructions/` or `.github/custom-instructions.md`
Applied to files:
website/src/pages/getting-started.astro
🔇 Additional comments (8)
website/src/components/AwesomeGithub/AwesomeGithubNav.astro (1)
355-357: 💤 Low valueVerify mobile search accessibility.
The search button is hidden on mobile (
display: none), which removes keyboard search (Cmd+K) access from mobile users. If search is a core feature, consider showing a search icon in the mobile nav menu or adding it to the hamburger menu links.Can you confirm whether mobile users need search access, or if it's intentionally omitted from the mobile experience?
website/src/pages/learning-hub/index.astro (1)
1-417: LGTM!website/src/pages/c/[type]/index.astro (1)
2-370: LGTM!website/src/pages/glossary/[term].astro (1)
1-315: LGTM!website/src/pages/references.astro (1)
1-410: LGTM!website/src/pages/why.astro (1)
1-257: LGTM!website/src/pages/learn/[track]/[lesson].astro (1)
1-378: LGTM!website/src/pages/cookbook/[slug].astro (1)
1-256: LGTM!
… comments - Add tabindex="-1" to <main id="main-content"> so skip-to-content focus works (WCAG 2.4.1) - Fix SearchPalette aria-expanded to reflect actual listbox visibility instead of hardcoded true - Sanitise localStorage branch value to only accept "main" or "develop" (injection guard) - Sync copy button aria-label with visible text on state change (WCAG 4.1.2) - Add scroll-margin-top: 104px to .glossary-group for sticky-nav hash navigation - Darken .kind--example and .kind--checklist badge colors for WCAG AA contrast in light mode; add dark-mode override for checklist badge - Guard track.lessons[0] CTA in learn/index.astro and learn/[track]/index.astro against empty tracks - Replace CSS selector interpolation with attribute-safe Array.find() for completed lesson slug matching - Add "plugins" to ResourceType union and getAvailableActions() map to match RESOURCE_TYPES registry - Replace hardcoded categories count "8" with String(CATEGORIES.length) on homepage - Append PR #841 and issue #842 links to CHANGELOG Unreleased entry https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH
Resolve conflicts by keeping our final Astro rebuild versions across all conflicted files. The develop branch contained intermediate Phase 1 files (awesome-github/ subfolder) that our branch superseded with the complete production rebuild. https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH
🔍 Reviewer Summary for PR #841CI Status: ✅ Recommendations
|
Linked issues
Relates to #840
Changelog
Added
<main id="main-content">for screen-reader and keyboard accessibility.Cmd/Ctrl+K) focus restoration: stores the triggering element on open and restores focus on close, preventing screen-reader disorientation.Fixed
slate-500(#565656) toslate-700(#404040) for WCAG AA compliance.margin-top: 72pxfrom hero sections across 9 pages — leftover from a previously fixed-position nav that caused an unwanted gap on mobile.awesome-githubprefix.var(--c-light-blue)(#7BE7FF) text colours withvar(--accent)on non-hero content areas —--accentis theme-aware so contrast passes WCAG AA in both light and dark modes.--space-40(160px) to--section-y(96px) on category and detail pages for improved vertical rhythm.documentrather than a singlequerySelectorbind, making it robust to multiple instances and View Transitions.localStorageaccess in the branch toggle wrapped intry/catchto preventSecurityErrorcrashes in private browsing.SearchPaletteTab key now traps focus inside the modal dialog (WCAG 2.1 SC 2.1.2).CatalogueItemtype import replaces verbose 200-char inline type signature inresources.ts.glossary.tsPR template path corrected fromPULL_REQUEST_TEMPLATE.mdtopull_request_template.md(case-sensitive GitHub blob URL)./getting-started/implementation-roadmap/,/getting-started/why-github-matters/) updated to/getting-started/across 4 pages.Risk Assessment
Risk Level: Low–Medium
Scope note: This PR's scope is broader than the original description implied. In addition to CSS/contrast fixes it also includes:
Cmd/Ctrl+K) wired via a custom DOM eventlocalStorageaccess (branch toggle preference) with private-browsing guardPotential Impact: Incorrect routing would produce 404s on static output; incorrect event wiring would break the search palette; focus-management bugs would affect keyboard/screen-reader users. No server-side logic, database, or auth is touched.
Mitigation Steps:
localStorageaccess is guarded withtry/catch.How to Test
Prerequisites
npm ciinwebsite/npm run build— confirm 244 pages, no errorsTest Steps
#main-content.Cmd/Ctrl+K. Tab cycles within the modal only. Esc closes and restores focus to the button that opened it./c/agents/— "Home" breadcrumb links to/./c/agents/use brand blue (#1E6AFF), not washed-out cyan./talk/and/agents/— "Getting Started" links resolve to/getting-started/.Edge Cases to Verify
Checklist (Global DoD / PR)
https://claude.ai/code/session_01VaY86RbnELdWvFyBdEMwLH