Rebuild website on Primer Brand design prototype - #2703
Conversation
Replace the Astro + Starlight site with the Brand Engineering design prototype, ported component-for-component onto plain Astro + React islands. The prototype is treated as the authority on markup and styling; dynamic data is injected into its components rather than the components being reinterpreted. Framework: - Remove @astrojs/starlight entirely, along with its document shell, search, footer and language selector. BaseLayout.astro now owns the document head, CSP, social meta and analytics. - Add @primer/react-brand and @astrojs/react. Alias the package to its ESM build in vite.resolve, since the default CJS entrypoint breaks named-export detection during SSR, and mark it noExternal so its stylesheet imports resolve. - Promote pagefind to an explicit devDependency; it was previously pulled in transitively by Starlight. Pages: home, the five catalogs, the five detail routes, contributors, Playbook index and articles, and the cookbook are all rendered by ported prototype components inside a shared PageShell. Detail pages share a DetailChassis (hero, breadcrumbs, sticky TOC with scroll-spy, prev/next) while keeping what makes each type distinct: a file switcher over bundled skill assets, an included-items grid and external provenance for plugins, and a hero-scale preview for extensions. i18n: resolve translated Playbook entries via Astro.currentLocale inside the shared article route instead of separate [locale] routes. The explicit routes collided with the i18n fallback routes, so translated articles were being shadowed by their English originals and 900 nonsensical double-locale pages were emitted. Search: TopNavSearch now queries the Pagefind index client-side in addition to the static resource index, merging on href and degrading to the static index in dev, where no index has been built. Also delete the superseded vanilla-TS page renderers and Astro partials, which the ported React components fully replace. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
Fixes the three axe violations surfaced by the a11y audit after the Primer Brand redesign: - aria-prohibited-attr: `aria-label` was set on roleless `div`s in InstructionDetail and PluginDetail. The "Applies to" list now uses list/listitem roles; plugin provenance uses a group role. - scrollable-region-focusable: the install command `code` element overflows horizontally but was not keyboard reachable. Added tabIndex to all three render sites. - color-contrast: the Playbook "New" label used the brand's success-fg on success-subtle, reaching only 4.09:1 in light mode. Stepped one down the same green ramp for 6.14:1. Scoped to light mode; dark mode already passed and its green-7 is near-black. Also corrects the stale route list in the audit script: /hooks/, /workflows/ and /tools/ have never existed as pages. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
Two issues surfaced by review of the redesigned site: Catalog facets rendered every option. The prototype's filter groups were built from small hardcoded arrays, but real data produces 193 tool options on /agents/ and 245 "Applies to" values on /instructions/. The sidebar grew to ~10,000px and stretched the whole catalog row, pushing the (already present) pagination control far below the fold so it read as missing. Adopt the prototype's own solution for this, which it had already applied to the extensions page: collapse groups past 10 options behind a "Show N more" toggle, and cap .filterOptions with an internal scroll area. Ported verbatim to the agents, instructions, skills, and plugins catalogs. Detail pages scroll inside .scrollHost rather than the document, but the footer came from PageShell, outside that element, so it stayed pinned over the content instead of appearing at the end. The prototype renders its footer inside the scroll host; PageShell now takes a renderFooter flag so DetailChassis can do the same. LearningArticleLayout already did this. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
Injected markdown inherited color from body, which sits outside the ThemeProvider and always resolved the light-mode token, making body copy unreadable in dark mode. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
Resource detail pages (agent, instruction, skill, plugin, extension) are not articles, and their markdown headings do not form a meaningful outline. Playbook and cookbook articles keep their TOC. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
Raw markdown-injected <a> elements previously fell back to the browser's default blue/purple link colours, which are harsh against the dark-mode background. Route them through --brand-color-text-link-rest (and the pressed/hover token) instead. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
…mode works LearningArticleLayout replaces PageShell for Playbook articles but never wrapped itself in a ThemeProvider, so its useTheme() call always fell back to Primer's light default regardless of the site's actual theme preference. Split the component into a thin ThemeProvider wrapper plus the existing implementation (now LearningArticleLayoutBody), matching the pattern already used by PageShell. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
Astro's default Shiki config bakes in the fixed 'github-dark' theme's literal colors, ignoring the site's actual light/dark mode - this made plain markdown-fenced code blocks (as opposed to the prototype's own SyntaxHighlightedCode component) always render a hardcoded dark box regardless of theme. Switch shikiConfig to the 'css-variables' theme so highlighted tokens resolve through --astro-code-* custom properties instead, then map those to the same brand color tokens the prototype's codeBlock uses (canvas-subtle background, border-muted border, brand text/link/accent colors for tokens). Raw markdown code blocks now match the prototype's bordered, canvas-subtle surface in both color modes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
The contributor badge rendered 0 on Playbook, Cookbook, home and custom pages, and reverted to 0 on hydration everywhere else. Two causes: - Shells that bypass PageShell (LearningArticleLayout, PlaybookIndex, PlaybookArticleBody, CookbookIndex, HomePage, TopNav, Custom) defaulted contributorsTotal to 0 instead of the site-data value. - site-data read .all-contributorsrc with node:fs at module scope. Those shells are client:load hydrated, so the read threw in the browser and the count reset to 0 after hydration. The count is now read once in astro.config.mjs and inlined through vite.define as __CONTRIBUTORS_TOTAL__, so it is a literal in both the server render and the client bundle. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
The filter option lists only set scrollbar-width: thin, so they rendered the platform default scrollbar. They now use the same muted, transparent track treatment as the article sidebar, which resolves through --brand-color-border-muted in both colour modes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
Plugin detail pages exposed only a copyable CLI command. They now lead with a ghapp://plugins/install deep link in the same split-button ActionMenu the other detail pages use, keeping the CLI command available as a Copy action in the menu. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
Astro 7 deprecates markdown.remarkPlugins in favour of passing a unified() processor from @astrojs/markdown-remark. Moves the GitHub admonitions plugin into markdown.processor, clearing the startup deprecation warning. shikiConfig stays at the markdown level as it is not part of UnifiedProcessorOptions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
Silently falling back to 0 is how the contributor badge regressed before, so a missing or malformed .all-contributorsrc now throws in production builds and warns in dev instead of shipping a wrong count. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
|
🟡 Contributor Reputation Check: MEDIUM risk
Maintainers: please review this contributor before merging. |
- Fix real typos flagged by codespell: 'Couldn't' -> 'Couldn't' (plain apostrophe, matching convention elsewhere in JSX) and 'Unparseable' -> 'Unparsable' in catalogFilters.ts - DetailChassis.tsx: replace sequential HTML entity unescaping with a single-pass replace to avoid double-unescape/injection risk flagged by CodeQL - SyntaxHighlightedCode.tsx: make the markup HTML comment regex match newlines so multi-line comments cannot break out of the token (Bad HTML filtering regexp) - pagefindSearch.ts: strip HTML tags in a loop until stable so nested/ malformed markup can't survive a single-pass strip (Incomplete multi-character sanitization) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
🔍 Vally Lint Results⛔ Findings need attention
Summary
Full linter output
|
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Existing routes regress to 404s, extension installation is misdirected, localization metadata is incorrect, and advertised catalog behavior remains incomplete.
Review tier: Balanced
Findings: 5
Pre-existing issues (52)
| Severity | Finding |
|---|---|
website/package.json — The locked @​primer/react-brand package declares node >=24, but both website deployment… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — installUrl is not a Copilot-app URL: generated in-repo records receive a GitHub tree URL, and… View comment |
|
website/scripts/a11y-audit.mjs — The rebuilt site has no /hooks/, /workflows/, or /tools/ routes (nor their former detail… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — External extension URLs are only normalized as strings by the data generator, but this helper… View comment |
|
website/src/pages/skills.astro — The generated skill records expose files as an array, but SkillsCatalog treats it as a number… View comment |
|
website/src/pages/learning-hub/[...slug].astro — englishId for the CLI landing document is learning-hub/cli-for-beginners/index, so… View comment |
|
website/src/lib/learning-hub-routes.ts — The translated workshop landing page is omitted from this predicate even though every configured… View comment |
|
docs/README.skills.md — This generated row now advertises numerous obj/ build outputs, but none of those files are… View comment |
|
website/src/components/brand/LearningArticleLayout.tsx — This article back-to-top control also forces smooth motion for users who have requested reduced… View comment |
|
website/src/components/brand/useAgentDetailScroll.ts — The back-to-top action always performs smooth scrolling, even when the user requests reduced… View comment |
|
website/src/layouts/LearningHubArticle.astro — Several generic articles begin with a Markdown H1 (for example… View comment |
|
website/src/pages/learning-hub/index.astro — The two workshop cards receive IDs ending in /index, so these links point to… View comment |
|
website/src/components/brand/SkillsCatalog.tsx — A clipboard failure is swallowed and execution continues to setCopied(true), so the UI announces… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — This handler reports success immediately even when the Clipboard API is unavailable or its promise… View comment |
|
website/src/components/brand/ExtensionDetail.tsx — Every screenshot is marked eager, so extensions with galleries download all full-size remote images… View comment |
|
website/src/pages/learning-hub/index.astro — The comment says the copilot-workshops tracks have their own entry point, but no rebuilt page or… View comment |
|
website/src/components/brand/LearningArticleLayout.tsx — The desktop Playbook header omits LanguageSelect, even though these workshop articles are the… View comment |
|
website/src/components/brand/navigation.ts — Hooks, workflows, and tools are omitted from the new destination list, and their former… View comment |
|
website/src/components/brand/SkillsCatalog.tsx — skills.json emits files as an array of file records, not a number (see… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — This catalog hardcodes name ordering and provides no sorting control, regressing the previous… View comment |
And 32 more that still need to be addressed.
Suppressed comments (14)
Previously missed (3) — in code that hasn't changed since the last review.
website/src/components/brand/AgentsCatalog.tsx:428
- Changing pages only replaces the grid contents; it leaves focus and the viewport down at the pagination controls, so users do not see the newly selected page. This contradicts the stated pagination/scrolling fix. After updating the page, scroll the catalog into view while respecting reduced-motion preferences.
website/src/components/brand/InstructionsCatalog.tsx:565 - Changing pages only replaces the grid contents; it leaves focus and the viewport down at the pagination controls, so users do not see the newly selected page. After updating the page, scroll the catalog into view while respecting reduced-motion preferences.
website/src/components/brand/SkillsCatalog.tsx:355 - Changing pages only replaces the grid contents; it leaves focus and the viewport down at the pagination controls, so users do not see the newly selected page. After updating the page, scroll the catalog into view while respecting reduced-motion preferences.
website/src/components/brand/ExtensionsCatalog.tsx:385
installUrlin generated extension data is the GitHub tree URL for built-in extensions, not aghapp://deep link. As a result, every catalog button labeled “Open in Copilot app” opens GitHub instead. Derive the app URL frompluginNameas the detail route does, and keepinstallUrlonly for the source fallback.
website/src/components/brand/SkillsCatalog.tsx:49- This URL uses GitHub's
/blob/route for a skill directory, so every catalog “View on GitHub” action points to a 404. Skill folders must use/tree/main/skills/<id>, matching the detail page.
website/scripts/a11y-audit.mjs:34 - The rebuild removes
/hooks/,/workflows/,/tools/and their detail routes from the page tree, and this change merely drops them from the audit. These are existing public resource pages (the Pagefind integration still indexes those route types), so the PR silently turns them into 404s despite stating that non-prototype pages remain functional. Restore/migrate the routes and keep representative audit coverage.
docs/README.skills.md:440 - This generated row now advertises
obj/build outputs that are explicitly ignored by.gitignoreand are not committed, so all of these new links are broken. Regenerate the README from a clean tree (or exclude ignored build directories) so only bundled skill assets are listed.
website/src/components/brand/PluginsCatalog.tsx:381 - Changing pages only replaces the grid contents; it leaves focus and the viewport down at the pagination controls, so users do not see the newly selected page. After updating the page, scroll the catalog into view while respecting reduced-motion preferences.
website/src/components/brand/ExtensionsCatalog.tsx:444 - Changing pages only replaces the grid contents; it leaves focus and the viewport down at the pagination controls, so users do not see the newly selected page. After updating the page, scroll the catalog into view while respecting reduced-motion preferences.
website/src/components/brand/InstructionsCatalog.tsx:114 sortModeis initialized to"az"without a setter or any sort control, making the"newest"branch unreachable. The PR promises catalog sorting, but this page can only sort alphabetically; expose a control that callssetSortMode(and reset pagination when it changes).
website/src/components/brand/PluginsCatalog.tsx:125sortModeis initialized to"az"without a setter or any sort control, so the catalog cannot perform the sorting promised by the PR and the declared"newest"mode is dead code. Add a sort control wired tosetSortModeand implement the newest ordering.
website/src/components/brand/AgentsCatalog.tsx:160- This catalog always sorts A–Z and exposes no sort state or control, so the sorting behavior described in the PR (including recent updates) is unavailable. Add a selectable sort mode and apply it here before pagination.
website/src/components/brand/SkillsCatalog.tsx:141 - This catalog always sorts A–Z and exposes no sort state or control, so the sorting behavior described in the PR is unavailable. Add a selectable sort mode and apply it here before pagination.
website/src/components/brand/ExtensionsCatalog.tsx:193 - This catalog always sorts A–Z and exposes no sort state or control, so the sorting behavior described in the PR is unavailable. Add a selectable sort mode and apply it here before pagination.
Detail page Previous/Up next links were stacked vertically. Change .nextUp to a row layout (space-between) so Previous sits left-aligned and Up next right-aligned on the same row, with a max-width: 40rem media query reverting to a stacked column layout on small screens. Use an explicit .nextUpNext modifier class (applied to the "Up next" link specifically) with margin-inline-start: auto instead of a positional :last-child selector, so the link right-aligns correctly even when it is the only link present (e.g. the first item in a catalog, which has no Previous link). Fixes #2966
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Extension installation, pagination behavior, article anchors, naming consistency, generated documentation, sorting, and accessibility coverage have unresolved defects.
Review tier: Balanced
Findings: 5
Pre-existing issues (52)
| Severity | Finding |
|---|---|
website/package.json — The locked @​primer/react-brand package declares node >=24, but both website deployment… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — installUrl is not a Copilot-app URL: generated in-repo records receive a GitHub tree URL, and… View comment |
|
website/scripts/a11y-audit.mjs — The rebuilt site has no /hooks/, /workflows/, or /tools/ routes (nor their former detail… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — External extension URLs are only normalized as strings by the data generator, but this helper… View comment |
|
website/src/pages/skills.astro — The generated skill records expose files as an array, but SkillsCatalog treats it as a number… View comment |
|
website/src/pages/learning-hub/[...slug].astro — englishId for the CLI landing document is learning-hub/cli-for-beginners/index, so… View comment |
|
website/src/lib/learning-hub-routes.ts — The translated workshop landing page is omitted from this predicate even though every configured… View comment |
|
docs/README.skills.md — This generated row now advertises numerous obj/ build outputs, but none of those files are… View comment |
|
website/src/components/brand/LearningArticleLayout.tsx — This article back-to-top control also forces smooth motion for users who have requested reduced… View comment |
|
website/src/components/brand/useAgentDetailScroll.ts — The back-to-top action always performs smooth scrolling, even when the user requests reduced… View comment |
|
website/src/layouts/LearningHubArticle.astro — Several generic articles begin with a Markdown H1 (for example… View comment |
|
website/src/pages/learning-hub/index.astro — The two workshop cards receive IDs ending in /index, so these links point to… View comment |
|
website/src/components/brand/SkillsCatalog.tsx — A clipboard failure is swallowed and execution continues to setCopied(true), so the UI announces… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — This handler reports success immediately even when the Clipboard API is unavailable or its promise… View comment |
|
website/src/components/brand/ExtensionDetail.tsx — Every screenshot is marked eager, so extensions with galleries download all full-size remote images… View comment |
|
website/src/pages/learning-hub/index.astro — The comment says the copilot-workshops tracks have their own entry point, but no rebuilt page or… View comment |
|
website/src/components/brand/LearningArticleLayout.tsx — The desktop Playbook header omits LanguageSelect, even though these workshop articles are the… View comment |
|
website/src/components/brand/navigation.ts — Hooks, workflows, and tools are omitted from the new destination list, and their former… View comment |
|
website/src/components/brand/SkillsCatalog.tsx — skills.json emits files as an array of file records, not a number (see… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — This catalog hardcodes name ordering and provides no sorting control, regressing the previous… View comment |
And 32 more that still need to be addressed.
Suppressed comments (12)
Previously missed (4) — in code that hasn't changed since the last review.
website/src/components/brand/AgentsCatalog.tsx:428
- Changing pages only swaps the sliced records; because the click occurs below the grid and default navigation is prevented, the viewport remains at the pagination/footer instead of showing the new page. Scroll the catalog back into view after selecting a page (respecting reduced motion).
website/src/components/brand/InstructionsCatalog.tsx:565 - Changing pages only swaps the sliced records; because the click occurs below the grid and default navigation is prevented, the viewport remains at the pagination/footer instead of showing the new page. Scroll the catalog back into view after selecting a page (respecting reduced motion).
website/src/components/brand/LearningHubIndex.tsx:847 - Changing pages only swaps the sliced records; because the click occurs below the article grid and default navigation is prevented, the viewport remains at the pagination/footer instead of showing the new page. Scroll the catalog back into view after selecting a page (respecting reduced motion).
website/src/components/brand/SkillsCatalog.tsx:355 - Changing pages only swaps the sliced records; because the click occurs below the grid and default navigation is prevented, the viewport remains at the pagination/footer instead of showing the new page. Scroll the catalog back into view after selecting a page (respecting reduced motion).
website/src/components/brand/ExtensionsCatalog.tsx:385
- The primary CTA does not open the Copilot app. For built-in extensions, generated
installUrlis the GitHub tree URL (eng/generate-website-data.mjs:1224-1251); for external extensions it is an external repository URL. The detail route correctly derives aghapp://plugins/install?...URL frompluginNameinstead (website/src/pages/extension/[id].astro:111-121). Derive and use that deep link here for built-in extensions, and label external URLs according to their actual destination.
docs/README.skills.md:440 - This generated row now advertises local
obj/build outputs as bundled skill assets, even thoughobj/is ignored by the repository. Besides exposing irrelevant NuGet intermediates to users, this makes README generation depend on local build residue. Exclude ignored/build directories in the asset walker and regenerate this file without these entries.
website/src/components/brand/navigation.ts:13 - The PR describes this section as renamed to “Playbook,” but the new primary navigation still exposes “Learning Hub”; the index title and search labels do the same. Update the user-facing name consistently (the existing
/learning-hub/route may remain for compatibility).
website/scripts/a11y-audit.mjs:35 - The audit no longer visits any actual Learning Hub article:
/learning-hub/is only the catalog and/learning-hub/cookbook/uses a separate index component. As a result, the new markdown article chassis, generated TOC, callouts, and language selector receive no axe coverage. Keep at least one generic article route in this list.
website/src/components/brand/PluginsCatalog.tsx:381 - Changing pages only swaps the sliced records; because the click occurs below the grid and default navigation is prevented, the viewport remains at the pagination/footer instead of showing the new page. Scroll the catalog back into view after selecting a page (respecting reduced motion).
website/src/components/brand/ExtensionsCatalog.tsx:444 - Changing pages only swaps the sliced records; because the click occurs below the grid and default navigation is prevented, the viewport remains at the pagination/footer instead of showing the new page. Scroll the catalog back into view after selecting a page (respecting reduced motion).
website/src/components/brand/InstructionsCatalog.tsx:114 sortModeis permanently initialized to"az"because the setter is discarded and this component renders no sort control. Consequently the"newest"branch below is unreachable, so the catalog does not provide the sorting behavior described by the PR. Retain the setter and wire it to a sort control (resetting pagination when it changes).
website/src/components/brand/PluginsCatalog.tsx:125sortModecan never change because its setter is discarded and no sort control is rendered. The advertised catalog sorting is therefore unavailable; additionally, the non-azpath below would preserve input order rather than explicitly sort bylastUpdated. Add a real sort control and implement the newest comparator.
The .proTip callout (Note/Tip/Caution admonitions in Learning Hub articles, and the "Maintained outside this repository" notice on external Plugin Detail pages) had its own 32px horizontal margin. The prototype places this callout as a sibling of .articleSection (which has no horizontal padding of its own), using that margin to align its edges with the section's own 32px padding. Our port always renders it nested *inside* an already-padded .articleSection, so the extra margin doubled up with that padding, making the callout visibly narrower than the surrounding paragraph/table text -- most obvious on narrow viewports. Remove the horizontal margin (keep only the bottom spacing) in both dotnet-upgrade.module.css and github-copilot-app.module.css so the callout's internal padding lines up with the article text on both edges, at all viewport widths. Fixes #2967
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The generated skills README now publishes ignored .NET build artifacts from an obj directory as bundled skill assets.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: 5
Pre-existing issues (52)
| Severity | Finding |
|---|---|
website/package.json — The locked @​primer/react-brand package declares node >=24, but both website deployment… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — installUrl is not a Copilot-app URL: generated in-repo records receive a GitHub tree URL, and… View comment |
|
website/scripts/a11y-audit.mjs — The rebuilt site has no /hooks/, /workflows/, or /tools/ routes (nor their former detail… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — External extension URLs are only normalized as strings by the data generator, but this helper… View comment |
|
website/src/pages/skills.astro — The generated skill records expose files as an array, but SkillsCatalog treats it as a number… View comment |
|
website/src/pages/learning-hub/[...slug].astro — englishId for the CLI landing document is learning-hub/cli-for-beginners/index, so… View comment |
|
website/src/lib/learning-hub-routes.ts — The translated workshop landing page is omitted from this predicate even though every configured… View comment |
|
docs/README.skills.md — This generated row now advertises numerous obj/ build outputs, but none of those files are… View comment |
|
website/src/components/brand/LearningArticleLayout.tsx — This article back-to-top control also forces smooth motion for users who have requested reduced… View comment |
|
website/src/components/brand/useAgentDetailScroll.ts — The back-to-top action always performs smooth scrolling, even when the user requests reduced… View comment |
|
website/src/layouts/LearningHubArticle.astro — Several generic articles begin with a Markdown H1 (for example… View comment |
|
website/src/pages/learning-hub/index.astro — The two workshop cards receive IDs ending in /index, so these links point to… View comment |
|
website/src/components/brand/SkillsCatalog.tsx — A clipboard failure is swallowed and execution continues to setCopied(true), so the UI announces… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — This handler reports success immediately even when the Clipboard API is unavailable or its promise… View comment |
|
website/src/components/brand/ExtensionDetail.tsx — Every screenshot is marked eager, so extensions with galleries download all full-size remote images… View comment |
|
website/src/pages/learning-hub/index.astro — The comment says the copilot-workshops tracks have their own entry point, but no rebuilt page or… View comment |
|
website/src/components/brand/LearningArticleLayout.tsx — The desktop Playbook header omits LanguageSelect, even though these workshop articles are the… View comment |
|
website/src/components/brand/navigation.ts — Hooks, workflows, and tools are omitted from the new destination list, and their former… View comment |
|
website/src/components/brand/SkillsCatalog.tsx — skills.json emits files as an array of file records, not a number (see… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — This catalog hardcodes name ordering and provides no sorting control, regressing the previous… View comment |
And 32 more that still need to be addressed.
Agents, Instructions, Skills, and Plugins catalog cards (.item) used the desktop 60px padding at every viewport, including phone widths, because their @media (max-width: 47.99rem) block never reduced it -- unlike the Extension catalog, which drops to a 32px inset at that breakpoint. This made cards on those four catalogs look inconsistently over-indented on mobile compared to Extension cards. Add the same `.item { padding: var(--base-size-32); }` override to the mobile media query in agents.module.css, instructions.module.css, and skills.module.css. plugins.module.css already had an override, but with an asymmetric 32px/24px padding -- normalized it to the same 32px on all sides used everywhere else. Fixes #2968
There was a problem hiding this comment.
Copilot review overview
Review tier: Balanced
Findings: 5
Pre-existing issues (52)
| Severity | Finding |
|---|---|
website/package.json — The locked @​primer/react-brand package declares node >=24, but both website deployment… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — installUrl is not a Copilot-app URL: generated in-repo records receive a GitHub tree URL, and… View comment |
|
website/scripts/a11y-audit.mjs — The rebuilt site has no /hooks/, /workflows/, or /tools/ routes (nor their former detail… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — External extension URLs are only normalized as strings by the data generator, but this helper… View comment |
|
website/src/pages/skills.astro — The generated skill records expose files as an array, but SkillsCatalog treats it as a number… View comment |
|
website/src/pages/learning-hub/[...slug].astro — englishId for the CLI landing document is learning-hub/cli-for-beginners/index, so… View comment |
|
website/src/lib/learning-hub-routes.ts — The translated workshop landing page is omitted from this predicate even though every configured… View comment |
|
docs/README.skills.md — This generated row now advertises numerous obj/ build outputs, but none of those files are… View comment |
|
website/src/components/brand/LearningArticleLayout.tsx — This article back-to-top control also forces smooth motion for users who have requested reduced… View comment |
|
website/src/components/brand/useAgentDetailScroll.ts — The back-to-top action always performs smooth scrolling, even when the user requests reduced… View comment |
|
website/src/layouts/LearningHubArticle.astro — Several generic articles begin with a Markdown H1 (for example… View comment |
|
website/src/pages/learning-hub/index.astro — The two workshop cards receive IDs ending in /index, so these links point to… View comment |
|
website/src/components/brand/SkillsCatalog.tsx — A clipboard failure is swallowed and execution continues to setCopied(true), so the UI announces… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — This handler reports success immediately even when the Clipboard API is unavailable or its promise… View comment |
|
website/src/components/brand/ExtensionDetail.tsx — Every screenshot is marked eager, so extensions with galleries download all full-size remote images… View comment |
|
website/src/pages/learning-hub/index.astro — The comment says the copilot-workshops tracks have their own entry point, but no rebuilt page or… View comment |
|
website/src/components/brand/LearningArticleLayout.tsx — The desktop Playbook header omits LanguageSelect, even though these workshop articles are the… View comment |
|
website/src/components/brand/navigation.ts — Hooks, workflows, and tools are omitted from the new destination list, and their former… View comment |
|
website/src/components/brand/SkillsCatalog.tsx — skills.json emits files as an array of file records, not a number (see… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — This catalog hardcodes name ordering and provides no sorting control, regressing the previous… View comment |
And 32 more that still need to be addressed.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
YouTube embeds are blocked by CSP, and several catalogs have unresolved dark-theme and pagination-navigation regressions.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: 5
New issues introduced by this change (9)
| Severity | Finding |
|---|---|
website/src/layouts/BaseLayout.astro — The new Playbook components embed YouTube iframes (for example, VideoCarousel.tsx:86-90), but… |
|
website/src/components/brand/AgentsCatalog.tsx — useTheme() executes before the descendant PageShell can provide its theme context, so this… |
|
website/src/components/brand/ExtensionsCatalog.tsx — useTheme() executes before the descendant PageShell can provide its theme context, so this… |
|
website/src/components/brand/InstructionsCatalog.tsx — useTheme() executes before the descendant PageShell can provide its theme context, so this… |
|
website/src/components/brand/InstructionsCatalog.tsx — Changing pages only updates state, leaving the viewport and keyboard focus on the pager below the… |
|
website/src/components/brand/PluginDetail.tsx — useTheme() runs before DetailChassis renders the descendant PageShell provider, so this… |
|
website/src/components/brand/PluginsCatalog.tsx — useTheme() executes before the descendant PageShell can provide its theme context, so this… |
|
website/src/components/brand/SkillsCatalog.tsx — useTheme() executes before the descendant PageShell can provide its theme context, so this… |
|
website/src/components/brand/SkillsCatalog.tsx — Changing pages only updates state, leaving the viewport and keyboard focus on the pager below the… |
Pre-existing issues (40)
| Severity | Finding |
|---|---|
website/package.json — The locked @​primer/react-brand package declares node >=24, but both website deployment… View comment |
|
website/scripts/a11y-audit.mjs — The rebuilt site has no /hooks/, /workflows/, or /tools/ routes (nor their former detail… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — External extension URLs are only normalized as strings by the data generator, but this helper… View comment |
|
website/src/pages/skills.astro — The generated skill records expose files as an array, but SkillsCatalog treats it as a number… View comment |
|
website/src/components/brand/SkillsCatalog.tsx — A clipboard failure is swallowed and execution continues to setCopied(true), so the UI announces… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — This handler reports success immediately even when the Clipboard API is unavailable or its promise… View comment |
|
website/src/pages/learning-hub/index.astro — The comment says the copilot-workshops tracks have their own entry point, but no rebuilt page or… View comment |
|
website/src/components/brand/LearningArticleLayout.tsx — The desktop Playbook header omits LanguageSelect, even though these workshop articles are the… View comment |
|
website/src/components/brand/navigation.ts — Hooks, workflows, and tools are omitted from the new destination list, and their former… View comment |
|
website/src/components/brand/SkillsCatalog.tsx — skills.json emits files as an array of file records, not a number (see… View comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — This catalog hardcodes name ordering and provides no sorting control, regressing the previous… View comment |
|
website/src/components/brand/InstructionsCatalog.tsx — sortMode has no setter and is permanently "az", so the "newest" branch below is unreachable… View comment |
|
website/src/components/brand/PluginsCatalog.tsx — sortMode has no setter and is permanently "az", making the advertised catalog sorting… View comment |
|
website/src/components/brand/SkillsCatalog.tsx — This catalog now always sorts A–Z and exposes no sort control, although the previous page offered… View comment |
|
website/src/components/brand/AgentsCatalog.tsx — This catalog now always sorts A–Z and exposes no sort control, although the previous page offered… View comment |
|
website/src/pages/learning-hub/[...slug].astro — For nested index.md entries this self-link still includes /index/, even after the route should… View comment |
|
website/src/pages/learning-hub/[...slug].astro — Nested collection indexes retain the literal index segment here (for example,… View comment |
|
website/src/components/brand/navigation.ts — The Playbook destination is present in destinations but excluded from AwesomeCopilotPage, so… View comment |
|
website/src/components/brand/CookbookRecipe.tsx — The cookbook's raw file URL is cross-origin, so download does not force a save and this action… View comment |
|
website/src/components/brand/SkillDetail.tsx — activeRawUrl is cross-origin, so the download attribute cannot force saving the selected skill… View comment |
And 20 more that still need to be addressed.
Issues resolved since last review (12)
| Severity | Finding |
|---|---|
website/src/pages/learning-hub/[...slug].astro — englishId for the CLI landing document is learning-hub/cli-for-beginners/index, so… View resolved comment |
|
website/src/lib/learning-hub-routes.ts — The translated workshop landing page is omitted from this predicate even though every configured… View resolved comment |
|
docs/README.skills.md — This generated row now advertises numerous obj/ build outputs, but none of those files are… View resolved comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — installUrl is not a Copilot-app URL: generated in-repo records receive a GitHub tree URL, and… View resolved comment |
|
website/src/components/brand/CookbookIndex.tsx — This newly added component duplicates components/brand/learning-hub/CookbookIndex.tsx, but the… View resolved comment |
|
website/src/components/brand/LearningArticleLayout.tsx — This article back-to-top control also forces smooth motion for users who have requested reduced… View resolved comment |
|
website/src/components/brand/useAgentDetailScroll.ts — The back-to-top action always performs smooth scrolling, even when the user requests reduced… View resolved comment |
|
website/src/components/brand/navigation.ts — The PR description says the Learning Hub is renamed to “Playbook”, but the rebuilt primary… View resolved comment |
|
website/src/layouts/LearningHubArticle.astro — Several generic articles begin with a Markdown H1 (for example… View resolved comment |
|
website/src/pages/learning-hub/index.astro — The two workshop cards receive IDs ending in /index, so these links point to… View resolved comment |
|
website/src/components/brand/ExtensionDetail.tsx — Every screenshot is marked eager, so extensions with galleries download all full-size remote images… View resolved comment |
|
website/src/components/brand/searchIndex.ts — staticPages(base) defines the fixed Pages results promised by this adapter, but it is never… View resolved comment |
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
website/src/components/brand/AgentsCatalog.tsx:455
- Changing pages only updates state, leaving the viewport and keyboard focus on the pager below the grid; the newly rendered cards remain above the viewport. Mirror the post-change scroll/focus handling already used by
PluginsCatalogandExtensionsCatalogso each page change returns users to#catalog.
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Several paginated catalogs lose viewport context, and two programmatic scroll paths still ignore reduced-motion preferences.
Review tier: Balanced
Findings: None
Issues resolved since last review (49)
| Severity | Finding |
|---|---|
website/src/components/brand/SkillsCatalog.tsx — Changing pages only updates state, leaving the viewport and keyboard focus on the pager below the… View resolved comment |
|
website/src/components/brand/SkillsCatalog.tsx — useTheme() executes before the descendant PageShell can provide its theme context, so this… View resolved comment |
|
website/src/components/brand/PluginsCatalog.tsx — useTheme() executes before the descendant PageShell can provide its theme context, so this… View resolved comment |
|
website/src/components/brand/PluginDetail.tsx — useTheme() runs before DetailChassis renders the descendant PageShell provider, so this… View resolved comment |
|
website/src/components/brand/InstructionsCatalog.tsx — Changing pages only updates state, leaving the viewport and keyboard focus on the pager below the… View resolved comment |
|
website/src/components/brand/InstructionsCatalog.tsx — useTheme() executes before the descendant PageShell can provide its theme context, so this… View resolved comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — useTheme() executes before the descendant PageShell can provide its theme context, so this… View resolved comment |
|
website/src/components/brand/AgentsCatalog.tsx — useTheme() executes before the descendant PageShell can provide its theme context, so this… View resolved comment |
|
website/src/layouts/BaseLayout.astro — The new Playbook components embed YouTube iframes (for example, VideoCarousel.tsx:86-90), but… View resolved comment |
|
website/package.json — The locked @​primer/react-brand package declares node >=24, but both website deployment… View resolved comment |
|
website/src/components/brand/SkillsCatalog.tsx — A clipboard failure is swallowed and execution continues to setCopied(true), so the UI announces… View resolved comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — This handler reports success immediately even when the Clipboard API is unavailable or its promise… View resolved comment |
|
website/src/pages/learning-hub/index.astro — The comment says the copilot-workshops tracks have their own entry point, but no rebuilt page or… View resolved comment |
|
website/src/components/brand/LearningArticleLayout.tsx — The desktop Playbook header omits LanguageSelect, even though these workshop articles are the… View resolved comment |
|
website/src/components/brand/navigation.ts — Hooks, workflows, and tools are omitted from the new destination list, and their former… View resolved comment |
|
website/src/components/brand/SkillsCatalog.tsx — skills.json emits files as an array of file records, not a number (see… View resolved comment |
|
website/scripts/a11y-audit.mjs — The rebuilt site has no /hooks/, /workflows/, or /tools/ routes (nor their former detail… View resolved comment |
|
website/src/components/brand/ExtensionsCatalog.tsx — This catalog hardcodes name ordering and provides no sorting control, regressing the previous… View resolved comment |
|
website/src/components/brand/InstructionsCatalog.tsx — sortMode has no setter and is permanently "az", so the "newest" branch below is unreachable… View resolved comment |
|
website/src/components/brand/PluginsCatalog.tsx — sortMode has no setter and is permanently "az", making the advertised catalog sorting… View resolved comment |
And 29 more resolved.
Suppressed comments (6)
Previously missed (4) — in code that hasn't changed since the last review.
website/src/components/brand/AgentsCatalog.tsx:455
- Changing pages only updates state, so the replacement agent cards render above the still-focused paginator and the user remains at the bottom of the old result set. Apply the same post-render scroll/focus behavior used by
PluginsCatalogandExtensionsCatalog(and make#catalogprogrammatically focusable).
website/src/components/brand/DetailChassis.tsx:213 - This TOC jump hard-codes smooth scrolling, so detail pages still animate when
prefers-reduced-motion: reduceis enabled. Replace it with the sharedgetScrollBehavior()helper used by the other detail/article scrolling paths.
website/src/components/brand/LearningHubIndex.tsx:582 - This explicit smooth scroll still animates for users who request reduced motion; the CSS media query cannot override a programmatic
behavior: "smooth". Use the sharedgetScrollBehavior()helper here.
website/src/components/brand/LearningHubIndex.tsx:847 - The Playbook paginator updates the six-card page in place but leaves users at the paginator below the replacement results. After rendering, scroll and focus a programmatically focusable
#catalog, matching the behavior already implemented for plugin and extension pagination.
website/src/components/brand/InstructionsCatalog.tsx:584
- Changing pages leaves the viewport and keyboard focus on the paginator while the new instruction cards render above it. Mirror the reduced-motion-aware scroll/focus effect already present in
PluginsCatalogandExtensionsCatalog, withtabIndex={-1}on#catalog.
website/src/components/brand/SkillsCatalog.tsx:385 - This page change replaces the skill results above the paginator without moving the viewport or focus, so users remain below the newly rendered cards. Add the same post-render scroll/focus handling and focusable
#catalogtarget used by the plugin and extension catalogs.
…lamp # Conflicts: # eng/yaml-parser.mjs
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Reduced-motion handling, skill downloads, and search defaults contain unresolved functional issues.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: 2
New issues introduced by this change (2)
| Severity | Finding |
|---|---|
website/src/components/brand/DetailChassis.tsx — The TOC forces smooth scrolling even when the user has requested reduced motion. Other new… |
|
website/src/components/brand/LearningArticleLayout.tsx — Defaulting the search index to an empty array breaks search on every bespoke Playbook page and the… |
Suppressed comments (1)
website/src/components/brand/SkillDetail.tsx:373
- This
downloadattribute is ignored becauseactiveRawUrlpoints toraw.githubusercontent.com; the control opens the raw file instead of downloading it. Route the action through the existingdownloadFile(activeRawUrl, active.name)helper, as the other download controls do.
| document | ||
| .getElementById(section.id) | ||
| ?.scrollIntoView({ | ||
| behavior: "smooth", |
| heroCta, | ||
| heroExtra, | ||
| tocSections, | ||
| searchIndex = [], |



Pull Request Checklist
npm startand verified thatREADME.mdis up to date.mainbranch for this pull request.Description
This rebuilds the
website/app on the Brand Engineering design prototype, replacing the previous Starlight-based UI with components and styling ported directly from the prototype (Astro 7 + React +@primer/react-brand). The prototype is treated as the design authority: catalogs, detail pages, the home page, navigation, search, and the renamed "Playbook" (formerly Learning Hub) all now use the prototype's components as-is, with dynamic data (agent/skill/plugin/contributor counts, search index, catalog listings) injected at build time rather than reinvented.Scope covered by this PR:
ThemeProvideron the Playbook layout), softened scrollbars on filter/sidebar lists, a broken contributor count that reverted to zero after hydration, and an Astro 7 markdown API deprecation warningNotable implementation details
.all-contributorsrcat build time and inlined viavite.define, since several page shells areclient:loadhydrated and can't safely read the filesystem in the browser. A missing/malformed manifest now fails production builds instead of silently rendering0.markdown.remarkPluginsoption to amarkdown.processor: unified({...})config per Astro 7's guidance, preserving GFM, SmartyPants, and the GitHub-admonitions-to-directives conversion used by mirrored Playbook content.ghapp://plugins/install?source=<id>@awesome-copilotdeep link into the Copilot app (mirroring the existing VS Code deep-link pattern on agent pages), with "copy CLI install command" available as a secondary action in the same split-button menu.Type of Contribution
Additional Notes
This PR does not yet cover every page that exists on the current site; pages without a corresponding design prototype were built following the existing site's UX as a functional guide, using the prototype's components as the visual/interaction authority.
npm run buildpasses (1084 pages) andnpm run plugin:validate/npm run skill:validateare unaffected, as this PR only toucheswebsite/.By submitting this pull request, I confirm that my contribution abides by the Code of Conduct and will be licensed under the MIT License.