🧠 Context
There's no on-site call to action telling visitors how to contribute. This ticket adds a primary button to each gallery page, on the header row:
- Projects page (
/projects): an "Add a project" button.
- Webring page (
/webring): a "Join the webring" button.
Both link out to the repo's README, deep-linked to the relevant how-to section (those sections currently say "Coming soon" and get filled in separately — the link target is stable regardless):
- Add a project →
https://github.com/CarletonComputerScienceSociety/showcase#adding-a-project
- Join the webring →
https://github.com/CarletonComputerScienceSociety/showcase#joining-the-webring
(GitHub auto-generates those heading anchors from the README's ## Adding a project / ## Joining the webring headings.)
Layout: on desktop the button sits on the header row, right-aligned and sized to its content, opposite the title + description — the primary action's home. On mobile it stacks below the description as a full-width button with centered text (so it lines up with the full-width search bar that will eventually sit below it on small screens (not implemented yet). Note the projects page will later grow a separate filter/search toolbar row below the header; this button owns the header-row right slot, so keep it on the header row and leave the area between the header and the grid alone. Style: Carleton red with white text (bg-accent / text-accent-contrast).
See images below for an example mockup for reference:
Desktop:

Mobile:

Disclaimer: I'm not the best at UI design so if you think a different layout would look better, feel free to play around with it and share for feedback!
Files you'll touch:
src/pages/projects.astro (header area)
src/pages/webring.astro (header area)
Don't touch:
- The
FILTER BAR insertion point comment in projects.astro and the #project-grid <ul> — the button goes on the header row, not in that area and not inside the grid (it must not become a card or interfere with the filter/search wiring that lands there later).
- The two-column layout block in
webring.astro — the button goes above it, on the header row.
Card.astro, other components, and the content schema.
🛠️ Implementation Plan
-
Projects page header. In src/pages/projects.astro, wrap the existing <h1> + description <p> in a left-hand block and add the button as a sibling, in a container that's justify-between on wide screens and stacks on mobile. Keep the FILTER BAR insertion point comment exactly where it is, below this header block.
<div
class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between"
>
<div>
<h1 class="text-2xl font-bold tracking-tight">Projects</h1>
<p class="text-muted mt-1">
Projects built by Carleton Computer Science students.
</p>
</div>
<a
href="https://github.com/CarletonComputerScienceSociety/showcase#adding-a-project"
target="_blank"
rel="noopener"
class="bg-accent text-accent-contrast w-full rounded-md px-4 py-2 text-center text-sm font-medium transition-opacity hover:opacity-90 sm:w-auto sm:shrink-0"
>
Add a project
</a>
</div>
(Adjust code and styling as needed)
Mobile vs desktop width: on mobile the button is full-width with centered text (the w-full text-center above — in the stacked flex-col it fills the row, matching the full-width search bar below it). On desktop sm:w-auto shrinks it back to its content so it sits compact and right-aligned on the header row. So the label is centered on mobile and the button never looks awkwardly left-aligned or oversized.
-
Webring page header. Do the same in src/pages/webring.astro — wrap its <h1> + description, add a "Join the webring" button with the #joining-the-webring href, on the header row above the two-column layout block. Use the same button classes so the two pages match.
-
Consistency. The two buttons should be visually identical except for label/href. If you'd rather not duplicate the markup, a tiny shared component (props: label, href) is fine — but keep it simple; inline is acceptable. Either way, match the styling exactly across both pages.
-
Optional polish. If you want, add a small trailing icon (the project uses astro-icon with the lucide set — e.g. <Icon name="lucide:arrow-up-right" />) inside the button to signal it goes off-site, or maybe a + Icon to the left of the text (either/or, not both); mark it aria-hidden (decorative — the button's text already names it; aria-hidden hides the icon from screen readers only, it stays visible). Not required.
-
Verify in pnpm dev: on a wide screen each button is right-aligned next to its page intro; on a narrow screen it stacks below the description; both are red/white, hover works, and each opens the correct README section in a new tab. Confirm the project grid and the area reserved for the filter/search toolbar are unaffected.
✅ Acceptance Criteria
🧠 Context
There's no on-site call to action telling visitors how to contribute. This ticket adds a primary button to each gallery page, on the header row:
/projects): an "Add a project" button./webring): a "Join the webring" button.Both link out to the repo's README, deep-linked to the relevant how-to section (those sections currently say "Coming soon" and get filled in separately — the link target is stable regardless):
https://github.com/CarletonComputerScienceSociety/showcase#adding-a-projecthttps://github.com/CarletonComputerScienceSociety/showcase#joining-the-webring(GitHub auto-generates those heading anchors from the README's
## Adding a project/## Joining the webringheadings.)Layout: on desktop the button sits on the header row, right-aligned and sized to its content, opposite the title + description — the primary action's home. On mobile it stacks below the description as a full-width button with centered text (so it lines up with the full-width search bar that will eventually sit below it on small screens (not implemented yet). Note the projects page will later grow a separate filter/search toolbar row below the header; this button owns the header-row right slot, so keep it on the header row and leave the area between the header and the grid alone. Style: Carleton red with white text (
bg-accent/text-accent-contrast).See images below for an example mockup for reference:


Desktop:
Mobile:
Disclaimer: I'm not the best at UI design so if you think a different layout would look better, feel free to play around with it and share for feedback!
Files you'll touch:
src/pages/projects.astro(header area)src/pages/webring.astro(header area)Don't touch:
FILTER BAR insertion pointcomment inprojects.astroand the#project-grid<ul>— the button goes on the header row, not in that area and not inside the grid (it must not become a card or interfere with the filter/search wiring that lands there later).webring.astro— the button goes above it, on the header row.Card.astro, other components, and the content schema.🛠️ Implementation Plan
Projects page header. In
src/pages/projects.astro, wrap the existing<h1>+ description<p>in a left-hand block and add the button as a sibling, in a container that'sjustify-betweenon wide screens and stacks on mobile. Keep theFILTER BAR insertion pointcomment exactly where it is, below this header block.(Adjust code and styling as needed)
Mobile vs desktop width: on mobile the button is full-width with centered text (the
w-full text-centerabove — in the stackedflex-colit fills the row, matching the full-width search bar below it). On desktopsm:w-autoshrinks it back to its content so it sits compact and right-aligned on the header row. So the label is centered on mobile and the button never looks awkwardly left-aligned or oversized.Webring page header. Do the same in
src/pages/webring.astro— wrap its<h1>+ description, add a "Join the webring" button with the#joining-the-webringhref, on the header row above the two-column layout block. Use the same button classes so the two pages match.Consistency. The two buttons should be visually identical except for label/href. If you'd rather not duplicate the markup, a tiny shared component (props:
label,href) is fine — but keep it simple; inline is acceptable. Either way, match the styling exactly across both pages.Optional polish. If you want, add a small trailing icon (the project uses
astro-iconwith thelucideset — e.g.<Icon name="lucide:arrow-up-right" />) inside the button to signal it goes off-site, or maybe a+Icon to the left of the text (either/or, not both); mark itaria-hidden(decorative — the button's text already names it;aria-hiddenhides the icon from screen readers only, it stays visible). Not required.Verify in
pnpm dev: on a wide screen each button is right-aligned next to its page intro; on a narrow screen it stacks below the description; both are red/white, hover works, and each opens the correct README section in a new tab. Confirm the project grid and the area reserved for the filter/search toolbar are unaffected.✅ Acceptance Criteria
/projectsshows an "Add a project" button linking to the repo README#adding-a-project./webringshows a "Join the webring" button linking to the repo README#joining-the-webring.bg-accent/text-accent-contrast) and identical styling.target="_blank" rel="noopener").FILTER BARinsertion comment,#project-grid, and the webring two-column block are untouched; the button is on the header row, not inside the grid.pnpm format:check,pnpm check, andpnpm buildall pass.