# Numbers Protocol Website - Complete Documentation for LLMs ## Project Overview Numbers Protocol Website - A modern, responsive React application built with Vite, TypeScript, and Tailwind CSS. This is a pixel-perfect conversion of Figma designs for Numbers Protocol's provenance infrastructure platform. **Repository**: numbersprotocol/numbers-website **Production URL**: https://numbersprotocol.io **Tech Stack**: React 18, TypeScript, Vite 6, Tailwind CSS, React Router DOM 6 ## Key Features - Fully responsive design (mobile, tablet, desktop) - Static site generation for optimal performance - MDX-based blog system with frontmatter - Automated blog metadata generation - SEO-optimized with sitemap.xml and robots.txt - AI-friendly crawler permissions - GitHub Pages deployment with SPA routing - Dedicated ProofSnap storytelling sections for mobile and browser extension workflows ## ProofSnap Product Suite ### ProofSnap Mobile App - Seals photos and videos with GPS, device ID, and timestamps on Numbers Mainnet the instant they are captured - Automatically embeds C2PA manifests so editors and partners can validate provenance downstream - Field-reporter UX with offline capture queues and one-tap sharing for rapid evidence delivery ### ProofSnap Browser Extension - Captures full-page visuals, HTML source, and network headers in one verifiable package - Stores assets on IPFS, timestamps them to blockchain, and injects C2PA credentials automatically - Supports Chrome, Brave, and Edge with an "Add to Browser" CTA mirrored across hero and final CTA blocks ### Unified Evidence Workflow - Anchored sections (`#mobile`, `#extension`) let humans and crawlers deep-link directly to each product overview - Shared gradient CTA styling across page sections reinforces provenance-first messaging for ProofSnap queries - Dedicated data policy at `/proofsnap/data-policy` keeps compliance guidance adjacent to product marketing ## Project Structure ``` /workspaces/numbers-website/ ├── docs/ # Main application directory │ ├── src/ │ │ ├── App.tsx # Main router configuration │ │ ├── index.tsx # Entry point │ │ ├── components/ # Reusable React components │ │ │ ├── BlogContent/ # Blog article display │ │ │ ├── NavigationBar/ # Header navigation │ │ │ ├── Footer/ # Site footer │ │ │ ├── MDXRenderer.tsx # MDX content renderer │ │ │ └── PageLayout/ # Page wrapper layout │ │ ├── screens/ # Page-level components │ │ │ ├── Home.tsx # Landing page │ │ │ ├── Blog.tsx # Blog listing page │ │ │ ├── BlogArticle.tsx # Individual blog post │ │ │ ├── UseCases.tsx # Use cases listing │ │ │ ├── UseCaseArticle.tsx # Use case detail │ │ │ ├── About.tsx # About page │ │ │ ├── Build.tsx # Build page │ │ │ ├── Careers.tsx # Careers page │ │ │ ├── Ecosystem.tsx # Ecosystem page │ │ │ ├── ProofSnap.tsx # ProofSnap product page │ │ │ └── SwapNum.tsx # NUM token swap page │ │ ├── data/ │ │ │ ├── blogMetadata.json # Generated blog metadata │ │ │ └── blogModules.ts # Generated static imports │ │ ├── services/ # Business logic │ │ ├── types/ # TypeScript type definitions │ │ └── utils/ # Helper functions │ ├── blogs/ # Blog content (MDX files) │ │ └── YYYY-MM-DD_slug/ │ │ ├── article.mdx # Blog content with frontmatter │ │ └── assets/ # Blog images/media │ ├── scripts/ # Build scripts │ │ ├── generateBlogMetadata.js # Extracts blog frontmatter │ │ ├── generateBlogModules.js # Creates static imports │ │ ├── generateSitemap.js # Generates sitemap.xml │ │ └── validateBlogs.js # Validates blog structure │ ├── static/ # Static assets │ │ ├── robots.txt # AI-friendly crawler config │ │ └── sitemap.xml # Auto-generated sitemap │ ├── plugins/ # Vite plugins │ │ └── blogAssets.ts # Blog asset handling │ ├── index.html # HTML entry point │ ├── package.json # Dependencies and scripts │ ├── vite.config.ts # Vite configuration │ ├── tailwind.config.js # Tailwind CSS config │ └── tsconfig.json # TypeScript config ├── .github/ │ └── workflows/ # GitHub Actions CI/CD └── README.md # Project documentation ``` ## Core Technologies ### Frontend Framework - **React 18**: Component-based UI library - **TypeScript**: Static typing for JavaScript - **Vite 6**: Build tool and dev server (ESM-first) - **React Router DOM 6**: Client-side routing ### Styling - **Tailwind CSS 3**: Utility-first CSS framework - **tailwind-merge**: Conditional Tailwind class merging - **tailwindcss-animate**: Animation utilities - **clsx**: Conditional className utility ### Content Management - **MDX (@mdx-js/react, @mdx-js/rollup)**: Markdown + JSX - **gray-matter**: Frontmatter parsing - **remark-frontmatter**: MDX frontmatter plugin - **remark-mdx-frontmatter**: MDX frontmatter injection ### Utilities - **date-fns**: Date formatting - **lucide-react**: Icon library - **prop-types**: Runtime prop validation ### Build Tools - **esbuild**: Fast JavaScript bundler - **glob**: File pattern matching - **chokidar**: File system watcher ## Routing Configuration Routes are defined in `docs/src/App.tsx`: ```typescript / (index) → Home screen /home → Home screen /about → About page /build → Build page /ecosystem → Ecosystem page /careers → Careers page /swap-num → NUM token swap /proofsnap → ProofSnap product page /proofsnap/data-policy → Data policy page /blog → Blog listing /blog/:slug → Individual blog article /use-cases → Use cases listing /use-case-article/:slug → Use case detail page /* → Fallback to Home ``` ### GitHub Pages SPA Routing The app includes a redirect handler for GitHub Pages 404-based routing: - 404.html redirects to index.html with `?redirect=/path` - RedirectHandler component reads the redirect parameter - Navigates to the intended route client-side ## Blog System ### Architecture The blog system uses **static imports** for stability and predictability: 1. **No Dynamic Imports**: Eliminates runtime import.meta.glob() issues 2. **Build-Time Generation**: Metadata and modules generated once 3. **Static Type Safety**: TypeScript knows all blog modules 4. **Predictable Bundling**: Vite can optimize better ### Blog Directory Structure ``` docs/blogs/YYYY-MM-DD_slug/ ├── article.mdx # Content with frontmatter └── assets/ # Images and media └── cover.png ``` ### Frontmatter Schema ```yaml --- title: string (required) category: TUTORIAL | GENERAL | TECH | TECHNOLOGY | ANNOUNCEMENT | GUIDE | NEWS | USE CASES excerpt: string (required) coverImage: ./assets/image.png (required) author: string (optional) date: YYYY-MM-DD (optional, defaults to folder date) --- ``` ### Blog Workflow 1. **Create blog**: `docs/blogs/2025-11-17_my-article/article.mdx` 2. **Add frontmatter**: Title, category, excerpt, coverImage 3. **Run generation**: `npm run blog:build` - Validates all blogs - Generates `src/data/blogMetadata.json` - Generates `src/data/blogModules.ts` (static imports) - Generates `static/sitemap.xml` 4. **Test**: `npm run blog:preview` 5. **Commit**: Generated files + blog content ### Generated Files **src/data/blogMetadata.json** ```json [ { "slug": "my-article", "title": "My Article", "category": "TUTORIAL", "excerpt": "...", "coverImage": "/blogs/2025-11-17_my-article/assets/cover.png", "date": "2025-11-17", "folder": "2025-11-17_my-article" } ] ``` **src/data/blogModules.ts** ```typescript import article_1 from '../blogs/2025-11-17_my-article/article.mdx'; export const blogModules: Record = { '2025-11-17_my-article': article_1, }; ``` ## NPM Scripts ```json { "dev": "vite", // Start dev server "build": "npm run blog:build && vite build", // Production build "blog:build": "npm run validate-blogs && npm run generate-blog-metadata && npm run generate-blog-modules && npm run generate-sitemap", "generate-blog-metadata": "node scripts/generateBlogMetadata.js", "generate-blog-modules": "node scripts/generateBlogModules.js", "generate-sitemap": "node scripts/generateSitemap.js", "validate-blogs": "node scripts/validateBlogs.js", "blog:check": "npm run validate-blogs && echo '✅ All blogs are valid!'", "blog:preview": "npm run blog:build && npm run dev" } ``` ## Build Scripts ### scripts/validateBlogs.js - Scans `blogs/` directory - Validates frontmatter presence and format - Checks required fields (title, category, excerpt, coverImage) - Validates category values - Ensures blog folder naming convention (YYYY-MM-DD_slug) ### scripts/generateBlogMetadata.js - Parses all article.mdx files - Extracts frontmatter using gray-matter - Generates `src/data/blogMetadata.json` - Sorts by date (newest first) - Computes slug from folder name ### scripts/generateBlogModules.js - Creates `src/data/blogModules.ts` - Generates static import statements for each blog - Exports Record mapping folder name to MDX component - Enables type-safe blog loading ### scripts/generateSitemap.js - Reads `src/data/blogMetadata.json` - Generates `static/sitemap.xml` - Includes static routes (/, /about, /blog, etc.) - Includes dynamic blog routes (/blog/:slug) - Includes use case routes (/use-case-article/:slug) - Sets appropriate changefreq and priority values - Uses ISO 8601 date format for lastmod ## SEO Configuration ### robots.txt (static/robots.txt) AI-friendly configuration allowing all major crawlers: ``` User-agent: * Allow: / Sitemap: https://numbersprotocol.io/sitemap.xml # AI Crawlers (explicitly allowed) User-agent: GPTBot # OpenAI User-agent: OAI-SearchBot # OpenAI Search User-agent: ChatGPT-User # ChatGPT User-agent: CCBot # Common Crawl User-agent: Google-Extended # Google AI User-agent: anthropic-ai # Anthropic User-agent: ClaudeBot # Claude User-agent: Claude-Web # Claude Web User-agent: Claude-User # Claude User User-agent: cohere-ai # Cohere User-agent: PerplexityBot # Perplexity User-agent: meta-externalagent # Meta AI User-agent: Applebot-Extended # Apple AI User-agent: Amazonbot # Amazon User-agent: DuckAssistBot # DuckDuckGo AI User-agent: Bytespider # ByteDance/TikTok # Traditional Search (allowed) User-agent: Googlebot User-agent: Bingbot User-agent: Slurp # Yahoo User-agent: DuckDuckBot ``` ### sitemap.xml Auto-generated, includes: - Static pages with appropriate priorities (homepage: 1.0, main sections: 0.8-0.9) - Blog articles with lastmod dates (priority: 0.6, changefreq: never) - Use case articles (priority: 0.6, changefreq: monthly) - All routes use https://numbersprotocol.io base URL ## Styling System ### Tailwind CSS Configuration Custom theme extensions in `tailwind.config.js`: **Colors:** - Primary: Numbers Protocol brand colors - Accent colors for CTAs and highlights - Semantic colors (success, warning, error) **Typography:** - Font families: Instrument Serif, Roboto Mono, Overused Grotesk - Custom font sizes and line heights - Responsive typography scales **Spacing:** - Custom spacing scale - Container max-widths - Section padding utilities **Components:** - Custom button styles - Card components - Navigation styles - Footer layouts ### CSS Architecture - **Utility-first**: Tailwind utilities for most styling - **Component Classes**: Extracted for repeated patterns - **Responsive Design**: Mobile-first breakpoints (sm, md, lg, xl, 2xl) - **Dark Mode**: Prepared for dark mode support - **Animations**: Custom animations via tailwindcss-animate ## Component Patterns ### Page Structure ```tsx import { PageLayout } from '../components/PageLayout'; export const MyPage = () => { return ( {/* Page content */} ); }; ``` ### Blog Article Component ```tsx // BlogArticle.tsx - Reads slug from route params - Loads blog from blogModules - Fetches metadata from blogMetadata.json - Renders MDX content via MDXRenderer - Displays author, date, category - Shows cover image - Handles 404 for missing articles ``` ### MDX Rendering ```tsx // MDXRenderer.tsx - Wraps MDX content with MDXProvider - Provides custom components for MDX elements - Handles headings, links, images, code blocks - Applies consistent styling - Enables component imports in MDX ``` ## Deployment ### GitHub Pages 1. **Build**: `npm run build` creates `dist/` folder 2. **Deploy**: GitHub Actions pushes `dist/` to `gh-pages` branch 3. **Serve**: GitHub Pages serves from `gh-pages` branch 4. **Domain**: Custom domain configured (numbersprotocol.io) ### CI/CD Pipeline GitHub Actions workflow (`.github/workflows/deploy.yml`): ```yaml - Checkout code - Setup Node.js - Install dependencies - Run blog:build (generates metadata, modules, sitemap) - Build production bundle - Deploy to gh-pages branch ``` ### Environment Variables - `SITEMAP_BASE_URL`: Override base URL for sitemap (default: https://numbersprotocol.io) ## Development Workflow ### Starting Development ```bash cd docs npm install npm run blog:build # Generate blog files npm run dev # Start dev server ``` ### Adding a New Page 1. Create component in `src/screens/NewPage.tsx` 2. Add route in `src/App.tsx` 3. Update navigation in `src/components/NavigationBar` 4. Add to sitemap in `scripts/generateSitemap.js` (staticRoutes array) 5. Test and commit ### Adding a New Blog Post ```bash # 1. Create blog folder mkdir docs/blogs/2025-11-17_my-new-post # 2. Create article.mdx cat > docs/blogs/2025-11-17_my-new-post/article.mdx << 'EOF' --- title: My New Post category: TUTORIAL excerpt: A brief description coverImage: ./assets/cover.png --- ## Content here... EOF # 3. Add cover image mkdir docs/blogs/2025-11-17_my-new-post/assets cp ~/cover.png docs/blogs/2025-11-17_my-new-post/assets/ # 4. Generate and test npm run blog:build npm run dev # 5. Commit git add docs/blogs/2025-11-17_my-new-post git add docs/src/data/blogMetadata.json git add docs/src/data/blogModules.ts git add docs/static/sitemap.xml git commit -m "Add blog post: My New Post" git push origin main ``` ### Code Style - **TypeScript**: Strict mode enabled - **ESLint**: Code linting (if configured) - **Prettier**: Code formatting (if configured) - **Naming**: PascalCase for components, camelCase for functions/variables - **Imports**: Absolute imports from `src/` ## Common Issues & Solutions ### Blog Not Showing **Problem**: New blog article doesn't appear on site **Solution**: 1. Run `npm run blog:check` to validate frontmatter 2. Ensure folder name is `YYYY-MM-DD_slug` format 3. Run `npm run blog:build` to regenerate metadata 4. Check browser console for errors 5. Verify `src/data/blogMetadata.json` includes your post ### 404 on GitHub Pages **Problem**: Direct navigation to route shows 404 **Solution**: Already implemented - 404.html redirects to index.html with query param ### Vite Import Errors **Problem**: Module import errors during build **Solution**: 1. Ensure all blog MDX files have valid frontmatter 2. Run `npm run blog:build` to regenerate static imports 3. Clear Vite cache: `rm -rf node_modules/.vite` 4. Restart dev server ### Sitemap Not Updating **Problem**: Sitemap.xml doesn't include new content **Solution**: 1. Run `npm run generate-sitemap` 2. Or run full `npm run blog:build` 3. Commit `docs/static/sitemap.xml` ### TypeScript Errors **Problem**: Type errors in MDX or blog modules **Solution**: 1. Ensure `@mdx-js/react` types are installed 2. Check `tsconfig.json` includes MDX files 3. Regenerate `blogModules.ts`: `npm run generate-blog-modules` ## Key Files Reference ### App.tsx Main application router with route definitions and redirect handler ### PageLayout.tsx Wrapper component providing consistent page structure with navigation and footer ### BlogService.ts Service layer for blog operations (fetching, filtering, searching) ### blogMetadata.json Generated file with all blog metadata (DO NOT EDIT MANUALLY) ### blogModules.ts Generated file with static MDX imports (DO NOT EDIT MANUALLY) ### vite.config.ts Vite configuration with MDX plugin, build settings, and base path ### tailwind.config.js Tailwind CSS theme configuration and custom utilities ### package.json Project metadata, dependencies, and build scripts ## API Reference ### Blog Service Methods ```typescript // Get all blogs const blogs = blogService.getAllBlogs(); // Get blog by slug const blog = blogService.getBlogBySlug('my-article'); // Get blogs by category const tutorials = blogService.getBlogsByCategory('TUTORIAL'); // Search blogs const results = blogService.searchBlogs('keyword'); // Get recent blogs const recent = blogService.getRecentBlogs(5); ``` ### MDX Components Custom components available in MDX: ```tsx // Headings with auto-generated IDs

,

,

,

,

,
// Enhanced links // Images with lazy loading ... // Code blocks with syntax highlighting


// Custom components (import in MDX)
import { CustomComponent } from '../components/CustomComponent';
```

## Performance Optimizations

- **Code Splitting**: Route-based code splitting via React Router
- **Lazy Loading**: Images lazy loaded by default
- **Static Generation**: Blog metadata pre-generated
- **Tree Shaking**: Vite eliminates unused code
- **Minification**: Production builds minified with esbuild
- **Asset Optimization**: Images optimized and served via CDN
- **Caching**: Proper cache headers for static assets

## Security Considerations

- **Content Security**: React automatically escapes string content, but embedded HTML in MDX is rendered without additional sanitization; only allow trusted authors or add a sanitizer if needed
- **XSS Prevention**: React's built-in escaping for props/text
- **HTTPS Only**: Enforced via GitHub Pages
- **No Sensitive Data**: No API keys or secrets in frontend code
- **Dependencies**: Regular dependency updates for security patches

## Accessibility

- **Semantic HTML**: Proper heading hierarchy, landmarks
- **ARIA Labels**: Screen reader support
- **Keyboard Navigation**: All interactive elements keyboard accessible
- **Focus States**: Visible focus indicators
- **Alt Text**: Images have descriptive alt attributes
- **Color Contrast**: WCAG AA compliant color ratios

## Browser Support

- **Modern Browsers**: Chrome, Firefox, Safari, Edge (latest 2 versions)
- **Mobile**: iOS Safari, Chrome Mobile
- **Fallbacks**: Graceful degradation for older browsers

## Testing Strategy

- **Manual Testing**: Visual regression testing
- **Browser Testing**: Cross-browser compatibility checks
- **Responsive Testing**: Mobile, tablet, desktop viewports
- **Blog Validation**: Automated via validateBlogs.js script

## Future Enhancements

Potential improvements:
- Search functionality for blogs
- Tag/category filtering
- Related articles suggestions
- Comment system integration
- Newsletter subscription
- Social media sharing
- Analytics integration
- A/B testing framework

## Contributing Guidelines

1. Fork the repository
2. Create a feature branch
3. Follow existing code style
4. Write clear commit messages
5. Test thoroughly (especially blog system)
6. Update documentation if needed
7. Submit pull request

## Contact & Support

- **Website**: https://numbersprotocol.io
- **Repository**: https://github.com/numbersprotocol/numbers-website
- **Issues**: GitHub Issues tracker

## License

Copyright © 2025 Numbers Protocol. All rights reserved.

---

**Last Updated**: November 21, 2025
**Documentation Version**: 1.0.0