feat: add Gear page CTA linking to /jersey-public (#245) #248

Merged
forgejo_admin merged 1 commit from 245-gear-jersey-public-link into main 2026-04-11 20:48:12 +00:00
Contributor

Summary

Adds a prominent "Order Your Jersey" CTA on the Gear page linking to /jersey-public so players browsing the site can discover the jersey intake flow without needing Marcus to DM the URL. Part of T7 of the System B production rollout.

Closes #245

Changes

  • src/routes/(public)/gear/+page.svelte — added an "Order CTA" section between the hero and the gear gallery. Uses existing btn btn-primary btn-lg classes (same as landing, about, staff, teams pages) for visual consistency. Plain <a href="/jersey-public"> — no JS interception. Sits above the fold on mobile immediately under the Kings/Queens toggle, so it's the first actionable element after a user picks a program.

Landing page CTA: intentionally omitted. The landing hero already has two primary CTAs (Register Your Player + Learn More) and a bottom Contact Us CTA. The Quick Links grid uses grid grid-3 with no grid-4 utility available, so adding a fourth card would require inventing layout. Adding a third hero button dilutes the existing "register" call-to-action, which is the higher-value top-of-funnel action. The user story explicitly names the Gear page as the discovery surface ("As a player visiting the Gear page"), and the ticket allows opting out of the landing CTA with justification. Gear page is the canonical discovery path; landing stays focused on registration.

Test Plan

  • npm run check — 0 errors (pre-existing warnings unchanged)
  • npm run build — clean
  • Verification greps:
    • grep -n "jersey-public" src/routes/(public)/gear/+page.svelte → 1 match (line 29)
    • grep -n "jersey-public" src/routes/(public)/+page.svelte → 0 matches (intentional, see above)
    • No new Tailwind/@apply in gear page
    • git diff main -- src/routes/(app)/ → empty (T1 untouched)
  • Manual: visit /gear, confirm "Order Your Jersey" button renders under the Kings/Queens toggle
  • Manual: click the CTA as an unauthenticated user and confirm it bounces through /signin via the existing (app)/+layout.svelte guard
  • Manual: check mobile tap target (375px) — btn-lg is well over 44px in the existing CSS

Review Checklist

  • CTA reuses existing btn btn-primary btn-lg classes — no visual invention
  • No Tailwind introduced
  • Plain <a href> — no JS interception, no goto()
  • No analytics wiring
  • Gear page existing content unchanged — only the new CTA section added
  • No modifications to src/routes/(app)/ (T1 hands off)
  • No modifications to nav/layout files
  • No modifications to src/app.css
  • Depends on: westside-landing#243 (T1 /jersey-public route — already in main)
  • Story: WS-S31 — admin public jersey intake link
  • Arch: arch-jersey-intake
  • Board item: #952 (T7 of System B rollout)
  • Runs in parallel with T3 (basketball-api POST endpoint, #948)
## Summary Adds a prominent "Order Your Jersey" CTA on the Gear page linking to `/jersey-public` so players browsing the site can discover the jersey intake flow without needing Marcus to DM the URL. Part of T7 of the System B production rollout. Closes #245 ## Changes - `src/routes/(public)/gear/+page.svelte` — added an "Order CTA" section between the hero and the gear gallery. Uses existing `btn btn-primary btn-lg` classes (same as landing, about, staff, teams pages) for visual consistency. Plain `<a href="/jersey-public">` — no JS interception. Sits above the fold on mobile immediately under the Kings/Queens toggle, so it's the first actionable element after a user picks a program. **Landing page CTA: intentionally omitted.** The landing hero already has two primary CTAs (`Register Your Player` + `Learn More`) and a bottom `Contact Us` CTA. The Quick Links grid uses `grid grid-3` with no `grid-4` utility available, so adding a fourth card would require inventing layout. Adding a third hero button dilutes the existing "register" call-to-action, which is the higher-value top-of-funnel action. The user story explicitly names the Gear page as the discovery surface ("As a player visiting the Gear page"), and the ticket allows opting out of the landing CTA with justification. Gear page is the canonical discovery path; landing stays focused on registration. ## Test Plan - [x] `npm run check` — 0 errors (pre-existing warnings unchanged) - [x] `npm run build` — clean - [x] Verification greps: - `grep -n "jersey-public" src/routes/(public)/gear/+page.svelte` → 1 match (line 29) - `grep -n "jersey-public" src/routes/(public)/+page.svelte` → 0 matches (intentional, see above) - No new Tailwind/`@apply` in gear page - `git diff main -- src/routes/(app)/` → empty (T1 untouched) - [ ] Manual: visit `/gear`, confirm "Order Your Jersey" button renders under the Kings/Queens toggle - [ ] Manual: click the CTA as an unauthenticated user and confirm it bounces through `/signin` via the existing `(app)/+layout.svelte` guard - [ ] Manual: check mobile tap target (375px) — `btn-lg` is well over 44px in the existing CSS ## Review Checklist - [x] CTA reuses existing `btn btn-primary btn-lg` classes — no visual invention - [x] No Tailwind introduced - [x] Plain `<a href>` — no JS interception, no `goto()` - [x] No analytics wiring - [x] Gear page existing content unchanged — only the new CTA section added - [x] No modifications to `src/routes/(app)/` (T1 hands off) - [x] No modifications to nav/layout files - [x] No modifications to `src/app.css` ## Related Notes - Depends on: `westside-landing#243` (T1 `/jersey-public` route — already in main) - Story: `WS-S31` — admin public jersey intake link - Arch: `arch-jersey-intake` - Board item: #952 (T7 of System B rollout) - Runs in parallel with T3 (basketball-api POST endpoint, #948)
feat: add Gear page CTA linking to /jersey-public (#245)
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
66fdbb90b9
Closes #245

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author
Contributor

PR #248 Review

DOMAIN REVIEW

Stack: SvelteKit / TypeScript / pure CSS (no Tailwind per feedback_no_tailwind).

Diff: 1 file, +7/-0, purely additive. New <section class="section"> block inserted between the hero section (closing </section> at line 25) and the Gear Gallery comment at line 26 in src/routes/(public)/gear/+page.svelte. No existing content touched.

Link correctness: Plain <a href="/jersey-public" class="btn btn-primary btn-lg">Order Your Jersey</a>. No JS interception, no SvelteKit goto(), no preventDefault. The unauthenticated user will hit the (app) layout guard and bounce through /signin as designed.

CSS class verification: Verified in src/app.css:

  • .btn — line 183
  • .btn-primary — line 203
  • .btn-lg — line 234
  • .container — line 123
  • .section — line 765

All four classes referenced in the diff exist. No T1-style phantom-class mistake. No new CSS, no @apply, no Tailwind utilities.

Scope hygiene:

  • src/routes/(app)/jersey-public/* — untouched (T1 territory preserved)
  • src/routes/(app)/+layout.svelte — untouched (auth guard preserved)
  • src/app.css — untouched
  • Nav/layout files — untouched

Accessibility / mobile: btn-lg is the same class used by hero CTAs on landing/about/staff/teams, so the 44px tap target is inherited from the existing design system. Centered via inline style="text-align: center;" which is acceptable for a one-off CTA container (not worth inventing a utility class for a single usage).

BLOCKERS

None.

NITS

  • Inline style="text-align: center;" is pragmatic but slightly inconsistent with the pure-CSS-vars convention. Non-blocking under the hot-fix profile — a single declarative style on a container is not worth a round trip.
  • Manual test checkboxes in Test Plan are unchecked. Expected for pre-merge; flagging so Lucas knows to verify /gear renders the CTA and the unauthenticated bounce works in prod.

SOP COMPLIANCE

  • Branch named after issue (245-gear-jersey-public-link)
  • PR body uses full template (Summary / Changes / Test Plan / Review Checklist / Related Notes)
  • Closes #245 present
  • No-landing-CTA decision documented with reasoning (register dilution + grid-4 absence + user story surface)
  • References story WS-S31, arch arch-jersey-intake, board item #952, parallel T3 #948
  • No Tailwind introduced
  • No secrets, no scope creep, no file churn
  • Reuses existing btn btn-primary btn-lg idiom

PROCESS OBSERVATIONS

Textbook T7 hot-fix execution. Minimal diff, correct classes verified against the stylesheet (unlike the T1 phantom-class incident this PR explicitly guards against), and the PR body pre-answers the obvious "why no landing CTA" question with sound reasoning tied to the user story. Change failure risk: near-zero — 7 additive lines touching zero existing behavior. Deployment frequency: positive contribution, unblocks the T7 checkbox on System B rollout. No documentation gap.

VERDICT: APPROVED

## PR #248 Review ### DOMAIN REVIEW **Stack:** SvelteKit / TypeScript / pure CSS (no Tailwind per `feedback_no_tailwind`). **Diff:** 1 file, +7/-0, purely additive. New `<section class="section">` block inserted between the hero section (closing `</section>` at line 25) and the Gear Gallery comment at line 26 in `src/routes/(public)/gear/+page.svelte`. No existing content touched. **Link correctness:** Plain `<a href="/jersey-public" class="btn btn-primary btn-lg">Order Your Jersey</a>`. No JS interception, no SvelteKit `goto()`, no preventDefault. The unauthenticated user will hit the `(app)` layout guard and bounce through `/signin` as designed. **CSS class verification:** Verified in `src/app.css`: - `.btn` — line 183 - `.btn-primary` — line 203 - `.btn-lg` — line 234 - `.container` — line 123 - `.section` — line 765 All four classes referenced in the diff exist. No T1-style phantom-class mistake. No new CSS, no `@apply`, no Tailwind utilities. **Scope hygiene:** - `src/routes/(app)/jersey-public/*` — untouched (T1 territory preserved) - `src/routes/(app)/+layout.svelte` — untouched (auth guard preserved) - `src/app.css` — untouched - Nav/layout files — untouched **Accessibility / mobile:** `btn-lg` is the same class used by hero CTAs on landing/about/staff/teams, so the 44px tap target is inherited from the existing design system. Centered via inline `style="text-align: center;"` which is acceptable for a one-off CTA container (not worth inventing a utility class for a single usage). ### BLOCKERS None. ### NITS - Inline `style="text-align: center;"` is pragmatic but slightly inconsistent with the pure-CSS-vars convention. Non-blocking under the hot-fix profile — a single declarative style on a container is not worth a round trip. - Manual test checkboxes in Test Plan are unchecked. Expected for pre-merge; flagging so Lucas knows to verify `/gear` renders the CTA and the unauthenticated bounce works in prod. ### SOP COMPLIANCE - [x] Branch named after issue (`245-gear-jersey-public-link`) - [x] PR body uses full template (Summary / Changes / Test Plan / Review Checklist / Related Notes) - [x] `Closes #245` present - [x] No-landing-CTA decision documented with reasoning (register dilution + grid-4 absence + user story surface) - [x] References story `WS-S31`, arch `arch-jersey-intake`, board item #952, parallel T3 #948 - [x] No Tailwind introduced - [x] No secrets, no scope creep, no file churn - [x] Reuses existing `btn btn-primary btn-lg` idiom ### PROCESS OBSERVATIONS Textbook T7 hot-fix execution. Minimal diff, correct classes verified against the stylesheet (unlike the T1 phantom-class incident this PR explicitly guards against), and the PR body pre-answers the obvious "why no landing CTA" question with sound reasoning tied to the user story. Change failure risk: near-zero — 7 additive lines touching zero existing behavior. Deployment frequency: positive contribution, unblocks the T7 checkbox on System B rollout. No documentation gap. ### VERDICT: APPROVED
forgejo_admin deleted branch 245-gear-jersey-public-link 2026-04-11 20:48:12 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/westside-app!248
No description provided.