Back to Library
Hero Image

Style Guide

Contents

For AI Agents (Claude Code)

Search for components using: grep "@component:" style-guide.html

Each component includes machine-readable metadata in HTML comments with @component, @classes, and @dependencies tags.

Colors

Brand and UI color palette

Brand Colors

Brand Tennis --brand-tennis
rgb(166, 213, 73)
#A6D549
Black --color-black
#000000
White --color-white
#FFFFFF
Gray 700 --color-gray-700
#333333

Overlay Colors

Overlay Light --color-overlay-light
rgba(0, 0, 0, 0.4)
Overlay Dark --color-overlay-dark
rgba(0, 0, 0, 0.6)

UI Colors

Gray 100 --color-gray-100
#F0F0F0
Gray 200 --color-gray-200
#E8E8E8
Accent Red --color-accent-red
#FF6B6B
Court Green --color-court-green
#4A7C4E

Typography

Exo 2 font family from Google Fonts

Type Scale

Aa

Hero Title | 95.4pt | Weight 900 | Uppercase

Variable: --text-hero | Class: .reseller-title

Usage: Main page cover titles

Heading

Section Heading | 32pt | Weight 900 | Uppercase

Variable: --text-2xl | Class: .key-info-heading

Usage: Major section headers on content pages

Card Title

Card Heading | 24pt | Weight 900 | Uppercase

Variable: --text-xl | Class: .drills-heading

Usage: Page section titles

Label Text

Label | 16pt | Weight 700 | Uppercase

Variable: --text-lg | Class: .info-label

Usage: List item labels, feature names

Endorsement

Endorsement | 12pt | Weight 700 | Uppercase

Variable: --text-base | Class: .endorsement-heading

Usage: Secondary headings, endorsement titles

Body text for descriptions and longer content that needs to be readable.

Body | 11pt | Weight 400 | Normal case

Variable: --text-sm | Class: .info-description

Usage: Descriptive text, paragraphs

Small Label

Small | 10pt | Weight 700 | Uppercase

Variable: --text-xs | Class: .drill-card h3

Usage: Small labels, card titles

Spacing

Consistent spacing tokens in millimeters

Spacing Scale

--space-xs: 2mm
--space-sm: 5mm
--space-md: 8mm
--space-lg: 10mm
--space-xl: 15mm
--space-2xl: 20mm
--space-3xl: 40mm

Page Dimensions

Property Value Variable
Page Width 210mm --page-width
Page Height 297mm --page-height
Page Padding 20mm --page-padding
Content Width 170mm --page-content-width
Content Height 257mm --page-content-height

Page Layout

210mm 297mm Safe area: 170 x 257mm 20mm padding

Components

Reusable UI elements for PDF templates

Hero Section

Full-bleed background with overlay and title

@component: tsp-hero

Specifications

ElementPropertyValue
.hero-sectionPositionabsolute, full page (100% x 100%)
.hero-imageObject Fitcover
.overlayBackgroundrgba(0, 0, 0, 0.4) | --color-overlay-light
.content-wrapperPositionabsolute, top: 10mm, left: 10mm
.content-wrapperz-index10
.logoWidth80mm
.logoMargin Bottom5mm
.reseller-titleFontExo 2, 95.4pt, weight 900
.reseller-titleColorwhite
.reseller-titleMax Width170mm

HTML Structure

<div class="page"> <div class="hero-section"> <img src="assets/img/hero.jpg" alt="Hero" class="hero-image"> </div> <div class="overlay"></div> <div class="content-wrapper"> <img src="assets/img/topspinpro-logo-white@SVG.svg" alt="Logo" class="logo"> <h1 class="reseller-title">Title Text</h1> </div> </div>

Curved Wave Section

Top section with curved bottom edge

@component: tsp-wave-curved-top

Specifications

ElementPropertyValue
.curved-topHeight193mm (65% of page)
.curved-topClip Pathurl(#curve-clip)
.curved-overlayBackgroundrgba(0, 0, 0, 0.6) | --color-overlay-dark
.curved-overlayz-index1
Contentz-index2 (must be above overlay)

SVG Clip Path Definition

<svg width="0" height="0"> <defs> <clipPath id="curve-clip" clipPathUnits="objectBoundingBox"> <path d="M0,0 L1,0 L1,0.667 Q0.75,0.833 0.5,0.833 T0,0.667 Z"/> </clipPath> </defs> </svg>

HTML Structure

<div class="page page-white"> <!-- SVG clip path definition (place once) --> <svg width="0" height="0">...</svg> <div class="curved-top"> <img src="assets/img/hero.jpg" alt="Hero" class="curved-top-image"> </div> <div class="curved-overlay"></div> <!-- Content goes here with z-index: 2 --> </div>

Curve Shape Preview

Info List

Feature list with icon markers

@component: tsp-info-list

Live Example

  • Label Text

    Description text goes here with supporting details.

Specifications

ElementPropertyValue
.info-itemGap8mm (--space-md)
.info-itemMargin Bottom10mm (--space-lg)
.info-iconSize7.5mm x 7.5mm
.info-iconBackgroundvar(--brand-tennis)
.info-iconPadding1.5mm
.info-icon svgFillblack
.info-labelFontExo 2, 16pt, weight 700, uppercase
.info-labelColorvar(--brand-tennis)
.info-descriptionFontExo 2, 11pt, weight 400
.info-descriptionColorwhite

HTML Structure

<ul class="info-list"> <li class="info-item"> <div class="info-icon"> <svg viewBox="0 0 24 24" fill="currentColor"> <!-- Heroicon path --> </svg> </div> <div class="info-content"> <h3 class="info-label">Label Text</h3> <p class="info-description">Description text</p> </div> </li> </ul>

Testimonial Cards

Grid of testimonial quotes with avatars

@component: tsp-testimonial-cards

Live Example

Matt Stringer

LTA level 3, All Star Tennis

The quickest results I have ever got teaching topspin.

Marjorie Blackwood

Former WTA Top 50 player

Pure genius! Amazing to see the difference in so little time!

Specifications

ElementPropertyValue
.testimonials-gridLayout2 columns, gap: 4mm
.testimonial-cardBackgroundrgba(30, 30, 30, 0.95)
.testimonial-cardBorder Radius3mm
.testimonial-cardPadding4mm
.testimonial-headerBorder Bottom1px solid rgba(166, 213, 73, 0.3)
.testimonial-avatarSize10mm x 10mm
.testimonial-nameFontExo 2, 9pt, weight 700
.testimonial-nameColorvar(--brand-tennis)
.testimonial-titleFontExo 2, 7pt, weight 400
.testimonial-quoteFontExo 2, 7pt, weight 400
.testimonial-quoteColorrgba(255, 255, 255, 0.9)

HTML Structure

<div class="testimonials-section"> <div class="testimonials-grid"> <div class="testimonial-card"> <div class="testimonial-header"> <img src="assets/img/testimonials/avatar.png" class="testimonial-avatar"> <div class="testimonial-info"> <p class="testimonial-name">Name Here</p> <p class="testimonial-title">Title/Role</p> </div> </div> <p class="testimonial-quote">Quote text here.</p> </div> </div> </div>

Pricing Table

Dark-themed pricing table with regional rates

@component: tsp-pricing-table

Live Example

Reseller Pricing

Wholesale rates for authorized resellers

Region RRP Purchase Price
Europe 115.83 EUR 68 EUR
United States 149.00 USD 80 USD

Specifications

ElementPropertyValue
.page-pricingBackgroundlinear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%)
.pricing-titleFontExo 2, 36pt, weight 900, uppercase
.pricing-subtitleColorvar(--brand-tennis)
.pricing-tableBorder Radius4mm
theadBackgroundvar(--brand-tennis)
thFontExo 2, 10pt, weight 700, uppercase
tbody tr:oddBackgroundrgba(255, 255, 255, 0.03)
tbody tr:evenBackgroundrgba(255, 255, 255, 0.07)
.region-nameFontExo 2, 12pt, weight 700, white
.price-rrpColorrgba(255, 255, 255, 0.7)
.price-purchaseColorvar(--brand-tennis), weight 700, 14pt

HTML Structure

<div class="page page-pricing"> <div class="pricing-header"> <h2 class="pricing-title">Reseller Pricing</h2> <p class="pricing-subtitle">Wholesale rates for authorized resellers</p> </div> <table class="pricing-table"> <thead> <tr> <th>Region</th> <th>RRP</th> <th>Purchase Price</th> </tr> </thead> <tbody> <tr> <td><span class="region-name">Europe</span></td> <td class="price-rrp">115.83 EUR</td> <td class="price-purchase">68 EUR</td> </tr> </tbody> </table> <div class="pricing-footnotes"> <p class="footnote"><strong>*</strong> Note text here</p> </div> </div>

Accessories Grid

Card-based grid for accessories with pricing

@component: tsp-accessories-grid

Live Example

Ball Pack & Screen Set

Contains: 1 x ball, 2 x elastics, 4 x washers

Region RRP Price
Europe 11.67 EUR 7.02 EUR

Specifications

ElementPropertyValue
.accessories-gridLayout2 columns, gap: 5mm
.accessory-cardBackgroundrgba(255, 255, 255, 0.05)
.accessory-cardBorder Radius3mm
.accessory-headerBackgroundrgba(50, 50, 50, 0.8)
.accessory-headerBorder Bottom2px solid var(--brand-tennis)
.accessory-nameFontExo 2, 9pt, weight 700, uppercase
.accessory-nameColorvar(--brand-tennis)
.accessory-imageSize20mm x 20mm
.accessory-descriptionFontExo 2, 7pt
.accessory-table thFontExo 2, 6pt, uppercase

HTML Structure

<div class="accessories-section"> <h3 class="accessories-title">Accessories</h3> <div class="accessories-grid"> <div class="accessory-card"> <div class="accessory-header"> <h4 class="accessory-name">Product Name</h4> </div> <div class="accessory-body"> <div class="accessory-intro"> <div class="accessory-image"> <img src="product.jpg" alt="Product"> </div> <p class="accessory-description">Description</p> </div> <table class="accessory-table"> <!-- Pricing rows --> </table> </div> </div> </div> </div>

Dimensions Table

Light-themed table for shipping and freight info

@component: tsp-dimensions-table

Live Example

Dimensions

Single Unit Master Carton
Individual units 1 6
Size L × W × H (cm) 68 × 27 × 10 63 × 28 × 70

Specifications

ElementPropertyValue
.page-freightBackgroundwhite
.freight-titleFontExo 2, 36pt, weight 900, uppercase
.section-titleFontExo 2, 18pt, weight 900, uppercase
.section-titleBorder Bottom1px solid rgba(0, 0, 0, 0.15)
.dimensions-tableBorder Radius4mm
.dimensions-tableBox Shadow0 2mm 10mm rgba(0, 0, 0, 0.1)
theadBackgroundvar(--brand-tennis)
th:first-childBackground#f5f5f5 (gray corner)
tbody tr:oddBackground#fafafa
tbody tr:evenBackground#f0f0f0
td:first-childFont Weight600
tdText Aligncenter (except first column: left)

HTML Structure

<div class="page page-freight"> <h2 class="freight-title">Freight</h2> <div class="dimensions-section"> <h3 class="section-title">Dimensions</h3> <table class="dimensions-table"> <thead> <tr> <th></th> <th>Single Unit</th> <th>Master Carton</th> </tr> </thead> <tbody> <tr> <td>Individual units</td> <td>1</td> <td>6</td> </tr> </tbody> </table> </div> </div>

Tennis Court Diagram

Court SVG for drill patterns and coaching visuals

@component: tsp-court-diagram

Live Example

Coaching Drill Patterns

Baseline Rally

Tennis Court

Cross-Court

Tennis Court

Volley Practice

Tennis Court

Specifications

ElementPropertyValue
.drills-headingFontExo 2, 24pt, weight 900, uppercase
.drills-headingColor#333
.drills-headingMargin Bottom10mm
.drills-gridLayout3 columns, gap: 8mm
.drill-cardText Aligncenter
.drill-card h3FontExo 2, 10pt, weight 700, uppercase
.drill-card h3Margin Bottom3mm
.court-diagramWidth100%
.court-diagramBorder Radius2mm

HTML Structure

<div class="drills-section"> <h2 class="drills-heading">Coaching Drill Patterns</h2> <div class="drills-grid"> <div class="drill-card"> <h3>Baseline Rally</h3> <img src="assets/img/tennis-court.svg" alt="Tennis Court" class="court-diagram"> </div> <!-- More drill cards --> </div> </div>

Court SVG Asset

PropertyValue
Pathassets/img/tennis-court.svg
TypeSVG vector image
UsageEmbed as <img> or inline SVG
CustomizationOverlay arrows/markers with CSS positioning

Tip: For interactive drill diagrams, consider wrapping the court in a positioned container and adding SVG overlays for arrows, player positions, and movement paths.

Logo Grid & Endorsement

Partner logos and endorsement headings

@component: tsp-logo-grid, tsp-endorsement

Endorsement Heading

Used & Endorsed by Tennis Pros and Federations

Logo Grid Specifications

ElementPropertyValue
.endorsement-sectionPositionabsolute, bottom: 20mm, left: 20mm, right: 20mm
.endorsement-sectionz-index3
.endorsement-headingFontExo 2, 12pt, weight 700, uppercase
.highlightColorvar(--brand-tennis)
.normalColorwhite
.logo-gridColumns5 equal columns
.logo-gridGap10mm (--space-lg)
.logo-item imgMax Height25mm
.logo-item imgFilterbrightness(0) invert(1) - makes white

HTML Structure

<div class="endorsement-section"> <h2 class="endorsement-heading"> <span class="highlight">Used & Endorsed by</span> <span class="normal">Tennis Pros and Federations</span> </h2> <div class="logo-grid"> <div class="logo-item"> <img src="assets/img/logos/logo-lta.png" alt="LTA"> </div> <!-- More logo items --> </div> </div>

Available Logos

FileOrganization
logo-lta.pngLTA Tennis for Britain
logo-atpca.pngATPCA
logo-btca.pngBTCA
logo-john-mcenroe-tennis-academy.pngJohn McEnroe Tennis Academy
logo-moratogalou-naples.webpMoratoglou Naples

Icons & Assets

Heroicons library and image assets

Heroicons Library

Icons are from Heroicons (heroicons.com). The full library is available in:

PathSizeCount
assets/icons/16/solid/16px316 icons
assets/icons/20/solid/20px324 icons
assets/icons/24/solid/24px324 icons

Commonly Used Icons

shield-check

check-badge

star

Icon Usage Pattern

<div class="info-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path fill-rule="evenodd" d="..." clip-rule="evenodd"/> </svg> </div>

Image Assets

PathDescription
assets/img/hero.jpgFull-bleed hero background
assets/img/topspinpro-logo-white@SVG.svgWhite logo for dark backgrounds
assets/img/topspinpro-logo-color@SVG.svgColor logo for light backgrounds
assets/img/topspinpro-for-tennis.pngProduct image
assets/img/logos/*.pngPartner logos

Utilities

Utility classes for page breaks and layout control

Page Break Utility

Force a manual page break in flowing content. Useful for breaking sections at specific points (e.g., before a glossary, appendix, or major section).

Specifications

PropertyValue
Class.page-break
Element Type<div> (empty)
DisplayBlock (invisible, height: 0)
page-break-afteralways
page-break-insideavoid
Height0 (no layout impact)
Margin0
Padding0

HTML Structure

<div class="content"> <h1>Chapter 1</h1> <p>Content here...</p> <!-- Force page break before glossary --> <div class="page-break"></div> <h1>Glossary</h1> <p>Term definitions...</p> </div>

Usage Notes

CSS Definition

.page-break { page-break-after: always; page-break-inside: avoid; height: 0; margin: 0; padding: 0; }