# Koa Africa Insurance Agency
Marketing website for Koa Africa Insurance Agency Limited, a Nairobi-based digital
insurance agency licensed by the Insurance Regulatory Authority of Kenya.
**Live:** koaafrica.agency
## Stack
- React 18 + Vite 6
- React Router 7
- CSS Modules with design token system
- No UI library, fully custom components
## Structure
```
scripts/ # verify.mjs harness + config
src/
├── styles/ # Design tokens, reset, global, animations
├── hooks/ # useRevealOnScroll, useNavScroll, useCounter,
│ useScrollAnimation
├── pages/ # Home, AboutPage, ProductsPage, CareersPage,
│ NotFoundPage
└── components/
├── layout/ # Navigation, Footer, PageHeader, ScrollToTop
├── sections/ # Hero, TrustBar, About, Products, WhyKoa,
│ AgentPortal, Testimonials, Contact
└── ui/ # Button, GlassCard, BaobabSVG, Icon
```
## Routes
| Path | Page |
|---|---|
| `/` | Home |
| `/about` | About + co-founders |
| `/products` | Product categories |
| `/careers` | Careers and CV submission |
| `/contact` | Contact form, details, and map |
| `*` | 404 |
## Dev
```bash
npm install
npm run dev #
localhost
npm run build
npm run verify # build + responsive/accessibility/routing checks
npm run images # regenerate public/*.webp from the source images
```
## Images
Photographic assets are WebP only, with no ` ` fallback: browsers
without WebP support (roughly 3%) get a broken image, traded for cutting the
payload from 5.1MB to 1.6MB.
Drop a new PNG/JPEG into `public/`, run `npm run images`, and commit the `.webp`
it leaves behind. The script converts and then deletes the source, so the repo
never carries both. `og-image.jpg` and `logo.png` are deliberately excluded:
social crawlers do not all render WebP, and the favicon wants a universally
accepted format. See the header of `scripts/images.mjs`.
`npm run verify` builds, serves `dist/`, and checks eve …