STYLE.md ·
How Pennant works. Every rule, written down.
Community sports clubs, as a website. It has four pieces:
- A registration finder. Add each player's birth year and it finds their age group and fee for the season, adds the state body's levy, takes off a sibling discount, and, when a family says it gets Family Tax Benefit, takes off the NSW Active and Creative Kids voucher for each child in its age range. Kit packs are optional.
- Fixtures and a ladder. Rounds as buttons, each round's games with scores or times, your own team marked with Win, Loss or Draw, and a ladder that's worked out from the results every time, so it's never out of date.
- A volunteer roster. Jobs down the side, match days across the top, dots for the slots that are filled, and a button on each one to put your name down.
- A return-to-play guide. Enter the day of a concussion and the first day without symptoms, and it lays out the steps and the earliest dates for contact training and games, as the 2024 national guidelines set them.
The type is Anton, Hind and Share Tech Mono, on clubhouse white with navy ink, one club green and gold for fills. A pennant is the mark.
Proud · welcoming · organised
Best for
- Community sports clubs of every code. It's written to the NSW Active and Creative Kids voucher rules, Working With Children Checks and the 2024 concussion guidelines (see "Clubs: what we build in").
- Anyone who runs seasons, teams and volunteers:
- netball and basketball clubs (Harbour: NetSetGo to seniors, three points a win, two a draw, one a loss)
- surf life saving clubs (Seabreeze: Nippers by age group, a water safety roster for parents)
- cricket, hockey, rugby, Aussie rules, swimming and athletics clubs, dance schools and scout groups
- Audiences: parents working out what a season costs for two kids, players checking the ladder on a Sunday night, and volunteers who'd rather pick a slot than be asked at the canteen.
Less suited to: a professional team's ticketing, a gym (Marquee), or a tournament with seeded draws.
Personality and voice
Proud and welcoming, the club secretary who knows every family's name.
- Headlines: "Everyone plays, every week." · "U12 Division 2, round by round." · "If in doubt, sit them out."
- Buttons: "Register for 2027" · "Add a player" · "Take a slot"
- Microcopy:
- "Player 2: MiniRoos U6–U11 · $185 · Sibling discount, 10% · −$18.50"
- "Worked out from the results: 3 points a win, 1 a draw; then difference, then goals for."
- "Earliest game: Saturday 7 Nov"
- Words to avoid: "fees from" without the levies, "compulsory volunteering or a $200 fine", "tough it out" about knocks to the head, and anything that makes a child's result the point.
Colour
| Token | Match day (light) | Night game (dark) | Role |
|---|---|---|---|
--paper |
#f4f4ef |
#0d1220 |
Page |
--card |
#ffffff |
#151b2b |
Registration, fixtures, roster, return to play |
--well |
#e8e8e1 |
#111726 |
Alternate sections, players, games |
--line |
#d6d6cc |
#283146 |
Hairlines |
--ink / --ink-2 |
#0f1a2e / #343d4f |
#eef1f6 / #cdd3de |
Text |
--muted |
#586174 |
#9ba3b3 |
Meta, ladder headings |
--green |
#0f6b3a |
#7fd6a0 |
The one accent: buttons, links, your team, the chosen round, your slots |
--gold |
#f2c12e |
#f2c12e |
Fills only: the hoops under the lit words, filled roster dots, the fee panel; text on it is ink |
--gold-ink |
#7a5a00 |
#f2c12e |
Gold as text |
--ok |
#0f6b3a |
#7fd6a0 |
Wins, discounts and vouchers |
--alert |
#b3261e |
#ff9a90 |
Invalid fields, losses, ages without a team |
Measured contrast (WCAG).
- Match day:
- ink on paper 15.8:1
- muted on paper 5.6:1 (5.1:1 on well)
- green on paper 6.0:1 (5.4:1 on well, 5.6:1 on its soft fill, 6.6:1 on card), white on green 6.6:1
- ink on gold 10.3:1; gold text 5.8:1 (5.6:1 on its soft fill)
- green on the gold hoop 3.9:1 (headline size only, where AA asks 3:1)
- alert 5.9:1
- Night game:
- ink 16.5:1
- muted 7.4:1 (6.8:1 on card)
- green 10.7:1, text on green 9.2:1, green on its soft fill 8.9:1
- gold 11.1:1
- the hoop dims to 34% so the lit words keep 6.6:1 on it
- Closing card: text 15.4:1, gold em 10.3:1, ink on its gold button 10.3:1.
- Example dials: magenta (Harbour), surf red (Seabreeze) and club blue (Lyrebirds) all meet AA, light and dark, and so does each closing card.
Typography
- Display: Anton, one weight, uppercase. Headlines, totals, scores, card titles.
- Body: Hind, 400–700. Reading, forms, buttons.
- Mono: Share Tech Mono. Fees, times, dates, the roster.
| Token | Size | Use |
|---|---|---|
--fs-h1 |
clamp(52px, 7.4vw, 116px) | Page headline, uppercase |
--fs-h2 |
clamp(38px, 4.6vw, 66px) | Section headline, uppercase |
--fs-h3 |
22px | Card titles |
--fs-lead |
clamp(17.5px, 1.35vw, 20.5px) | Intro paragraphs |
--fs-body |
17px | Body |
The signature move: the lit words turn club green and gold hoops run across behind them, a thick one and a thin one, like a jersey.
Layout
- Frame: a 1200px wrap with a
max(20px, 4vw)gutter. An ink top line with a gold label for the season; a sticky header with the pennant; pitch markings (the centre circle and halfway line) behind the hero. - Hero: copy on the left; the registration finder on the right.
- Then: fixtures beside the ladder; the volunteer roster; return to play beside the club's safety notes; questions; and a navy closing card with gold hoops and a pennant that flutters.
Shape
- Sporty:
--r-s4px,--r-m8px,--r-l14px. - Pennants: drawn in CSS, a triangle in club colours with a gold stripe, for the mark, the tag, the page heads and the closing card.
- Pitch lines: a ring and a halfway line behind the hero and page heads.
Motion language
- Registration: the total slides in when anything changes.
- Fixtures: your team's games get their result badge; the ladder re-sorts.
- Elsewhere: the hoops run across under the headline, the closing card's pennant flutters, sections reveal with a 14px rise over 650ms, and the phone menu drops in.
- Motion switch in the footer (
[data-motion-toggle],html.calm, remembered assite-motion, with the default fromprefers-reduced-motion). Calm stops the hoops, the flutter and the slides. - Night game switch (
[data-theme-toggle]), remembered assite-theme;theme-colorfollows.
Imagery and illustration
Your own club's photos, with families' permission recorded (the industry template asks for it, unticked by default): teams, volunteers, presentation day. The template draws pennants and pitch lines so nothing is borrowed. No league logos you don't have rights to, and no invented sponsor badges.
Signature components
- Registration finder:
.rego[data-rego]containingscript[data-rego-data](season;groupsas label, minimum age, maximum age, fee and note;levies;siblingPct;voucherwithamount,max,minAge,maxAge,label;start;youngest,oldest,max;playerandplayers),[data-players](rows ofselect[data-born]and[data-remove]),[data-add-player],input[data-voucher],select[data-vouchers],input[data-kit](data-price,data-label),[data-rego-lines],[data-rego-total]and[data-rego-per]. - Fixtures and ladder:
.fixtures[data-fixtures]containingscript[data-fix-data](teams,mine,pointsas win, draw and loss,weekdayfor match day, androundswithr,dayas a week offset andgamesas home, away, home score, away score and a note for unplayed games),[data-rounds],[data-round-head],[data-games]and[data-ladder]. - Volunteer roster:
.roster[data-roster]containingscript[data-roster-data](daysas week offsets,weekday,jobsas job, slots and note,filledas day, job and count),[data-roster-grid],[data-roster-count]and[data-roster-msg]. - Return to play:
.rtp[data-rtp]containingscript[data-rtp-data](freeDays,minDays),input[data-injury],input[data-symptom-free],input[data-still],[data-rtp-head]and[data-rtp-steps]. - Supporting pieces:
.plan-pair,.card,.facts(--ncolumns, or.stack),.notice,.side-box,.checks,.faq,.close-card(--close-bg,--close-em,--close-flag).
Multi-page kit
- Phone menu:
.menu-btn[aria-controls]opens.site-menu. Escape, an outside click or choosing a link closes it, and Tab stays inside while it's open. - Current page:
aria-current="page", shown as a green-soft pill. - Inner pages:
.page-head(a pitch ring and a flying pennant),.crumbs, a.tagand a smaller.h1. - Fields:
.field,.fields,.field-wide,fieldset.field-set,.check,.form-card,[aria-invalid="true"];form[data-template]. - Tiles, segmented control, gate, slider, switch, tables:
.choices,.seg,[data-gate],input.range,.switch[role=switch],.table. - Events:
rego(players, total, voucher),round(round, leader, minePos),roster(slots),rtp(injury, game). - Helper:
Pennant.refresh(root), andPennant.last, the latest detail of each event, for scripts that load afterwards.
Clubs: what we build in
We checked these for NSW clubs in October 2026:
- Active and Creative Kids. $50 a voucher, two a year (both can be used together for $100), for NSW children aged 4.5 to 18 whose parent or carer gets Family Tax Benefit. They're used with registered providers, can't be split between providers or turned into cash or credit, and 2026's run until 31 December 2026 and 14 July 2027. The registration finder takes them off per eligible child, and never below zero.
- One price for the season. Fees, the state body's levy and insurance, and any kit are added up into one total, with discounts and vouchers shown as their own lines.
- Concussion. The 2024 Australian Concussion Guidelines for Youth and Community Sport: if in doubt, sit them out; 24 to 48 hours of relative rest; school or work before sport; 14 days symptom-free before contact training; and no return to competitive contact sport for at least 21 days. The guide counts those dates, says it isn't medical advice, and the template names a concussion officer.
- Child safety. Coaches and team managers hold Working With Children Checks, verified with the Office of the Children's Guardian; the NSW Child Safe Standards are named; and there's one person to raise a concern with.
- Privacy. Medical and emergency details go to a secure registration portal, not a web form; photo consent is optional and unticked.
- No card surcharges. Surcharging on eftpos, Mastercard and Visa ended on 1 October 2026.
These notes are design guidance, not legal or medical advice.
Do and don't
- Do show the whole season's cost, levies and vouchers included.
- Do work the ladder out from results, not by hand.
- Do make the concussion message impossible to miss.
- Don't fine families for missed volunteer slots.
- Don't collect children's medical details in a plain web form.
- Don't put text on gold in anything but ink.
Accessibility
- AA contrast throughout (measured above), a skip link and a 3px focus ring.
- Registration: each player is a labelled birth-year select with a remove button that names what it removes; focus moves sensibly when players are added or removed; the total is announced.
- Fixtures: rounds are buttons with a pressed state; each game's teams, score and result are text; the ladder is a real table with headers and abbreviations explained.
- Roster: every slot is a button that says the job, the day, how many are filled and whether you're on it.
- Return to play: labelled date fields; the earliest game date and each step's date are text, announced as they change.
- Forms: labelled fields, errors listed in an alert, linked to and marked on each field.
- Testing: responsive to 360px, and tested with motion on and off, in Match day and Night game.
How to make it yours
| Dial | Range |
|---|---|
| Accent | Club green (default), magenta (Harbour), surf red (Seabreeze), club blue (Lyrebirds). Set --green, --green-2, --green-soft, --focus (plus --on-green at night), --close-bg, --close-em and --close-flag. |
| Registration | Your age groups, fees, levies, sibling discount, kit and your state's voucher. |
| Fixtures | Your competition's teams, rounds, results and points system. |
| Roster | Your jobs, slots and match days. |
| Return to play | Your sport's return-to-play policy, if it's stricter. |
| Not negotiable | The whole season's price, the concussion message, Working With Children Checks, privacy for children's details, no card surcharges, and the Motion switch. |



