feat: initial commit — storefront, convex backend, and shared packages

Completes the first milestone of The Pet Loft ecommerce platform:
- apps/storefront: full customer-facing Next.js app with HeroUI (cart,
  checkout, orders, wishlist, product detail, shop, search, auth)
- convex/: serverless backend with schema, queries, mutations, actions,
  HTTP routes, Stripe/Shippo integrations, and co-located tests
- packages/types, packages/utils, packages/convex: shared workspace packages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-04 09:31:18 +03:00
commit cc15338ad9
361 changed files with 45005 additions and 0 deletions

View File

@@ -0,0 +1,571 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PetPaws — Brand Color Palette</title>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:wght@400;600;700&family=DM+Sans:wght@300;400;500&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--brand: #38a99f;
--brand-dark: #236f6b;
--brand-light: #8dd5d1;
--brand-mist: #e8f7f6;
--warm: #f4a13a;
--warm-light: #fde8c8;
--coral: #f2705a;
--coral-light: #fce0da;
--neutral-900: #1a2e2d;
--neutral-700: #3d5554;
--neutral-400: #8aa9a8;
--neutral-100: #f0f8f7;
--white: #ffffff;
}
body {
background: var(--neutral-100);
font-family: 'DM Sans', sans-serif;
color: var(--neutral-900);
padding: 2rem;
min-height: 100vh;
}
header {
text-align: center;
margin-bottom: 3.5rem;
}
.badge {
display: inline-block;
background: var(--brand);
color: white;
font-size: .72rem;
font-weight: 500;
letter-spacing: .12em;
text-transform: uppercase;
padding: .35rem .9rem;
border-radius: 99px;
margin-bottom: 1rem;
}
header h1 {
font-family: 'Fraunces', serif;
font-size: clamp(2rem, 5vw, 3.2rem);
font-weight: 700;
line-height: 1.1;
color: var(--neutral-900);
}
header p {
margin-top: .6rem;
color: var(--neutral-700);
font-size: 1rem;
font-weight: 300;
}
/* ── section label ── */
.section-label {
font-size: .72rem;
font-weight: 500;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--neutral-400);
margin-bottom: 1rem;
}
/* ── swatch grid ── */
.palette-group {
margin-bottom: 3rem;
}
.swatches {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
gap: 1rem;
}
.swatch {
border-radius: 16px;
overflow: hidden;
box-shadow: 0 2px 12px rgba(56,169,159,.08);
background: white;
transition: transform .2s, box-shadow .2s;
}
.swatch:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(56,169,159,.18);
}
.swatch-color {
height: 110px;
width: 100%;
position: relative;
}
.swatch-color .star {
position: absolute;
top: 8px; right: 10px;
font-size: 1.1rem;
opacity: .85;
}
.swatch-info {
padding: .75rem 1rem .9rem;
}
.swatch-name {
font-weight: 500;
font-size: .9rem;
margin-bottom: .25rem;
color: var(--neutral-900);
}
.swatch-hex {
font-size: .78rem;
color: var(--neutral-400);
font-family: 'Courier New', monospace;
letter-spacing: .04em;
}
.swatch-role {
font-size: .72rem;
color: var(--neutral-700);
margin-top: .3rem;
font-weight: 300;
line-height: 1.3;
}
/* ── usage card ── */
.usage-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 1rem;
margin-bottom: 3rem;
}
.usage-card {
background: white;
border-radius: 16px;
padding: 1.2rem 1.4rem;
box-shadow: 0 2px 12px rgba(56,169,159,.07);
border-left: 4px solid var(--brand);
}
.usage-card h3 {
font-size: .88rem;
font-weight: 500;
margin-bottom: .5rem;
}
.usage-card p {
font-size: .8rem;
color: var(--neutral-700);
line-height: 1.5;
font-weight: 300;
}
/* ── preview strip ── */
.preview {
border-radius: 20px;
overflow: hidden;
box-shadow: 0 4px 24px rgba(56,169,159,.15);
margin-bottom: 3rem;
}
.preview-nav {
background: var(--brand-dark);
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 1.8rem;
}
.preview-nav .logo {
font-family: 'Fraunces', serif;
font-size: 1.35rem;
color: white;
font-weight: 700;
}
.preview-nav .logo span { color: var(--warm); }
.preview-nav nav a {
color: rgba(255,255,255,.75);
text-decoration: none;
font-size: .82rem;
margin-left: 1.5rem;
font-weight: 400;
}
.preview-hero {
background: linear-gradient(135deg, var(--brand-dark) 0%, var(--brand) 60%, var(--brand-light) 100%);
padding: 3rem 2rem;
display: flex;
align-items: center;
gap: 2rem;
flex-wrap: wrap;
}
.preview-hero-text { flex: 1; min-width: 200px; }
.preview-hero h2 {
font-family: 'Fraunces', serif;
font-size: clamp(1.6rem, 4vw, 2.4rem);
color: white;
line-height: 1.15;
margin-bottom: .8rem;
}
.preview-hero p {
color: rgba(255,255,255,.82);
font-size: .9rem;
margin-bottom: 1.2rem;
max-width: 320px;
font-weight: 300;
}
.btn-primary {
background: var(--warm);
color: var(--neutral-900);
border: none;
padding: .7rem 1.5rem;
border-radius: 99px;
font-weight: 500;
font-size: .88rem;
cursor: pointer;
font-family: 'DM Sans', sans-serif;
margin-right: .5rem;
}
.btn-outline {
background: transparent;
color: white;
border: 1.5px solid rgba(255,255,255,.5);
padding: .68rem 1.4rem;
border-radius: 99px;
font-size: .88rem;
cursor: pointer;
font-family: 'DM Sans', sans-serif;
}
.preview-cards {
background: var(--neutral-100);
padding: 1.5rem 2rem;
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
.mini-card {
background: white;
border-radius: 12px;
padding: 1rem;
width: 140px;
box-shadow: 0 2px 8px rgba(56,169,159,.1);
}
.mini-card-color {
height: 70px;
border-radius: 8px;
margin-bottom: .6rem;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.8rem;
}
.mini-card h4 {
font-size: .8rem;
font-weight: 500;
margin-bottom: .2rem;
}
.mini-card .price {
color: var(--brand-dark);
font-weight: 600;
font-size: .85rem;
}
.tag-sale {
display: inline-block;
background: var(--coral-light);
color: var(--coral);
font-size: .65rem;
font-weight: 500;
padding: .1rem .4rem;
border-radius: 4px;
margin-bottom: .3rem;
}
.tag-new {
display: inline-block;
background: var(--warm-light);
color: #b36a10;
font-size: .65rem;
font-weight: 500;
padding: .1rem .4rem;
border-radius: 4px;
margin-bottom: .3rem;
}
/* typography combos */
.typo-row {
display: flex;
gap: 1rem;
flex-wrap: wrap;
margin-bottom: 3rem;
}
.typo-card {
flex: 1;
min-width: 200px;
background: white;
border-radius: 16px;
padding: 1.4rem 1.6rem;
box-shadow: 0 2px 12px rgba(56,169,159,.07);
}
.typo-card .label {
font-size: .7rem;
text-transform: uppercase;
letter-spacing: .1em;
color: var(--neutral-400);
margin-bottom: .5rem;
}
footer {
text-align: center;
font-size: .78rem;
color: var(--neutral-400);
padding-top: 1rem;
border-top: 1px solid var(--brand-mist);
}
</style>
</head>
<body>
<header>
<div class="badge">🐾 Brand Color System</div>
<h1>PetPaws — Color Palette</h1>
<p>Designed around client primary <strong>#38a99f</strong> · Pet Items E-commerce</p>
</header>
<!-- PRIMARY PALETTE -->
<div class="palette-group">
<p class="section-label">01 · Primary — Teal Brand Family</p>
<div class="swatches">
<div class="swatch">
<div class="swatch-color" style="background:#236f6b;"><span class="star"></span></div>
<div class="swatch-info">
<div class="swatch-name">Deep Teal</div>
<div class="swatch-hex">#236f6b</div>
<div class="swatch-role">Headers, Nav, Footer</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#38a99f;"><span class="star" style="color:white">★ LOGO</span></div>
<div class="swatch-info">
<div class="swatch-name">Brand Teal</div>
<div class="swatch-hex">#38a99f</div>
<div class="swatch-role">Logo, Primary Buttons, Links</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#8dd5d1;"></div>
<div class="swatch-info">
<div class="swatch-name">Soft Teal</div>
<div class="swatch-hex">#8dd5d1</div>
<div class="swatch-role">Hover States, Icons, Tags</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#e8f7f6;"></div>
<div class="swatch-info">
<div class="swatch-name">Teal Mist</div>
<div class="swatch-hex">#e8f7f6</div>
<div class="swatch-role">Backgrounds, Cards, Section Fills</div>
</div>
</div>
</div>
</div>
<!-- ACCENT PALETTE -->
<div class="palette-group">
<p class="section-label">02 · Accent — Warmth & Energy</p>
<div class="swatches">
<div class="swatch">
<div class="swatch-color" style="background:#f4a13a;"></div>
<div class="swatch-info">
<div class="swatch-name">Sunny Amber</div>
<div class="swatch-hex">#f4a13a</div>
<div class="swatch-role">CTA Buttons, Sale Banners, Highlights</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#fde8c8;"></div>
<div class="swatch-info">
<div class="swatch-name">Amber Cream</div>
<div class="swatch-hex">#fde8c8</div>
<div class="swatch-role">"New" Tags, Promotional Chips</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#f2705a;"></div>
<div class="swatch-info">
<div class="swatch-name">Playful Coral</div>
<div class="swatch-hex">#f2705a</div>
<div class="swatch-role">Alerts, Discount Badges, Wishlist</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#fce0da;"></div>
<div class="swatch-info">
<div class="swatch-name">Coral Blush</div>
<div class="swatch-hex">#fce0da</div>
<div class="swatch-role">"Sale" Tag Fills, Error Backgrounds</div>
</div>
</div>
</div>
</div>
<!-- NEUTRAL PALETTE -->
<div class="palette-group">
<p class="section-label">03 · Neutrals — Structure & Readability</p>
<div class="swatches">
<div class="swatch">
<div class="swatch-color" style="background:#1a2e2d;"></div>
<div class="swatch-info">
<div class="swatch-name">Forest Black</div>
<div class="swatch-hex">#1a2e2d</div>
<div class="swatch-role">Body Text, Dark Mode BG</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#3d5554;"></div>
<div class="swatch-info">
<div class="swatch-name">Moss Grey</div>
<div class="swatch-hex">#3d5554</div>
<div class="swatch-role">Subheadings, Secondary Text</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#8aa9a8;"></div>
<div class="swatch-info">
<div class="swatch-name">Sage Mist</div>
<div class="swatch-hex">#8aa9a8</div>
<div class="swatch-role">Placeholders, Borders, Labels</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#f0f8f7; border: 1px solid #daeeed;"></div>
<div class="swatch-info">
<div class="swatch-name">Ice White</div>
<div class="swatch-hex">#f0f8f7</div>
<div class="swatch-role">Page Background, Card BG</div>
</div>
</div>
</div>
</div>
<!-- USAGE GUIDE -->
<p class="section-label">04 · Usage Guide</p>
<div class="usage-grid">
<div class="usage-card" style="border-color:var(--brand);">
<h3>🖥 Navigation & Header</h3>
<p>Deep Teal <strong>#236f6b</strong> background with white text. Logo in Brand Teal on light pages.</p>
</div>
<div class="usage-card" style="border-color:var(--warm);">
<h3>🛒 Primary CTA Buttons</h3>
<p>Sunny Amber <strong>#f4a13a</strong> — "Add to Cart", "Shop Now". Creates contrast & urgency.</p>
</div>
<div class="usage-card" style="border-color:var(--coral);">
<h3>🏷 Sale & Discount Badges</h3>
<p>Coral <strong>#f2705a</strong> on Coral Blush background. High visibility without harsh red.</p>
</div>
<div class="usage-card" style="border-color:var(--brand-light);">
<h3>📦 Product Cards</h3>
<p>White card on Ice White <strong>#f0f8f7</strong> background. Teal border on hover.</p>
</div>
<div class="usage-card" style="border-color:var(--neutral-700);">
<h3>📝 Typography</h3>
<p>Forest Black <strong>#1a2e2d</strong> for body. Deep Teal for headings. Sage Mist for metadata.</p>
</div>
<div class="usage-card" style="border-color:var(--brand-mist);">
<h3>🐶 Category Sections</h3>
<p>Alternating Teal Mist <strong>#e8f7f6</strong> and White sections for rhythm and visual flow.</p>
</div>
</div>
<!-- LIVE PREVIEW -->
<p class="section-label">05 · Live UI Preview</p>
<div class="preview">
<div class="preview-nav">
<div class="logo">Pet<span>Paws</span> 🐾</div>
<nav>
<a href="#">Dogs</a>
<a href="#">Cats</a>
<a href="#">Birds</a>
<a href="#">Sale</a>
</nav>
</div>
<div class="preview-hero">
<div class="preview-hero-text">
<h2>Everything Your Pet Deserves</h2>
<p>Premium food, toys & accessories — curated with love for your furry family.</p>
<button class="btn-primary">Shop Now</button>
<button class="btn-outline">Browse Categories</button>
</div>
</div>
<div class="preview-cards">
<div class="mini-card">
<div class="mini-card-color" style="background:var(--brand-mist);">🦴</div>
<div class="tag-new">NEW</div>
<h4>Dog Treats</h4>
<div class="price">KES 850</div>
</div>
<div class="mini-card">
<div class="mini-card-color" style="background:var(--warm-light);">🐱</div>
<div class="tag-sale">SALE 20%</div>
<h4>Cat Toy Set</h4>
<div class="price">KES 640</div>
</div>
<div class="mini-card">
<div class="mini-card-color" style="background:var(--coral-light);">🐦</div>
<h4>Bird Cage</h4>
<div class="price">KES 3,200</div>
</div>
<div class="mini-card">
<div class="mini-card-color" style="background:var(--brand-mist);">🐟</div>
<div class="tag-new">NEW</div>
<h4>Fish Food</h4>
<div class="price">KES 420</div>
</div>
</div>
</div>
<!-- TYPOGRAPHY -->
<p class="section-label">06 · Recommended Font Pairing</p>
<div class="typo-row">
<div class="typo-card">
<div class="label">Display / Headings</div>
<div style="font-family:'Fraunces',serif;font-size:2rem;font-weight:700;color:var(--neutral-900);line-height:1.1;">Fraunces<br><span style="color:var(--brand);">Serif</span></div>
<p style="font-size:.78rem;color:var(--neutral-400);margin-top:.5rem;">Warm, playful, trustworthy. Perfect for hero text and product names.</p>
</div>
<div class="typo-card">
<div class="label">Body / UI Text</div>
<div style="font-family:'DM Sans',sans-serif;font-size:1.6rem;font-weight:400;color:var(--neutral-700);">DM Sans<br><span style="font-weight:300;color:var(--neutral-400);">Clean Sans-Serif</span></div>
<p style="font-size:.78rem;color:var(--neutral-400);margin-top:.5rem;">Legible, modern, friendly. Great for body copy, buttons, and labels.</p>
</div>
</div>
<footer>
PetPaws Brand System · Primary #38a99f · Generated for Pet Items E-Commerce
</footer>
</body>
</html>