Brand book v3.0 · July 2026 · master reference
How Gaffer looks, sounds, and moves. This book covers the identity, product UI, Season 26/27 kits, and match-day graphics. It stays in step with the product: when the code changes, the relevant rule here changes with it.
Gaffer lets managers build fantasy leagues around their own sport, rules, and prize structure. The league belongs to the group; Gaffer provides the competition and settlement rails.
One sentence, used everywhere: "Run the league your way. Set the rules, set the prize, and let the contract settle it."
A gaffer is the manager: picks the team, takes the blame, lifts the cup. The brand lives in the manager's world, the touchline, the team sheet, the flat cap. The cap is the signature; the expanded uppercase wordmark gives it authority at product scale.
The mark is the violet flat cap, refined July 2026 (v3.0). The lockup pairs it with an expanded Archivo Black wordmark and a flat violet full stop. In product, components/brand/Logo.js renders both <Wordmark /> and <Monogram /> so color and scale stay consistent.
The full lockup, the monogram (avatar, favicon, tight slots), and the lockup on light mode, where only the text flips to near-black. The cap stays violet on every background.
Logo.js already does this, don't rebuild it by hand.Logo.js sets it in Archivo 900, expanded to 125%; prose uses normal-title-case Gaffer.cap-480.png (UI), icon-*.png (PWA), og-default.png (social). The April silhouette-tile SVGs (mark*.svg, wordmark.svg) are retired, do not use them.Gaffer has two equal presentation modes: floodlit dark and paper-light. Both carry the same violet identity and the same semantic split: gold is money, electric green is live. Violet replaced green as identity because green was borrowed FPL clothing and locked us to football; mode changes the surface, never the meaning.
#0c0618#110a1e#1c1232#8b5cf6#7c3aed for contrast.#f59e0b#00ff87#f87171#f5f5f7Text uses the --ink-1 through --ink-5 scale: pale ink on dark, near-black through slate on light. Use the tokens, not hardcoded text or surface colors. Light mode is a designed paper system with flatter elevation and deeper violet—not a CSS inversion.
Fixture difficulty (never grey, every fixture is color-coded) and position colors, from lib/designTokens.js. These are data colors: they never leak into chrome or CTAs.
Per-league theming overrides five variables (--league-primary, -secondary, -bg, -bg-card, -text-accent) and nothing else. Money, live, and danger never re-theme. This is the entire mechanism that makes Gaffer sport-agnostic.
Five faces, five defined jobs, all self-hosted. Archivo carries the identity in two widths: expanded for the wordmark and poster headlines, condensed for numerals and codes. IBM Plex Mono handles stamps, labels, and data. Archivo Black is reserved for cover moments, Inter handles long-form reading and UI, and Oswald is used only for broadcast information on the pitch. Space Grotesk is retired.
font-stretch. Stats set tabular-nums..font-condensed). Never for UI chrome or headings.| Level | Size | Weight | Tracking |
|---|---|---|---|
| H1 | clamp(30 to 44px) | 800 | -0.02em |
| H2 | clamp(24 to 32px) | 800 | -0.015em |
| H3 | 20px | 700 | -0.01em |
| H4 | 16px | 700 | -0.005em |
| Body | 16px, 14px dense | 400 to 500 | 0 |
| Label | 11 to 12px | 700 | +0.1em, uppercase |
Dark matte surfaces do most of the work. Glass is reserved for navigation, drawers, and controls that visibly sit above content. Resting cards use one hairline border and a low shadow; sheen and texture belong only to prize and celebration surfaces. Radii: 20px cards, 14px inputs and buttons, 10px chips. Depth is semantic:
| Token | Meaning | Used by |
|---|---|---|
--elev-1 | Subtle lift | Chips, small buttons |
--elev-2 | Resting card | .card and friends |
--elev-3 | Hover, modal | Card hover, dialogs |
--elev-4 | Popover, drawer | Slide-up drawer, menus |
8 managers · GW12 · $240 pool
The resting card; hover it to see the lift (-2px, elev-3, brighter border). On touch devices the lift is disabled and press feedback is a 0.985 scale instead.
CSS only, GPU-composited, no JS animation libraries. Animate transform and opacity only, never width, height, position, or spacing. Entry animations play once on mount; the only loops are state loops: live pulse, urgency pulse, captain glow, skeleton shimmer. Everything collapses to instant under prefers-reduced-motion.
| Token / class | Value | Job |
|---|---|---|
--dur-fast | 150ms | Presses, toggles |
--dur-base | 240ms | Hover, most transitions |
--dur-slow | 400ms | Drawers, page entry |
--ease-out-soft | cubic-bezier(0.22, 1, 0.36, 1) | Default easing |
--ease-spring | cubic-bezier(0.34, 1.56, 0.64, 1) | Celebration moments |
.animate-fade-in-up / -fade-in / -scale-in | once, on mount | Page and modal entry |
.stagger-children + .stagger-item | 40ms per child | Lists |
.hover-lift | translateY(-2px) + shadow | Cards, buttons |
.skeleton | shimmer sweep | Loading surfaces |
.live-dot-breathe | 2s opacity pulse | Live indicators |
.card-urgent / .captain-pulse | slow glow pulse | Deadline pressure, captain |
.animate-shake | once | Rejected input |
Live demos of the shipped classes. Hover and press the card; replay the entries. Only transform and opacity ever animate; everything collapses under prefers-reduced-motion.
The shipped controls, rendered from the same specs as globals.css. Each view gets one clear primary action; secondary controls stay quiet.
Primary: violet with glow and hover sheen. Secondary: glass. Danger: red tint, destructive actions only. There is also a bare .btn-ghost for tertiary actions.
Form input with violet focus ring (click in), the Toggle switch, and the create-league Wizard progress dots: completed and active fill violet, the active step gets a glow ring.
Archivo tabular numerals. Gold only when the number is money; green only when it is live.
Glow states the meaning: green live, gold money, violet brand. The DeadlineCountdown pill turns gold and pulses inside the final hours.
These examples show the main product states at working size. The reference table maps the remaining components to their files.
Top: sticky .nav-surface navbar (rgba(8,3,18,0.92) + blur), active link underlined in violet, wallet chip with tabular numerals (never coerces a null balance to $0), notification bell. Bottom: mobile nav, five tabs, active tab gets a violet pip and icon. A 2px violet scroll-progress bar runs along the top of every page.
Captain is gold, vice is silver, and triple captain shows ×3. Fixture chips combine the FDR dot, venue, and opponent code; double gameweeks stack two fixtures, while blanks and TBDs are stated directly. Higher live totals strengthen the green ring without adding novelty labels. Chip banners use violet for wildcard, green for bench boost, and gold for triple captain.
A quiet list, not cards: metal rank colors for the podium (gold, silver, bronze), your row tinted violet with a left rule, live GW points in green, and a gold dashed payout line marking the prize cutoff. Chip usage shows as small WC / BB / TC tags; live rows carry a match progress bar with the breathing green dot.
SettlementBanner is amber and provisional. WinnerBanner moves from projected to sending to arrived, then links the receipt in plain English. League cards, wallet balance, and payout progress use gold only for the money itself.
Skeleton shimmer for every loading surface (never spinners on content), the EmptyState pattern (icon tile in violet tint, honest copy, one action), and the version toast that nudges stale tabs after a deploy. Modals enter with .animate-scale-in over a blurred black overlay; sheets slide up as .drawer; rejected inputs .animate-shake.
| Area | Components (files in components/) |
|---|---|
| Chrome | Navbar + BottomNav (layout/Navbar.js), Layout (scroll progress, ambient orbs, footer), VersionUpdateBanner, NetworkBadge, UserDropdown |
| Pitch | PitchView (layered turf, mowing stripes, floodlight blooms, SVG markings), PickCard, ClubCrest / NationCrest, InjuryBadge, BudgetTracker (flashes on change, ∞ in limitless), ChipPanel + on-pitch chip banners, PlayerListDrawer, PlayerActionSheet, PlayerStatsModal, PointsBreakdownTable |
| League | LeaguePreviewCard (premium card, status badges, prize banner, 3-stat grid), Leaderboard, RankBadge medals, GwHistoryCard, LeagueFixtures (GW navigator, live rows), MatchDetailContent, OwnershipTable, InviteShareCard / Modal, StorylineBanner, PresenceBar, RulesSheet |
| Money | SmartWalletChip, AccountSetup activation card, WalletWidget, DepositQrCode, SettlementBanner, WinnerBanner + VaultPayoutProgress + PrizeBurst, ReauthPill, SwapperOnrampButton |
| Forms | Wizard + WizardNav (sticky mobile bar), StepCompetition / Template / Duration / CustomRules / Rewards / Social, Toggle, NumberInput, FormField, PostCreateCelebration |
| Feedback | Skeleton family (Box/Text/Circle/Card/Row/Grid/Pitch), Spinner, EmptyState, ErrorState / ErrorMessage, Portal modals, drawers, NotificationBell + notification rows |
| Misc | DeadlineCountdown, AnimatedNumber, avatars (gradient discs + initials), NationalFlag / CompetitionFlag, RatingBadge, SocialProofChip, onboarding (WelcomeModal, Checklist, PracticeTour) |
For 26/27, on-pitch picks use an original dimensional shirt silhouette instead of a crest tile. Every garment uses the same controlled three-quarter angle; the pitch adds depth while Gaffer color and chrome own the surface.
All 15 selections are visible in one system: the starting XI on the field and four ordered substitutes below it. Price stays gold because it is money; selection state stays violet.
The cards are compact, rectangular, and optically aligned. Shirt, name, and fixture form one bounded object; no floating white labels, mismatched radii, or translucent green boxes.
The formation, card footprint, and information hierarchy are identical. Only the surface system changes: paper cards, mineral turf, dark violet markings, and flatter elevation.
Light mode is deliberately Gaffer: violet owns selection and field geometry, while green remains limited to live and points semantics.
The same 11-player formation holds its position after deadline. Price gives way to points emphasis, live players gain a restrained green signal, and benched points remain visible but intentionally quieter.
Layout does not jump between Pick Team and Live Points. Only the information hierarchy changes: points first, live state second, fixture context third.
Short-format contests use the same card and pitch grammar at a larger scale. This 1–2–1–1 example has five starters and no substitutes; seven- and nine-player modes use the same line-based reflow.
Density is a layout variable, not a redesign. Fewer players create more breathing room and larger shirts while the Gaffer header, field, status color, and card geometry remain unchanged.
Every club variant uses the same original three-quarter silhouette, asymmetric light model, and controlled 8-degree turn. Color combines with eight controlled pattern types: solid, contrast sleeves, stripes, pinstripes, hoops, sash, hem fade, and tonal diagonals.
The 20-team sheet uses the current 26/27 club list. Each row reduces the home identity to color and generic geometry on the same Gaffer garment. Keep these values synchronized with lib/teamColors.js.
Season 26/27 uses violet as the primary accent under cool stadium light. Gold returns to its single job: money. The Global 26 interaction patterns remain, but its champagne-and-navy treatment does not.
38 gameweeks. Weekly prizes. Rules chosen by the league manager.
/* Season 26/27 theme, paste-ready for globals.css.
Same 5-variable contract as every league theme. */
:root[data-theme='season2627'] {
--league-primary: #8b5cf6;
--league-primary-rgb: 139,92,246;
--league-primary-glow: rgba(139,92,246,0.28);
--league-secondary: #37003c;
--league-bg: #0c0618;
--league-bg-card: #110a1e;
--league-text-accent: #ffffff;
/* Hero + ambience, successor of the g26-* set */
--s27-hero-start: #a78bfa;
--s27-hero-mid: #d946ef;
--s27-hero-end: #38bdf8;
--s27-floodlight: rgba(139,92,246,0.07);
}
:root[data-mode='light'][data-theme='season2627'] {
--league-primary: #7c3aed;
--league-primary-rgb: 124,58,237;
--league-primary-glow: rgba(124,58,237,0.18);
--league-secondary: #ede9fe;
--league-bg: #f5f5f7;
--league-bg-card: #ffffff;
--league-text-accent: #171125;
--s27-floodlight: rgba(124,58,237,0.05);
}
Move the existing .g26-hero, floodlight, and win-probability styles to season-neutral classes, then point them at these tokens.
Social and marketing graphics are match-day artifacts, not SaaS marketing. Tokens alone (palette + type + glow) produce generic startup cards; what makes a graphic unmistakably Gaffer is a football-native device carrying the layout. Every card is assembled from one of the three named devices below, never improvised from scratch. Coded templates live in social-agents/templates/cards/ (rendered via scripts/render-card.mjs); the shared assets partial (_assets.html) carries these fonts, the cap mark, and the jersey vector, so template output is brandbook-faithful by construction.
announcement.html) — an official squad-list document: ruled rows, violet number tiles, dotted leaders, a letterspaced stamp header, one gold money line in the footer. For announcements and any copy-led card; the sheet gives the copy a football object to sit beside.stat.html) — the owned vector jerseys in club colorways as the hero of player and stat cards. Names and numbers are facts; the shirt does the identity work. Violet bars for magnitude, gold for the value itself.fixture.html) — oversized Archivo tabular type (3-letter codes, scores, times) with kits flanking a lowercase v. Scoreboard typography at poster scale; the numbers are the design.playgaffer.xyz right. Compliance-sensitive cards carry "free everywhere · paid where the rules allow it" verbatim.| Don't | Do |
|---|---|
| A headline over an ambient gradient with the domain in a corner. The colors may be correct, but the card has no Gaffer device. | Set the same copy against the team sheet, kit wall, or fixture block. |
| Decorative glow gradients as the primary visual interest. | Devices as the visual interest; glow only as ambient depth behind a device. |
| Inventing a new layout per post. | New message → existing device + new data. New device → it gets named, coded, and added here first. |
Reference renders: social-agents/data/cards/2627-one-league.json → the announcement card that replaced the "don't" example above.
Gaffer talks like the sharpest manager in your league's group chat: quick, specific, a bit cocky, never corporate. If a sentence works without a word, the word goes.
| Say | Never | Why |
|---|---|---|
| Entry fee, prize pool | Buy-in, stake, pot, jackpot | Skill-based contest framing is a legal requirement, not a style choice |
| Skill-based contest | Bet, gamble, wager, odds, casino, house | Hard rule, no exceptions anywhere |
| "Held by a tamper-proof contract" | "We hold your money" | The escrow is the custodian, we never are |
| Instant payout, secure escrow | On-chain, gas, signer, USDC on Starknet | Plain English in the UI; the rails stay invisible |
| Manager, gaffer | User, player (for people) | "Player" means footballers; humans are managers |
| Settled, paid out | Cashed out (for prizes) | Matches the product's settlement lifecycle |
| "Global 26", "the international tournament" | Event names that are reserved marks | Same discipline the G26 hero copy already ships |
Social runs on the intern voice at @Play_Gaffer: over-eager, footy-brained, never corporate. No emojis, no hashtags, no threads, receipts over opinions.
The season opens in under a month. P1 ships before the opener, P2 during the first gameweeks, P3 when it hurts. Check items off, then delete them; this section should be empty by winter.
season2627 tokens, generalize the g26-* machinery (hero, floodlight, win-prob, confetti) to season classes, and point the PL surfaces at it before GW1.CLUB_COLORS to the 26/27 colorways in section 09 (COV / HUL / IPS rows, CRY sash, BHA pinstripes, LEE hoops, MCI fade, TOT tonal, CHE gold trim) and verify all 20 kits render legibly on the pitch.This brandbook is the locked single source of truth for Gaffer 27 identity and product presentation. The implementation lives in src/frontend/tailwind.config.js + styles/globals.css (tokens), components/brand/Logo.js + public/brand/ (logo), lib/teamColors.js + lib/playerIdentity.js (kits), and public/fonts/brand/ (fonts). Those files must implement the system defined here. Any intentional brand change starts in this book and updates the implementation in the same commit; legacy screenshots, drafts, and older handovers are not authority.