Documentation

GameGains API & Components

Comprehensive documentation for all public APIs, functions, and components used in the GameGains landing page.

Overview

GameGains is a Next.js 14 application built with React 18, TypeScript, and Tailwind CSS. It features a modern, responsive landing page with animated components, Supabase integration for email collection, and a distinctive visual design with pixel grid backgrounds and ASCII art decorations.

Next.js 14

App Router with server components

🎨

Tailwind CSS

Utility-first styling

🗄️

Supabase

Email collection backend

Getting Started

Installation

Clone the repository and install dependencies:

bash
git clone https://github.com/yourusername/gamegains-landing.git
cd gamegains-landing
npm install

Environment Variables

Create a .env.local file with the following variables:

env
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key

Development

Start the development server:

bash
npm run dev

The app will be available at http://localhost:3000

Production Build

bash
npm run build
npm start

Components

The application is built with modular React components. Below is documentation for each public component.

Component Architecture

text
src/
├── app/
│   ├── page.tsx          # Main landing page with all sections
│   ├── layout.tsx        # Root layout with metadata
│   └── globals.css       # Global styles and CSS variables
├── components/
│   └── Video2Ascii.tsx   # Video to ASCII art converter
└── lib/
    └── supabase.ts       # Supabase client configuration

Video2Ascii Component

A React component that converts video frames to ASCII art in real-time using canvas rendering.

Import

typescript
import Video2Ascii from '@/components/Video2Ascii';

Props

PropTypeDefaultDescription
videoSrcstring-Path to the video file to convert
classNamestring""Additional CSS classes to apply
fontSizenumber8Font size for ASCII characters in pixels
charactersstring" .:-=+*#%@"Character set for brightness mapping (dark to light)

Usage Example

typescript
<Video2Ascii 
  videoSrc="/background-video.mp4"
  className="opacity-50"
  fontSize={10}
  characters=" .:░▒▓█"
/>

How It Works

  1. Loads the video element (hidden) and a canvas element
  2. On each animation frame, draws the video to the canvas
  3. Reads pixel data and calculates brightness for each grid cell
  4. Maps brightness to ASCII characters and renders to canvas
  5. Automatically handles resize and video looping

EmailSignup Component

A form component for collecting email addresses and storing them in Supabase.

Props

PropTypeDefaultDescription
size"default" | "large""default"Controls the size of the input and button

Usage Example

typescript
// Default size
<EmailSignup />

// Large size for hero sections
<EmailSignup size="large" />

States

  • idle - Initial state, form is ready for input
  • loading - Submitting email to Supabase
  • success - Email successfully saved, shows confirmation

PixelGridBackground Component

An animated 8-bit style pixel grid background with randomly glowing squares.

Configuration

typescript
const gridSize = 40;           // 40x40 grid
const numGlowingSquares = 20;  // Number of active glowing squares
const interval = 15000;        // Milliseconds between glow changes

Animation

Squares transition between states using CSS transitions and the pulseGlow keyframe animation.

css
@keyframes pulseGlow {
  0%, 100% {
    background: rgba(250, 204, 21, 0.1);
    box-shadow: 0 0 15px rgba(250, 204, 21, 0.2);
  }
  50% {
    background: rgba(250, 204, 21, 0.2);
    box-shadow: 0 0 25px rgba(250, 204, 21, 0.4);
  }
}

GameItemsBanner Component

An infinite scrolling marquee displaying game items from CS2 and OSRS.

Game Items Data Structure

typescript
interface GameItem {
  src: string;    // Image path in /public
  name: string;   // Display name
  game: string;   // Game identifier (CS2, OSRS, etc.)
}

const gameItems: GameItem[] = [
  { src: "/awpdl.png", name: "AWP Dragon Lore", game: "CS2" },
  { src: "/bluephat.png", name: "Blue Partyhat", game: "OSRS" },
  // ... more items
];

Marquee Animation

css
.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee 40s linear infinite;
}

@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(calc(-100% / 3)); }
}

Supabase Integration

The application uses Supabase for storing email signups.

Client Configuration

typescript
// lib/supabase.ts
import { createClient } from '@supabase/supabase-js'

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL || ''
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || ''

export const supabase = supabaseUrl && supabaseAnonKey 
  ? createClient(supabaseUrl, supabaseAnonKey)
  : null

Database Schema

sql
CREATE TABLE emails (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  email TEXT NOT NULL UNIQUE,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Enable Row Level Security
ALTER TABLE emails ENABLE ROW LEVEL SECURITY;

-- Allow public inserts
CREATE POLICY "Allow public insert" ON emails
  FOR INSERT WITH CHECK (true);

Usage

typescript
// Insert a new email
const { error } = await supabase
  .from('emails')
  .insert([{ 
    email: userEmail, 
    created_at: new Date().toISOString() 
  }]);

Styling & Theming

The application uses CSS custom properties for consistent theming.

CSS Variables

css
:root {
  /* Typography */
  --font-heading: system-ui, -apple-system, sans-serif;
  --font-mono: 'SF Mono', 'Monaco', monospace;
  
  /* Colors */
  --color-bg: #0d0d0d;
  --color-text: #ffffff;
  --color-accent: #FACC15;
  --color-accent-dark: #EAB308;
  --color-green: #4ade80;
  --color-red: #f87171;
  --color-border: rgba(255, 255, 255, 0.08);
  --color-card-bg: rgba(20, 20, 20, 0.8);
  
  /* Layout */
  --section-padding: clamp(80px, 10vw, 160px);
}

Utility Classes

.card-border

Card with background and border styling

.glass

Glassmorphism effect with backdrop blur

.gradient-text

Yellow gradient text effect

.link-hover

Animated underline on hover

Animations

The application includes various animation utilities for scroll-triggered and interactive effects.

Scroll-Triggered Animations

typescript
// IntersectionObserver for fade-in animations
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add('visible');
      entry.target.classList.add('animate-in');
    }
  });
}, { threshold: 0.1, rootMargin: '50px' });

Animation Classes

.fade-in-up

Fade in with upward movement

.stagger

Staggered animation delays for children (0.1s increments)

.waterfall

Cascading reveal animation (0.15s increments)

.animate-float

Gentle floating animation

Hover Effects

css
/* Card lift effect */
.card:hover {
  transform: translateY(-8px);
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
}

/* Button color change */
.button:hover {
  background: var(--color-accent);
  color: #000000;
  transform: scale(1.02);
}

/* Image desaturate effect */
.image-hover img {
  filter: grayscale(30%);
}
.image-hover:hover img {
  transform: scale(1.03);
  filter: grayscale(0%);
}

© 2025 GameGains. All rights reserved.