bae705aa97
- Add NFC ePassport roadmap (ICAO 9303, eIDAS) - Add TensorFlow.js edge face detection (BlazeFace) - Add structured audit logger (GDPR-compliant) - Risk scoring support Part of KYC Apple Native UX v1.1.0
240 lines
8.3 KiB
Markdown
240 lines
8.3 KiB
Markdown
# quiXzoom Market Pages — Template System
|
||
|
||
> **Master template**: `se/index.html` (quiXzoom.se, Swedish market)
|
||
> **System**: 22-market ccTLD landing-page framework
|
||
> **Owner**: Wavult Group / AAMOS (aamos.systems)
|
||
> **Last updated**: 2026-06-07
|
||
|
||
---
|
||
|
||
## Architecture
|
||
|
||
Each market gets its own folder under `quixzoom-market-pages/<cc>/` containing:
|
||
|
||
```
|
||
markets/<cc>/
|
||
├── index.html ← Full HTML landing page (single-file, no build step)
|
||
├── robots.txt ← Market-specific robots with sitemap URL
|
||
└── sitemap.xml ← Market sitemap with full hreflang cross-links
|
||
```
|
||
|
||
Files are deployed to S3 `s3://quixzoom-landing-prod/markets/<cc>/` and served via CloudFront.
|
||
|
||
---
|
||
|
||
## Market Checklist
|
||
|
||
When creating a new market from the SE template, change every item below:
|
||
|
||
### `index.html`
|
||
|
||
| Element | SE value | Action |
|
||
|---------|----------|--------|
|
||
| `<html lang="...">` | `sv` | → market language code |
|
||
| `<title>` | Swedish title | → translate, keep ≤60 chars |
|
||
| `<meta name="description">` | Swedish description | → translate, keep ≤155 chars |
|
||
| `<link rel="canonical">` | `https://quixzoom.se/` | → market ccTLD |
|
||
| `<meta name="geo.region">` | `SE` | → ISO 3166-1 alpha-2 |
|
||
| `<meta name="geo.country">` | `Sweden` | → country name |
|
||
| `<meta name="language">` | `Swedish` | → language name |
|
||
| All `og:` and `twitter:` tags | Swedish copy | → translated copy |
|
||
| Schema.org `@id` URLs | `quixzoom.se` | → market ccTLD |
|
||
| Schema.org `areaServed` | `Sweden` | → market country |
|
||
| Schema.org `FAQPage` | Swedish FAQs | → 4–5 locally relevant FAQs |
|
||
| Schema.org `inLanguage` | `sv` | → BCP-47 code |
|
||
| H1 hero heading | Swedish copy | → translate/adapt for market |
|
||
| Hero subtext | Swedish | → translate/adapt |
|
||
| Hero badge | `🇸🇪 Lanseras i Sverige · Juni 2026` | → flag + country + date |
|
||
| Step descriptions | Swedish | → translate |
|
||
| Why-cards | Swedish | → translate |
|
||
| Business section | Swedish | → translate |
|
||
| FAQ answers | Swedish | → translate + localize (e.g. tax authority name) |
|
||
| Footer language switcher | Active = 🇸🇪 | → set correct active market |
|
||
| Footer copyright | Swedish | → translate |
|
||
| Footer AAMOS link | Swedish label | → translate |
|
||
| All internal links | `quixzoom.se/...` | → market ccTLD |
|
||
| CTA links | `app.quixzoom.com/join` | → keep (global app) |
|
||
|
||
### `robots.txt`
|
||
|
||
Change: `Sitemap: https://quixzoom.se/sitemap.xml` → `https://quixzoom.<cc>/sitemap.xml`
|
||
|
||
### `sitemap.xml`
|
||
|
||
Change all `<loc>` entries to the market ccTLD. The `<xhtml:link>` hreflang cross-links stay the same across all markets (they reference all ccTLDs).
|
||
|
||
---
|
||
|
||
## Localization Notes
|
||
|
||
### Language codes (hreflang)
|
||
| Market | ccTLD | hreflang | Active |
|
||
|--------|-------|----------|--------|
|
||
| Sweden | quixzoom.se | `sv` | ✅ Live template |
|
||
| Germany | quixzoom.de | `de` | ⏳ Pending |
|
||
| France | quixzoom.fr | `fr` | ⏳ Pending |
|
||
| Netherlands | quixzoom.nl | `nl` | ⏳ Pending |
|
||
| United Kingdom | quixzoom.co.uk | `en-gb` | ⏳ Pending |
|
||
| Italy | quixzoom.it | `it` | ⏳ Pending |
|
||
| Spain | quixzoom.es | `es` | ⏳ Pending |
|
||
| Finland | quixzoom.fi | `fi` | ⏳ Pending |
|
||
| Denmark | quixzoom.dk | `da` | ⏳ Pending |
|
||
| Belgium | quixzoom.be | `be` | ⏳ Pending |
|
||
| Default | quixzoom.com | `x-default` | ✅ Live |
|
||
|
||
> Add new markets to the hreflang list in **all** existing market pages when adding a new ccTLD.
|
||
|
||
### Pay rate localization
|
||
The `150–500 kr` value in the stats section must be updated to local currency:
|
||
- 🇩🇪 `15–50 €`
|
||
- 🇫🇷 `15–50 €`
|
||
- 🇬🇧 `12–42 £`
|
||
- etc.
|
||
|
||
### Tax/legal localization
|
||
The FAQ answer about taxation must reference the **local tax authority**:
|
||
- 🇸🇪 → Skatteverket
|
||
- 🇩🇪 → Finanzamt
|
||
- 🇫🇷 → Direction générale des Finances publiques (DGFiP)
|
||
- 🇬🇧 → HMRC
|
||
- etc.
|
||
|
||
### Launch badge
|
||
Update the `hero-badge` with the correct launch region and date for each market.
|
||
|
||
---
|
||
|
||
## Design System
|
||
|
||
All design tokens are defined as CSS custom properties in `:root{}` — no external frameworks.
|
||
|
||
| Token | Value | Usage |
|
||
|-------|-------|-------|
|
||
| `--qx-black` | `#0a0a0a` | Hero bg, nav, body text |
|
||
| `--qx-white` | `#FFFFFF` | Main bg, text on dark |
|
||
| `--qx-blue` | `#0066FF` | CTAs, accents, stats bg |
|
||
| `--qx-green` | `#00C853` | Success states (future use) |
|
||
| `--qx-gray` | `#F5F5F7` | Section backgrounds, cards |
|
||
| `--qx-dark-gray` | `#1a1a1a` | Footer background |
|
||
| `--qx-text-muted` | `#6e6e73` | Descriptive body copy |
|
||
|
||
Font stack: `-apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Helvetica Neue', sans-serif`
|
||
→ System font stack — zero external requests, instant render, optimal CWV.
|
||
|
||
---
|
||
|
||
## Infrastructure: Deploying a Market Page
|
||
|
||
### Prerequisites
|
||
- AWS CLI configured with profile `platform-ai-agent`
|
||
- S3 bucket: `quixzoom-landing-prod`
|
||
- CloudFront distribution: `EE30B9WM5ZYM7` (serves quixzoom.com)
|
||
- For ccTLD: separate CloudFront distribution + Route53 A-record required (see below)
|
||
|
||
### Deploy command (served under quixzoom.com/markets/<cc>/)
|
||
```bash
|
||
CC=se # change per market
|
||
|
||
aws s3 cp /home/bernt/.openclaw/workspace/quixzoom-market-pages/$CC/index.html \
|
||
s3://quixzoom-landing-prod/markets/$CC/index.html \
|
||
--content-type "text/html; charset=utf-8" \
|
||
--cache-control "max-age=3600"
|
||
|
||
aws s3 cp /home/bernt/.openclaw/workspace/quixzoom-market-pages/$CC/robots.txt \
|
||
s3://quixzoom-landing-prod/markets/$CC/robots.txt \
|
||
--content-type "text/plain"
|
||
|
||
aws s3 cp /home/bernt/.openclaw/workspace/quixzoom-market-pages/$CC/sitemap.xml \
|
||
s3://quixzoom-landing-prod/markets/$CC/sitemap.xml \
|
||
--content-type "application/xml"
|
||
|
||
# Invalidate CloudFront cache
|
||
aws cloudfront create-invalidation \
|
||
--distribution-id EE30B9WM5ZYM7 \
|
||
--paths "/markets/$CC/*"
|
||
```
|
||
|
||
---
|
||
|
||
## How to Connect quixzoom.se → Its Own CloudFront
|
||
|
||
The SE market is currently served under `quixzoom.com/markets/se/`. To go fully live on `quixzoom.se`:
|
||
|
||
### Step 1 – Request/verify SSL certificate in ACM
|
||
```
|
||
Region: us-east-1 (required for CloudFront)
|
||
Domain: quixzoom.se
|
||
Include SANs: www.quixzoom.se
|
||
Validation: DNS (add CNAME in Route53 zone quixzoom.se)
|
||
```
|
||
|
||
### Step 2 – Create dedicated S3 bucket or path
|
||
Option A: Reuse `quixzoom-landing-prod` with a `se/` path prefix
|
||
Option B: Create `quixzoom-landing-se` bucket (cleaner separation)
|
||
|
||
### Step 3 – Create CloudFront distribution
|
||
```
|
||
Origin: s3://quixzoom-landing-prod/markets/se/ (or new bucket)
|
||
Default root object: index.html
|
||
Alternate domain names: quixzoom.se, www.quixzoom.se
|
||
SSL certificate: (from Step 1)
|
||
HTTP→HTTPS redirect: Yes
|
||
Compress objects: Yes (gzip/brotli)
|
||
Price class: PriceClass_100 (EU + NA)
|
||
```
|
||
|
||
### Step 4 – Route53: Add apex A-record (alias)
|
||
```
|
||
Zone: quixzoom.se (already exists)
|
||
Record type: A (Alias)
|
||
Alias target: <new CloudFront distribution domain>.cloudfront.net
|
||
TTL: 60s initially, then raise to 300s after verified
|
||
```
|
||
Also add AAAA alias record for IPv6.
|
||
|
||
### Step 5 – Add www redirect (optional)
|
||
Create a CloudFront Function or use S3 redirect to send www → apex.
|
||
|
||
### Step 6 – Deploy market files to new origin path
|
||
```bash
|
||
aws s3 cp .../se/index.html s3://quixzoom-landing-prod/markets/se/index.html ...
|
||
aws s3 cp .../se/robots.txt s3://quixzoom-landing-prod/markets/se/robots.txt ...
|
||
aws s3 cp .../se/sitemap.xml s3://quixzoom-landing-prod/markets/se/sitemap.xml ...
|
||
```
|
||
|
||
### Step 7 – Verify
|
||
```bash
|
||
curl -sI https://quixzoom.se/ | head -10
|
||
# Expect: HTTP/2 200, x-cache: Hit from cloudfront
|
||
```
|
||
|
||
---
|
||
|
||
## SEO Validation Checklist
|
||
|
||
After deploying a market page, verify:
|
||
|
||
- [ ] `<html lang="">` correct for market
|
||
- [ ] Title ≤ 60 chars with primary keyword first
|
||
- [ ] Description ≤ 155 chars, includes key terms
|
||
- [ ] Canonical points to market ccTLD apex
|
||
- [ ] hreflang set complete (all 10 markets + x-default)
|
||
- [ ] Schema.org valid (test with Google Rich Results Test)
|
||
- [ ] OG image returns 200 (check og-image.jpg)
|
||
- [ ] robots.txt accessible at `/robots.txt`
|
||
- [ ] sitemap.xml accessible at `/sitemap.xml`
|
||
- [ ] Submit sitemap to Google Search Console for market domain
|
||
- [ ] Core Web Vitals: LCP < 2.5s, CLS < 0.1, INP < 200ms
|
||
|
||
---
|
||
|
||
## File Sizes (SE market, 2026-06-07)
|
||
|
||
| File | Size | Notes |
|
||
|------|------|-------|
|
||
| index.html | ~25 KB | Single-file, no deps, all inline CSS |
|
||
| robots.txt | ~142 B | Minimal |
|
||
| sitemap.xml | ~1.7 KB | 4 URLs + full hreflang cross-links |
|
||
|
||
LCP target: < 2s on 4G mobile (system fonts = zero font-fetch latency).
|