jersey-public.html — public intake prototype (System B) #57

Closed
opened 2026-04-10 21:12:23 +00:00 by forgejo_admin · 2 comments
Contributor

Type

Feature

Lineage

Standalone — discovered 2026-04-10 while scoping Marcus's jersey order outreach. Coexists with jersey.html (System A, token-gated roster flow). This is System B — public intake.

Repo

forgejo_admin/westside-playground

User Story

As Marcus
I want a long-standing public jersey order link I can share with any player (known or new)
So that they can submit their own sizes, number preferences, and tier without me collecting details manually

Context

Marcus currently collects jersey orders manually (text/GroupMe → spreadsheet). A token-gated flow already exists at jersey.html for known roster players — but that requires Marcus to generate a per-player link each time. For outreach to players who may not yet be in the roster (or for casual "send this to anyone" sharing), we need a second, public intake page.

Key decisions locked during scoping:

  • Two separate systems — System A (token, existing) and System B (public, new). No conflict, no merge. jersey.html is not touched.
  • Shooter shirt size is not collected. Per Lucas: shooter shirt size always matches jersey size.
  • Two tiers only: $90 Reversible and $130 Reversible + Shooter Shirt. (The existing prototype's "$130 Jersey + Warmup" is System A's product definition and stays there.)
  • Playground-first. No backend wiring, no Stripe, no submission endpoint in this ticket. Design approval on Lucas's phone is the exit gate.
  • Mirror existing card/style classes from jersey.html for visual consistency. Use shared/style.css. No Tailwind.
  • Kings/Queens image swap must be built from scratch. Neither jersey.html (hardcoded Queens) nor gear.html (no K/Q toggle) has an existing pattern to reuse. Implement with vanilla JS: a radio or toggle that swaps the two <img> src attributes between the Kings and Queens filenames listed under File Targets.

File Targets

Files to create:

  • jersey-public.html — the new public intake page. Mirrors card styles from jersey.html (reuse .jersey-option, .jersey-option-body, .jersey-form-group, etc.) but replaces token-gated identity with self-identification form fields and adds a K/Q image toggle.

Image sources (verified HTTP 200):

  • https://minio-api.tail5b443a.ts.net/assets/westside/jerseys/kings-home.jpeg
  • https://minio-api.tail5b443a.ts.net/assets/westside/jerseys/kings-away-new.jpeg
  • https://minio-api.tail5b443a.ts.net/assets/westside/jerseys/queens-home.jpeg
  • https://minio-api.tail5b443a.ts.net/assets/westside/jerseys/queens-away-new.jpeg

Files the agent should NOT touch:

  • jersey.html — System A, untouched. Different user story, different flow.
  • checkout.html, checkout-success.html, jersey-success.html — wired to System A.
  • gear.html — separate ticket for landing link.
  • shared/style.css, shared/app.js — extend only if strictly required; reuse existing classes first. If new styles are genuinely needed, scope them to a .jersey-public-* prefix inside a <style> block in jersey-public.html to avoid cross-page leakage.

Acceptance Criteria

  • AC-1 When I open jersey-public.html on mobile and desktop, I see a hero, two jersey tier cards, and the full intake form
  • AC-2 When I view the form, it contains exactly these fields: Player Name (text), Team (select), K/Q (Kings/Queens radio or select), Preferred Number #1/#2/#3 (three number inputs, labeled by priority, all optional, accepting 0, 00, or 1–99), Jersey Top Size (YS–AXL select), Jersey Short Size (YS–AXL select), Tier (radio: $90 Reversible or $130 Reversible + Shooter Shirt)
  • AC-3 When I select Kings, both card images use the kings-home.jpeg and kings-away-new.jpeg sources. When I select Queens, both card images use queens-home.jpeg and queens-away-new.jpeg. The swap is implemented in vanilla JS — there is no existing K/Q pattern to mirror; this is built from scratch.
  • AC-4 When I submit with any required field missing (Player Name, Team, K/Q, top size, short size, tier), the form blocks submission and shows inline validation errors. Preferred numbers stay optional.
  • AC-5 When jersey.html is opened, it is byte-identical to its state on main before this ticket (git diff main -- jersey.html returns empty)
  • AC-6 Jersey images load from the MinIO URLs listed in File Targets (no local asset fallbacks for jersey imagery)
  • AC-7 Page passes mobile validation on Lucas's phone via Tailscale preview (exit gate)

Test Expectations

  • Manual: open jersey-public.html in Chrome desktop, verify all fields + both card images render
  • Manual: open on iPhone via Tailscale preview, verify mobile layout + tap targets
  • Manual: git diff main -- jersey.html returns empty (AC-5 check)
  • Manual: submit with each required field missing in turn → inline validation blocks each time
  • Manual: submit with preferred numbers all blank → form allows submission (optional)
  • Manual: toggle Kings → both card images swap to kings-; toggle Queens → both swap to queens-
  • Run command: visual inspection, no automated tests (playground convention per feedback_playground_first.md)

Constraints

  • Match existing card/form class names from jersey.html — do not invent new visual patterns
  • No Tailwind (feedback_no_tailwind.md) — pure CSS via shared/style.css + optional page-scoped <style> block
  • No framework, no build step — vanilla HTML/CSS/JS only
  • No backend calls — this is playground, all data is form-only
  • Images must come from the MinIO URLs in File Targets, not local assets
  • Mobile-first — phone is the primary target device

Checklist

  • PR opened against westside-playground main
  • Tailscale preview URL posted in PR for Lucas
  • Zero changes to jersey.html (verified via git diff main)
  • No unrelated changes (no refactors, no style sweeps)
  • westside-basketball — project this affects
  • story:WS-S31 — user story this implements (admin public jersey intake link)
  • arch-generic-checkout — future backend target (out of scope here)
  • feedback_playground_first.md — playground-gate philosophy
  • feedback_svelte_is_html.md — .svelte files are HTML, promotion is copy-paste
  • Follow-up (not blocking): create arch-jersey-intake note documenting System A + System B coexistence before any backend/API work lands. Reviewer flagged this as required-before-backend-follow-up but not a gate for this playground ticket.
### Type Feature ### Lineage Standalone — discovered 2026-04-10 while scoping Marcus's jersey order outreach. Coexists with `jersey.html` (System A, token-gated roster flow). This is System B — public intake. ### Repo `forgejo_admin/westside-playground` ### User Story As Marcus I want a long-standing public jersey order link I can share with any player (known or new) So that they can submit their own sizes, number preferences, and tier without me collecting details manually ### Context Marcus currently collects jersey orders manually (text/GroupMe → spreadsheet). A token-gated flow already exists at `jersey.html` for known roster players — but that requires Marcus to generate a per-player link each time. For outreach to players who may not yet be in the roster (or for casual "send this to anyone" sharing), we need a second, public intake page. Key decisions locked during scoping: - Two separate systems — System A (token, existing) and System B (public, new). No conflict, no merge. `jersey.html` is not touched. - Shooter shirt size is **not** collected. Per Lucas: shooter shirt size always matches jersey size. - Two tiers only: `$90 Reversible` and `$130 Reversible + Shooter Shirt`. (The existing prototype's "$130 Jersey + Warmup" is System A's product definition and stays there.) - Playground-first. No backend wiring, no Stripe, no submission endpoint in this ticket. Design approval on Lucas's phone is the exit gate. - Mirror existing card/style classes from `jersey.html` for visual consistency. Use `shared/style.css`. No Tailwind. - **Kings/Queens image swap must be built from scratch.** Neither `jersey.html` (hardcoded Queens) nor `gear.html` (no K/Q toggle) has an existing pattern to reuse. Implement with vanilla JS: a radio or toggle that swaps the two `<img>` `src` attributes between the Kings and Queens filenames listed under File Targets. ### File Targets Files to create: - `jersey-public.html` — the new public intake page. Mirrors card *styles* from `jersey.html` (reuse `.jersey-option`, `.jersey-option-body`, `.jersey-form-group`, etc.) but replaces token-gated identity with self-identification form fields and adds a K/Q image toggle. Image sources (verified HTTP 200): - `https://minio-api.tail5b443a.ts.net/assets/westside/jerseys/kings-home.jpeg` - `https://minio-api.tail5b443a.ts.net/assets/westside/jerseys/kings-away-new.jpeg` - `https://minio-api.tail5b443a.ts.net/assets/westside/jerseys/queens-home.jpeg` - `https://minio-api.tail5b443a.ts.net/assets/westside/jerseys/queens-away-new.jpeg` Files the agent should NOT touch: - `jersey.html` — System A, untouched. Different user story, different flow. - `checkout.html`, `checkout-success.html`, `jersey-success.html` — wired to System A. - `gear.html` — separate ticket for landing link. - `shared/style.css`, `shared/app.js` — extend only if strictly required; reuse existing classes first. If new styles are genuinely needed, scope them to a `.jersey-public-*` prefix inside a `<style>` block in `jersey-public.html` to avoid cross-page leakage. ### Acceptance Criteria - [ ] **AC-1** When I open `jersey-public.html` on mobile and desktop, I see a hero, two jersey tier cards, and the full intake form - [ ] **AC-2** When I view the form, it contains exactly these fields: Player Name (text), Team (select), K/Q (Kings/Queens radio or select), Preferred Number #1/#2/#3 (three number inputs, labeled by priority, all optional, accepting 0, 00, or 1–99), Jersey Top Size (YS–AXL select), Jersey Short Size (YS–AXL select), Tier (radio: `$90 Reversible` or `$130 Reversible + Shooter Shirt`) - [ ] **AC-3** When I select Kings, both card images use the `kings-home.jpeg` and `kings-away-new.jpeg` sources. When I select Queens, both card images use `queens-home.jpeg` and `queens-away-new.jpeg`. The swap is implemented in vanilla JS — there is no existing K/Q pattern to mirror; this is built from scratch. - [ ] **AC-4** When I submit with any required field missing (Player Name, Team, K/Q, top size, short size, tier), the form blocks submission and shows inline validation errors. Preferred numbers stay optional. - [ ] **AC-5** When `jersey.html` is opened, it is byte-identical to its state on `main` before this ticket (`git diff main -- jersey.html` returns empty) - [ ] **AC-6** Jersey images load from the MinIO URLs listed in File Targets (no local asset fallbacks for jersey imagery) - [ ] **AC-7** Page passes mobile validation on Lucas's phone via Tailscale preview (exit gate) ### Test Expectations - [ ] Manual: open `jersey-public.html` in Chrome desktop, verify all fields + both card images render - [ ] Manual: open on iPhone via Tailscale preview, verify mobile layout + tap targets - [ ] Manual: `git diff main -- jersey.html` returns empty (AC-5 check) - [ ] Manual: submit with each required field missing in turn → inline validation blocks each time - [ ] Manual: submit with preferred numbers all blank → form allows submission (optional) - [ ] Manual: toggle Kings → both card images swap to kings-*; toggle Queens → both swap to queens-* - Run command: visual inspection, no automated tests (playground convention per `feedback_playground_first.md`) ### Constraints - Match existing card/form class names from `jersey.html` — do not invent new visual patterns - No Tailwind (`feedback_no_tailwind.md`) — pure CSS via `shared/style.css` + optional page-scoped `<style>` block - No framework, no build step — vanilla HTML/CSS/JS only - No backend calls — this is playground, all data is form-only - Images must come from the MinIO URLs in File Targets, not local assets - Mobile-first — phone is the primary target device ### Checklist - [ ] PR opened against `westside-playground` main - [ ] Tailscale preview URL posted in PR for Lucas - [ ] Zero changes to `jersey.html` (verified via `git diff main`) - [ ] No unrelated changes (no refactors, no style sweeps) ### Related - `westside-basketball` — project this affects - `story:WS-S31` — user story this implements (admin public jersey intake link) - `arch-generic-checkout` — future backend target (out of scope here) - `feedback_playground_first.md` — playground-gate philosophy - `feedback_svelte_is_html.md` — .svelte files are HTML, promotion is copy-paste - **Follow-up (not blocking):** create `arch-jersey-intake` note documenting System A + System B coexistence before any backend/API work lands. Reviewer flagged this as required-before-backend-follow-up but not a gate for this playground ticket.
Author
Contributor

Scope Review: NEEDS_REFINEMENT

Review note: review-942-2026-04-10

Scope is fundamentally sound — template complete, traceability verified (WS-S31 found on project-westside-basketball), file targets checked, MinIO images confirmed live, no blocking dependencies, and the System A/B split is cleanly enforced by the "do not touch" list + byte-identical AC. Two small fixes before dispatch:

  • [BODY] Fix AC-3: gear.html does not contain a Kings/Queens image swap pattern (verified — 138 lines, no K/Q toggle). Drop "(same pattern as gear.html)" and say explicitly that the K/Q image swap is to be built from scratch with vanilla JS, swapping between kings-home.jpeg/kings-away-new.jpeg and queens-home.jpeg/queens-away-new.jpeg from the MinIO jerseys bucket.
  • [SCOPE] Create architecture note arch-jersey-intake documenting System A (token-gated, jersey.html, existing) + System B (public, jersey-public.html, this ticket) coexistence. Not blocking this playground ticket but required before any backend/API follow-up.

No decomposition needed — single-agent pass, ~15–25 min. Playground-gate exit via Lucas's phone/Tailscale is correct.

Reviewed by Dottie.

## Scope Review: NEEDS_REFINEMENT Review note: `review-942-2026-04-10` Scope is fundamentally sound — template complete, traceability verified (WS-S31 found on project-westside-basketball), file targets checked, MinIO images confirmed live, no blocking dependencies, and the System A/B split is cleanly enforced by the "do not touch" list + byte-identical AC. Two small fixes before dispatch: - **[BODY]** Fix AC-3: `gear.html` does not contain a Kings/Queens image swap pattern (verified — 138 lines, no K/Q toggle). Drop "(same pattern as gear.html)" and say explicitly that the K/Q image swap is to be built from scratch with vanilla JS, swapping between `kings-home.jpeg`/`kings-away-new.jpeg` and `queens-home.jpeg`/`queens-away-new.jpeg` from the MinIO jerseys bucket. - **[SCOPE]** Create architecture note `arch-jersey-intake` documenting System A (token-gated, `jersey.html`, existing) + System B (public, `jersey-public.html`, this ticket) coexistence. Not blocking this playground ticket but required before any backend/API follow-up. No decomposition needed — single-agent pass, ~15–25 min. Playground-gate exit via Lucas's phone/Tailscale is correct. Reviewed by Dottie.
Author
Contributor

Scope Re-Review: APPROVED

Review note: review-942-2026-04-10 (verdict section appended at top).

Both findings from the first pass are resolved:

  • [BODY] AC-3 gear.html reference removed — AC-3 now lists the four explicit jersey image filenames (kings-home.jpeg, kings-away-new.jpeg, queens-home.jpeg, queens-away-new.jpeg) and states the K/Q swap is built from scratch in vanilla JS. Context section adds a matching "no existing pattern to reuse" decision bullet. File Targets lists the four MinIO URLs.
  • [SCOPE] arch-jersey-intake follow-up — correctly noted in Related as non-blocking for this playground ticket; required before any backend/API jersey-intake work.

Regression check on AC-5 (byte-identical jersey.html), AC-2 (field enumeration), AC-7 (mobile/Tailscale exit gate), "do not touch" list, no-Tailwind constraint, two-tier spec, and shooter-shirt-size decision — all intact. No drift.

Ticket is ready to advance backlog → todo on board-westside-basketball.

## Scope Re-Review: APPROVED Review note: `review-942-2026-04-10` (verdict section appended at top). Both findings from the first pass are resolved: - **[BODY] AC-3 gear.html reference removed** — AC-3 now lists the four explicit jersey image filenames (`kings-home.jpeg`, `kings-away-new.jpeg`, `queens-home.jpeg`, `queens-away-new.jpeg`) and states the K/Q swap is built from scratch in vanilla JS. Context section adds a matching "no existing pattern to reuse" decision bullet. File Targets lists the four MinIO URLs. - **[SCOPE] arch-jersey-intake follow-up** — correctly noted in Related as non-blocking for this playground ticket; required before any backend/API jersey-intake work. Regression check on AC-5 (byte-identical jersey.html), AC-2 (field enumeration), AC-7 (mobile/Tailscale exit gate), "do not touch" list, no-Tailwind constraint, two-tier spec, and shooter-shirt-size decision — all intact. No drift. Ticket is ready to advance backlog → todo on `board-westside-basketball`.
Commenting is not possible because the repository is archived.
No labels
No milestone
No project
No assignees
1 participant
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-playground#57
No description provided.