Compare commits
49 Commits
376755889d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3ee755f47 | ||
|
|
f8d97f46c5 | ||
|
|
edec5370b6 | ||
| 08699e6d0d | |||
|
|
74793fbc11 | ||
| 1de7b09ceb | |||
|
|
a8229e543e | ||
| b34e4b8538 | |||
|
|
37055ca74a | ||
| 9f58001a56 | |||
|
|
2a2d5fb9e5 | ||
|
|
0220aa5ff8 | ||
|
|
7f7b44415e | ||
| 265a867602 | |||
|
|
61ef7c14de | ||
| b8103ea072 | |||
| a481c382a6 | |||
| 5f9e8db7e5 | |||
| fe14ca30ff | |||
| cf9cbb6134 | |||
| 77485eee63 | |||
| 6e90a4adb6 | |||
| 3933cf42c0 | |||
| df6cff4895 | |||
|
|
7b45ca94a6 | ||
| 82e3a23df3 | |||
|
|
c09ba76350 | ||
| 66f52a2d6e | |||
|
|
ff7e4395ea | ||
| b6e6178466 | |||
| ce1095088d | |||
|
|
a8474fd208 | ||
|
|
c587df063b | ||
|
|
c7a205e40c | ||
|
|
92bd81aed4 | ||
|
|
33b1f7f9dd | ||
|
|
d31a13cbbe | ||
|
|
6f8d36140a | ||
| e5bcb7bad2 | |||
|
|
dbda554d28 | ||
|
|
93049e9044 | ||
|
|
a6bd0ca864 | ||
|
|
dbaad19d0b | ||
|
|
4134aec1f8 | ||
|
|
a23dcf0a95 | ||
|
|
b0329e3863 | ||
|
|
ede669051b | ||
|
|
02102dd046 | ||
|
|
3d1d674419 |
10
.env.deploy.example
Normal file
@@ -0,0 +1,10 @@
|
||||
# Copy to .env.deploy for local runs: set -a && source .env.deploy && set +a && ./scripts/deploy-talkpro.sh
|
||||
#
|
||||
# Gitea Actions: only this secret is required (Settings → Secrets → Actions):
|
||||
# TALKPRO_SSH_PRIVATE_KEY = full PEM file contents
|
||||
# Host/user/path defaults are in .gitea/workflows/deploy-talkpro.yml
|
||||
|
||||
TALKPRO_HOST=13.214.179.69
|
||||
TALKPRO_USER=ubuntu
|
||||
TALKPRO_REMOTE_ROOT=/home/ubuntu/talkpro
|
||||
TALKPRO_SSH_KEY_FILE=/absolute/path/to/luis-only.pem
|
||||
57
.gitea/workflows/deploy-talkpro.yml
Normal file
@@ -0,0 +1,57 @@
|
||||
# Build talk-pro and rsync dist/ to the marketing VPS (talkpro.info).
|
||||
#
|
||||
# Required Gitea repo secret (Settings → Secrets → Actions):
|
||||
# TALKPRO_SSH_PRIVATE_KEY full PEM for ubuntu@talkpro (same as luis-only.pem)
|
||||
#
|
||||
# Host/user/path defaults are in the `env:` block below (edit there if needed).
|
||||
#
|
||||
# Requires a runner with: node 22+, ssh, ssh-keyscan, tar (rsync optional; no sudo needed).
|
||||
|
||||
name: Deploy to talkpro
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
TALKPRO_HOST: "13.214.179.69"
|
||||
TALKPRO_USER: ubuntu
|
||||
TALKPRO_REMOTE_ROOT: /home/ubuntu/talkpro
|
||||
|
||||
jobs:
|
||||
build-and-sync:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "22"
|
||||
cache: npm
|
||||
|
||||
- name: Check deploy secrets
|
||||
env:
|
||||
TALKPRO_SSH_PRIVATE_KEY: ${{ secrets.TALKPRO_SSH_PRIVATE_KEY }}
|
||||
run: |
|
||||
if [ -z "${TALKPRO_SSH_PRIVATE_KEY}" ]; then
|
||||
echo "ERROR: Missing Gitea secret TALKPRO_SSH_PRIVATE_KEY"
|
||||
echo "Add it under Repository → Settings → Secrets (Actions)."
|
||||
echo "Value: full contents of your ubuntu@talkpro SSH private key (PEM)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Trust host key
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
chmod 700 ~/.ssh
|
||||
ssh-keyscan -H "$TALKPRO_HOST" >> ~/.ssh/known_hosts 2>/dev/null || true
|
||||
|
||||
- name: Build and deploy to talkpro
|
||||
env:
|
||||
TALKPRO_SSH_PRIVATE_KEY: ${{ secrets.TALKPRO_SSH_PRIVATE_KEY }}
|
||||
run: bash scripts/deploy-talkpro.sh
|
||||
2
.gitignore
vendored
@@ -5,3 +5,5 @@ dist/
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.deploy.example
|
||||
.env.deploy
|
||||
|
||||
59
README.md
@@ -26,6 +26,28 @@ Open [http://localhost:4321](http://localhost:4321)
|
||||
| `npm run build` | Build for production into `dist/` |
|
||||
| `npm run preview` | Preview production build locally |
|
||||
|
||||
## Deploy (Gitea Actions → talkpro.info)
|
||||
|
||||
Pushes to **`main`** or **`master`** run [`.gitea/workflows/deploy-talkpro.yml`](.gitea/workflows/deploy-talkpro.yml): `npm ci` → `npm run build` → `rsync` `dist/` to the marketing server (`/home/ubuntu/talkpro`).
|
||||
|
||||
**Repository secret** (Gitea → Settings → Secrets → Actions) — **required**:
|
||||
|
||||
| Secret | Value |
|
||||
|--------|--------|
|
||||
| `TALKPRO_SSH_PRIVATE_KEY` | Full PEM text of the `ubuntu@talkpro` deploy key |
|
||||
|
||||
Host (`13.214.179.69`), user (`ubuntu`), and web root (`/home/ubuntu/talkpro`) are set in the workflow. Optional secrets `TALKPRO_HOST`, `TALKPRO_USER`, `TALKPRO_REMOTE_ROOT` override those defaults.
|
||||
|
||||
Manual deploy from this repo:
|
||||
|
||||
```bash
|
||||
cp .env.deploy.example .env.deploy # edit paths
|
||||
set -a && source .env.deploy && set +a
|
||||
bash scripts/deploy-talkpro.sh
|
||||
```
|
||||
|
||||
`/api/site-links` (APK / App Store URLs) is still updated via the parent **talkpro** repo: `./scripts/post-talkpro-site-links.sh` on your laptop.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
@@ -72,6 +94,41 @@ Figma assets are stored in `public/assets/`. To re-download them (valid for 7 da
|
||||
bash scripts/download-assets.sh
|
||||
```
|
||||
|
||||
## Cloudflare Cache & the `site-links-client.js` Version Flag
|
||||
|
||||
The site is proxied through **Cloudflare**, which aggressively caches static files. Astro's built CSS/JS bundles are safe because they get **content-hashed filenames** on every build (e.g. `_astro/index.Bx3kF9.js`) — Cloudflare never has an old copy because the filename itself changes.
|
||||
|
||||
`public/site-links-client.js` is the exception. It lives in `public/` so it always deploys to the same URL (`/site-links-client.js`). Cloudflare caches this URL and will keep serving the old version until either:
|
||||
|
||||
- The Cloudflare cache is **purged** (Caching → Purge Everything in the dashboard), or
|
||||
- The script URL is **versioned** so Cloudflare treats it as a new file.
|
||||
|
||||
The URL is versioned in `src/layouts/Base.astro`:
|
||||
|
||||
```html
|
||||
<script src="/site-links-client.js?v=2" defer></script>
|
||||
```
|
||||
|
||||
**Every time you change `site-links-client.js`**, bump this number (`?v=2` → `?v=3`, etc.) and redeploy. Cloudflare will fetch the latest file immediately without needing a cache purge.
|
||||
|
||||
| Change type | Cache action needed |
|
||||
|---|---|
|
||||
| CSS / Astro component change | None — hashed filename handles it |
|
||||
| `site-links-client.js` change | Bump `?v=N` in `Base.astro` and redeploy |
|
||||
| Emergency full reset | Cloudflare dashboard → Caching → Purge Everything |
|
||||
|
||||
## i18n — Adding or Updating Translations
|
||||
|
||||
All page copy lives in `src/i18n/translations.ts`. The English (`en`) entry is the base — every other language only needs to override the keys it wants to change; missing keys fall back to English automatically.
|
||||
|
||||
Supported languages: `en`, `zh-cn`, `zh-tw`, `es`, `vi`, `pt`, `de`, `fr`, `hi`, `ar`, `ru`, `id`, `ur`, `ja`, `ko`, `ms`.
|
||||
|
||||
To add a new language:
|
||||
1. Add the locale code to the `languages` array at the top of `translations.ts`.
|
||||
2. Add its label to `languageLabels` and `languageNames`.
|
||||
3. Add a translation object under `translations` (only the keys you want to override are required).
|
||||
4. Create the page route: copy `src/pages/[lang]/index.astro` if it doesn't exist.
|
||||
|
||||
## Design Source
|
||||
|
||||
Figma: [Talk Pro — Home Page Desktop](https://www.figma.com/design/Gb8WMJ2RLlcZ0bigoiOQx9/Talk-Pro?node-id=9333-31390)
|
||||
Figma: [Talk Pro — Home Page Desktop](https://www.figma.com/design/Gb8WMJ2RLlcZ0bigoiOQx9/Talk-Pro?node-id=9505-537&m=dev)
|
||||
|
||||
BIN
public/assets/core-halftone-bg.png
Normal file
|
After Width: | Height: | Size: 4.6 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
BIN
public/assets/core-icon-groups.png
Normal file
|
After Width: | Height: | Size: 414 KiB |
BIN
public/assets/core-icon-media.png
Normal file
|
After Width: | Height: | Size: 386 KiB |
BIN
public/assets/core-icon-private.png
Normal file
|
After Width: | Height: | Size: 316 KiB |
BIN
public/assets/core-icon-video.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/assets/core-icon-voice.png
Normal file
|
After Width: | Height: | Size: 473 KiB |
13
public/assets/cta-android-icon.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_9846_29800)">
|
||||
<path d="M3.79923 9.12891H3.7275C2.80804 9.12891 2.05835 9.88098 2.05835 10.7981V18.0653C2.05835 18.986 2.80804 19.7356 3.7275 19.7356H3.80045C4.71991 19.7356 5.4696 18.9835 5.4696 18.0653V10.798C5.46838 9.88098 4.71753 9.12891 3.79923 9.12891Z" fill="white"/>
|
||||
<path d="M6.26831 20.8732C6.26831 21.7173 6.95819 22.4048 7.80233 22.4048H9.4416V26.3302C9.4416 27.252 10.1937 28.0017 11.1108 28.0017H11.1825C12.1032 28.0017 12.854 27.2509 12.854 26.3302V22.4048H15.1449V26.3302C15.1449 27.252 15.8994 28.0017 16.8165 28.0017H16.887C17.8077 28.0017 18.5573 27.2509 18.5573 26.3302V22.4048H20.1978C21.0407 22.4048 21.7306 21.7173 21.7306 20.8732V9.39844H6.26831V20.8732Z" fill="white"/>
|
||||
<path d="M17.8506 2.43795L19.1527 0.428069C19.2364 0.301301 19.1993 0.127973 19.0714 0.045438C18.9447 -0.0382608 18.7713 -0.00356184 18.6887 0.126753L17.3389 2.20603C16.3262 1.79114 15.1951 1.558 14.0006 1.558C12.8049 1.558 11.6762 1.79114 10.6611 2.20603L9.3136 0.126753C9.23112 -0.00356184 9.05651 -0.0382608 8.92858 0.045438C8.80065 0.127917 8.76357 0.301301 8.84727 0.428069L10.1505 2.43795C7.80103 3.58939 6.2168 5.75951 6.2168 8.24886C6.2168 8.4019 6.22639 8.55256 6.23952 8.70199H21.7628C21.7759 8.55256 21.7843 8.4019 21.7843 8.24886C21.7843 5.75951 20.1989 3.58939 17.8506 2.43795ZM10.4016 6.03688C9.98912 6.03688 9.65432 5.70447 9.65432 5.2908C9.65432 4.87713 9.98912 4.54588 10.4016 4.54588C10.8165 4.54588 11.1489 4.87707 11.1489 5.2908C11.1489 5.70453 10.8141 6.03688 10.4016 6.03688ZM17.5983 6.03688C17.1858 6.03688 16.851 5.70447 16.851 5.2908C16.851 4.87713 17.1858 4.54588 17.5983 4.54588C18.012 4.54588 18.3444 4.87707 18.3444 5.2908C18.3444 5.70447 18.012 6.03688 17.5983 6.03688Z" fill="white"/>
|
||||
<path d="M24.2714 9.12891H24.2021C23.2826 9.12891 22.5305 9.88098 22.5305 10.7981V18.0653C22.5305 18.986 23.2838 19.7356 24.2021 19.7356H24.2726C25.1932 19.7356 25.9418 18.9835 25.9418 18.0653V10.798C25.9418 9.88098 25.1909 9.12891 24.2714 9.12891Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_9846_29800">
|
||||
<rect width="28" height="28" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
339
public/assets/cta-bg-pattern.svg
Normal file
@@ -0,0 +1,339 @@
|
||||
<svg preserveAspectRatio="xMidYMid slice" width="1920" height="923" overflow="visible" style="display: block;" viewBox="0 0 1920 923" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Layer_1" clip-path="url(#clip0_0_4)">
|
||||
<path id="Vector" d="M12.1851 -29.997L0.00488281 -17.7969L12.1851 -5.59676L24.3653 -17.7969L12.1851 -29.997Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_2" d="M102.45 -30.0001L90.2725 -17.7969L102.45 -5.59361L114.627 -17.7969L102.45 -30.0001Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_3" d="M192.717 -30.0001L180.54 -17.7969L192.717 -5.59361L204.894 -17.7969L192.717 -30.0001Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_4" d="M282.985 -30.0001L270.808 -17.7969L282.985 -5.59361L295.162 -17.7969L282.985 -30.0001Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_5" d="M373.252 -30.0001L361.075 -17.7969L373.252 -5.59361L385.429 -17.7969L373.252 -30.0001Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_6" d="M463.519 -30.0001L451.342 -17.7969L463.519 -5.59361L475.696 -17.7969L463.519 -30.0001Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_7" d="M553.787 -29.9894L541.61 -17.7861L553.787 -5.58287L565.964 -17.7861L553.787 -29.9894Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_8" d="M644.065 -29.9894L631.888 -17.7861L644.065 -5.58287L656.242 -17.7862L644.065 -29.9894Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_9" d="M734.329 -29.9972L722.152 -17.7939L734.329 -5.59068L746.506 -17.7939L734.329 -29.9972Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_10" d="M824.607 -29.9972L812.43 -17.7939L824.607 -5.59068L836.784 -17.7939L824.607 -29.9972Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_11" d="M914.875 -29.9972L902.698 -17.7939L914.875 -5.59068L927.052 -17.794L914.875 -29.9972Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_12" d="M1005.14 -29.9972L992.965 -17.7939L1005.14 -5.59068L1017.32 -17.7939L1005.14 -29.9972Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_13" d="M1095.4 -29.9973L1083.22 -17.7939L1095.4 -5.59068L1107.58 -17.794L1095.4 -29.9973Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_14" d="M1185.68 -29.9972L1173.5 -17.7939L1185.68 -5.59068L1197.85 -17.7939L1185.68 -29.9972Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_15" d="M1275.94 -29.9972L1263.77 -17.7939L1275.94 -5.59068L1288.12 -17.7939L1275.94 -29.9972Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_16" d="M1366.22 -29.9943L1354.04 -17.791L1366.22 -5.58775L1378.4 -17.791L1366.22 -29.9943Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_17" d="M1456.49 -29.9934L1444.31 -17.79L1456.49 -5.58677L1468.66 -17.7901L1456.49 -29.9934Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_18" d="M1546.75 -30.0001L1534.57 -17.7969L1546.75 -5.59358L1558.93 -17.7968L1546.75 -30.0001Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_19" d="M1637.02 -29.9973L1624.84 -17.7939L1637.02 -5.59075L1649.2 -17.7941L1637.02 -29.9973Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_20" d="M1727.29 -29.9982L1715.11 -17.7949L1727.29 -5.59163L1739.46 -17.7949L1727.29 -29.9982Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_21" d="M1817.56 -29.9953L1805.38 -17.792L1817.56 -5.58873L1829.73 -17.792L1817.56 -29.9953Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_22" d="M1907.82 -29.9952L1895.65 -17.792L1907.82 -5.58872L1920 -17.792L1907.82 -29.9952Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_23" d="M12.1871 44.9044L0.00683594 57.1045L12.1871 69.3046L24.3673 57.1045L12.1871 44.9044Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_24" d="M102.451 44.9012L90.2744 57.1045L102.451 69.3078L114.629 57.1045L102.451 44.9012Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_25" d="M192.718 44.9012L180.541 57.1045L192.718 69.3078L204.895 57.1045L192.718 44.9012Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_26" d="M282.987 44.9012L270.81 57.1045L282.987 69.3078L295.164 57.1045L282.987 44.9012Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_27" d="M373.253 44.9012L361.076 57.1045L373.253 69.3078L385.43 57.1045L373.253 44.9012Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_28" d="M463.521 44.9012L451.344 57.1045L463.521 69.3078L475.698 57.1045L463.521 44.9012Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_29" d="M553.789 44.9012L541.612 57.1045L553.789 69.3078L565.966 57.1045L553.789 44.9012Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_30" d="M644.056 44.911L631.879 57.1143L644.056 69.3175L656.233 57.1142L644.056 44.911Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_31" d="M734.33 44.8934L722.153 57.0967L734.33 69.2999L746.507 57.0967L734.33 44.8934Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_32" d="M824.598 44.9042L812.421 57.1074L824.598 69.3107L836.775 57.1074L824.598 44.9042Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_33" d="M914.876 44.9041L902.699 57.1074L914.876 69.3107L927.053 57.1074L914.876 44.9041Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_34" d="M1005.14 44.9042L992.967 57.1074L1005.14 69.3107L1017.32 57.1074L1005.14 44.9042Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_35" d="M1095.4 44.9041L1083.22 57.1074L1095.4 69.3107L1107.58 57.1074L1095.4 44.9041Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_36" d="M1185.68 44.9042L1173.5 57.1074L1185.68 69.3107L1197.86 57.1074L1185.68 44.9042Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_37" d="M1275.95 44.9042L1263.77 57.1074L1275.95 69.3107L1288.12 57.1074L1275.95 44.9042Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_38" d="M1366.22 44.8973L1354.04 57.1006L1366.22 69.3038L1378.4 57.1006L1366.22 44.8973Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_39" d="M1456.48 44.9002L1444.31 57.1035L1456.48 69.3068L1468.66 57.1034L1456.48 44.9002Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_40" d="M1546.75 44.8993L1534.57 57.1026L1546.75 69.3058L1558.93 57.1026L1546.75 44.8993Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_41" d="M1637.02 44.9021L1624.84 57.1055L1637.02 69.3087L1649.2 57.1053L1637.02 44.9021Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_42" d="M1727.29 44.9012L1715.11 57.1045L1727.29 69.3078L1739.46 57.1045L1727.29 44.9012Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_43" d="M1817.56 44.9042L1805.38 57.1074L1817.56 69.3107L1829.73 57.1074L1817.56 44.9042Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_44" d="M1907.82 44.9051L1895.65 57.1084L1907.82 69.3117L1920 57.1084L1907.82 44.9051Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_45" d="M12.189 119.805L0.00878906 132.005L12.189 144.205L24.3692 132.005L12.189 119.805Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_46" d="M102.452 119.802L90.2754 132.005L102.452 144.208L114.63 132.005L102.452 119.802Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_47" d="M192.72 119.802L180.543 132.005L192.72 144.208L204.897 132.005L192.72 119.802Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_48" d="M282.989 119.802L270.812 132.005L282.989 144.208L295.166 132.005L282.989 119.802Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_49" d="M373.255 119.802L361.078 132.005L373.255 144.208L385.432 132.005L373.255 119.802Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_50" d="M463.523 119.802L451.346 132.005L463.523 144.208L475.7 132.005L463.523 119.802Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_51" d="M553.79 119.802L541.613 132.005L553.79 144.208L565.967 132.005L553.79 119.802Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_52" d="M644.058 119.802L631.881 132.005L644.058 144.208L656.235 132.005L644.058 119.802Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_53" d="M734.332 119.795L722.155 131.998L734.332 144.201L746.509 131.998L734.332 119.795Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_54" d="M824.6 119.805L812.423 132.008L824.6 144.211L836.777 132.008L824.6 119.805Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_55" d="M914.868 119.805L902.69 132.008L914.867 144.211L927.045 132.008L914.868 119.805Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_56" d="M1005.14 119.805L992.958 132.008L1005.14 144.211L1017.31 132.008L1005.14 119.805Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_57" d="M1095.4 119.795L1083.23 131.998L1095.4 144.201L1107.58 131.998L1095.4 119.795Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_58" d="M1185.68 119.805L1173.5 132.008L1185.68 144.211L1197.86 132.008L1185.68 119.805Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_59" d="M1275.95 119.805L1263.77 132.008L1275.95 144.211L1288.13 132.008L1275.95 119.805Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_60" d="M1366.22 119.798L1354.05 132.001L1366.22 144.204L1378.4 132.001L1366.22 119.798Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_61" d="M1456.48 119.8L1444.31 132.003L1456.48 144.206L1468.66 132.003L1456.48 119.8Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_62" d="M1546.75 119.798L1534.57 132.001L1546.75 144.204L1558.93 132.001L1546.75 119.798Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_63" d="M1637.02 119.802L1624.84 132.005L1637.02 144.208L1649.2 132.005L1637.02 119.802Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_64" d="M1727.29 119.8L1715.11 132.003L1727.29 144.206L1739.46 132.003L1727.29 119.8Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_65" d="M1817.56 119.804L1805.38 132.007L1817.56 144.21L1829.73 132.007L1817.56 119.804Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_66" d="M1907.82 119.805L1895.65 132.008L1907.82 144.211L1920 132.008L1907.82 119.805Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_67" d="M12.191 194.695L0.0107422 206.896L12.191 219.096L24.3712 206.896L12.191 194.695Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_68" d="M102.454 194.703L90.2773 206.906L102.454 219.109L114.631 206.906L102.454 194.703Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_69" d="M192.722 194.703L180.545 206.906L192.722 219.109L204.899 206.906L192.722 194.703Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_70" d="M282.991 194.703L270.813 206.906L282.991 219.109L295.168 206.906L282.991 194.703Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_71" d="M373.257 194.703L361.08 206.906L373.257 219.109L385.434 206.906L373.257 194.703Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_72" d="M463.525 194.703L451.348 206.906L463.525 219.109L475.702 206.906L463.525 194.703Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_73" d="M553.792 194.703L541.615 206.906L553.792 219.109L565.969 206.906L553.792 194.703Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_74" d="M644.06 194.703L631.883 206.906L644.06 219.109L656.237 206.906L644.06 194.703Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_75" d="M734.334 194.696L722.157 206.899L734.334 219.103L746.511 206.899L734.334 194.696Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_76" d="M824.602 194.696L812.425 206.899L824.602 219.103L836.779 206.899L824.602 194.696Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_77" d="M914.869 194.706L902.692 206.909L914.869 219.112L927.047 206.909L914.869 194.706Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_78" d="M1005.14 194.706L992.96 206.909L1005.14 219.112L1017.31 206.909L1005.14 194.706Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_79" d="M1095.4 194.696L1083.23 206.899L1095.4 219.103L1107.58 206.899L1095.4 194.696Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_80" d="M1185.67 194.706L1173.49 206.909L1185.67 219.112L1197.85 206.909L1185.67 194.706Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_81" d="M1275.94 194.706L1263.76 206.909L1275.94 219.112L1288.12 206.909L1275.94 194.706Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_82" d="M1366.21 194.699L1354.04 206.902L1366.21 219.106L1378.39 206.902L1366.21 194.699Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_83" d="M1456.48 194.699L1444.31 206.902L1456.48 219.106L1468.66 206.902L1456.48 194.699Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_84" d="M1546.75 194.697L1534.57 206.9L1546.75 219.104L1558.93 206.9L1546.75 194.697Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_85" d="M1637.02 194.701L1624.84 206.904L1637.02 219.107L1649.2 206.904L1637.02 194.701Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_86" d="M1727.29 194.699L1715.11 206.902L1727.29 219.106L1739.46 206.902L1727.29 194.699Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_87" d="M1817.56 194.703L1805.38 206.906L1817.56 219.109L1829.73 206.906L1817.56 194.703Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_88" d="M1907.82 194.704L1895.65 206.907L1907.82 219.11L1920 206.907L1907.82 194.704Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_89" d="M12.1822 269.597L0.00195312 281.797L12.1822 293.997L24.3624 281.797L12.1822 269.597Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_90" d="M102.446 269.594L90.2686 281.797L102.446 294L114.623 281.797L102.446 269.594Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_91" d="M192.724 269.604L180.547 281.808L192.724 294.011L204.901 281.808L192.724 269.604Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_92" d="M282.992 269.604L270.814 281.808L282.992 294.011L295.169 281.808L282.992 269.604Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_93" d="M373.259 269.604L361.082 281.808L373.259 294.011L385.436 281.808L373.259 269.604Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_94" d="M463.526 269.604L451.349 281.808L463.526 294.011L475.703 281.808L463.526 269.604Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_95" d="M553.794 269.604L541.617 281.808L553.794 294.011L565.971 281.808L553.794 269.604Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_96" d="M644.062 269.604L631.885 281.808L644.062 294.011L656.239 281.808L644.062 269.604Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_97" d="M734.336 269.597L722.159 281.8L734.336 294.003L746.513 281.8L734.336 269.597Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_98" d="M824.603 269.597L812.426 281.8L824.603 294.003L836.78 281.8L824.603 269.597Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_99" d="M914.871 269.596L902.694 281.8L914.871 294.003L927.049 281.8L914.871 269.596Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_100" d="M1005.14 269.597L992.962 281.8L1005.14 294.003L1017.32 281.8L1005.14 269.597Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_101" d="M1095.41 269.596L1083.23 281.8L1095.41 294.003L1107.58 281.8L1095.41 269.596Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_102" d="M1185.67 269.607L1173.5 281.811L1185.67 294.014L1197.85 281.811L1185.67 269.607Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_103" d="M1275.94 269.607L1263.76 281.811L1275.94 294.014L1288.12 281.811L1275.94 269.607Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_104" d="M1366.22 269.598L1354.04 281.801L1366.22 294.004L1378.39 281.801L1366.22 269.598Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_105" d="M1456.48 269.598L1444.31 281.802L1456.48 294.005L1468.66 281.802L1456.48 269.598Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_106" d="M1546.75 269.597L1534.57 281.8L1546.75 294.003L1558.93 281.8L1546.75 269.597Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_107" d="M1637.02 269.6L1624.84 281.804L1637.02 294.007L1649.2 281.804L1637.02 269.6Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_108" d="M1727.29 269.598L1715.11 281.802L1727.29 294.005L1739.46 281.802L1727.29 269.598Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_109" d="M1817.56 269.602L1805.38 281.806L1817.56 294.009L1829.73 281.806L1817.56 269.602Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_110" d="M1907.82 269.603L1895.65 281.807L1907.82 294.01L1920 281.807L1907.82 269.603Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_111" d="M12.1841 344.498L0.00390625 356.698L12.1841 368.898L24.3644 356.698L12.1841 344.498Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_112" d="M102.448 344.495L90.2705 356.698L102.448 368.901L114.625 356.698L102.448 344.495Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_113" d="M192.716 344.495L180.539 356.698L192.716 368.901L204.893 356.698L192.716 344.495Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_114" d="M282.983 344.495L270.806 356.698L282.983 368.901L295.16 356.698L282.983 344.495Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_115" d="M373.25 344.495L361.073 356.698L373.25 368.901L385.427 356.698L373.25 344.495Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_116" d="M463.528 344.505L451.351 356.708L463.528 368.911L475.705 356.708L463.528 344.505Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_117" d="M553.796 344.505L541.619 356.708L553.796 368.911L565.973 356.708L553.796 344.505Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_118" d="M644.063 344.505L631.886 356.708L644.063 368.911L656.24 356.708L644.063 344.505Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_119" d="M734.338 344.498L722.161 356.701L734.338 368.904L746.515 356.701L734.338 344.498Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_120" d="M824.605 344.498L812.428 356.701L824.605 368.904L836.782 356.701L824.605 344.498Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_121" d="M914.873 344.498L902.696 356.701L914.873 368.904L927.05 356.701L914.873 344.498Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_122" d="M1005.14 344.498L992.964 356.701L1005.14 368.904L1017.32 356.701L1005.14 344.498Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_123" d="M1095.41 344.498L1083.23 356.701L1095.41 368.904L1107.58 356.701L1095.41 344.498Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_124" d="M1185.68 344.508L1173.5 356.711L1185.68 368.914L1197.85 356.711L1185.68 344.508Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_125" d="M1275.94 344.508L1263.77 356.711L1275.94 368.914L1288.12 356.711L1275.94 344.508Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_126" d="M1366.22 344.497L1354.04 356.7L1366.22 368.904L1378.39 356.7L1366.22 344.497Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_127" d="M1456.48 344.498L1444.31 356.701L1456.48 368.904L1468.66 356.701L1456.48 344.498Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_128" d="M1546.75 344.496L1534.57 356.699L1546.75 368.902L1558.93 356.699L1546.75 344.496Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_129" d="M1637.02 344.499L1624.84 356.702L1637.02 368.905L1649.2 356.702L1637.02 344.499Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_130" d="M1727.29 344.498L1715.11 356.701L1727.29 368.904L1739.46 356.701L1727.29 344.498Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_131" d="M1817.56 344.501L1805.38 356.704L1817.56 368.907L1829.73 356.704L1817.56 344.501Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_132" d="M1907.82 344.503L1895.65 356.706L1907.82 368.909L1920 356.706L1907.82 344.503Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_133" d="M12.1851 419.399L0.00488281 431.599L12.1851 443.799L24.3653 431.599L12.1851 419.399Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_134" d="M102.45 419.396L90.2725 431.599L102.45 443.802L114.627 431.599L102.45 419.396Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_135" d="M192.718 419.396L180.541 431.599L192.718 443.802L204.895 431.599L192.718 419.396Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_136" d="M282.985 419.396L270.808 431.599L282.985 443.802L295.162 431.599L282.985 419.396Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_137" d="M373.252 419.396L361.075 431.599L373.252 443.802L385.429 431.599L373.252 419.396Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_138" d="M463.519 419.406L451.342 431.609L463.519 443.813L475.696 431.609L463.519 419.406Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_139" d="M553.787 419.406L541.61 431.609L553.787 443.813L565.964 431.609L553.787 419.406Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_140" d="M644.054 419.406L631.877 431.609L644.054 443.813L656.231 431.609L644.054 419.406Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_141" d="M734.329 419.398L722.152 431.602L734.329 443.805L746.506 431.602L734.329 419.398Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_142" d="M824.607 419.398L812.43 431.602L824.607 443.805L836.784 431.602L824.607 419.398Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_143" d="M914.875 419.398L902.698 431.602L914.875 443.805L927.052 431.602L914.875 419.398Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_144" d="M1005.14 419.398L992.965 431.602L1005.14 443.805L1017.32 431.602L1005.14 419.398Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_145" d="M1095.4 419.398L1083.22 431.602L1095.4 443.805L1107.58 431.602L1095.4 419.398Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_146" d="M1185.68 419.398L1173.5 431.602L1185.68 443.805L1197.85 431.602L1185.68 419.398Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_147" d="M1275.94 419.409L1263.77 431.612L1275.94 443.816L1288.12 431.612L1275.94 419.409Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_148" d="M1366.22 419.396L1354.04 431.599L1366.22 443.802L1378.39 431.599L1366.22 419.396Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_149" d="M1456.48 419.396L1444.31 431.6L1456.48 443.803L1468.66 431.599L1456.48 419.396Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_150" d="M1546.75 419.396L1534.57 431.599L1546.75 443.802L1558.93 431.599L1546.75 419.396Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_151" d="M1637.02 419.398L1624.84 431.602L1637.02 443.805L1649.2 431.601L1637.02 419.398Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_152" d="M1727.29 419.397L1715.11 431.601L1727.29 443.804L1739.46 431.601L1727.29 419.397Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_153" d="M1817.56 419.401L1805.38 431.605L1817.56 443.808L1829.73 431.605L1817.56 419.401Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_154" d="M1907.82 419.402L1895.65 431.605L1907.82 443.809L1920 431.605L1907.82 419.402Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_155" d="M12.1871 494.3L0.00683594 506.5L12.1871 518.7L24.3673 506.5L12.1871 494.3Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_156" d="M102.451 494.297L90.2744 506.5L102.452 518.703L114.629 506.5L102.451 494.297Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_157" d="M192.718 494.297L180.541 506.5L192.718 518.703L204.895 506.5L192.718 494.297Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_158" d="M282.987 494.297L270.81 506.5L282.987 518.703L295.164 506.5L282.987 494.297Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_159" d="M373.254 494.297L361.077 506.5L373.254 518.703L385.431 506.5L373.254 494.297Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_160" d="M463.521 494.297L451.344 506.5L463.521 518.703L475.698 506.5L463.521 494.297Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_161" d="M553.789 494.297L541.612 506.5L553.789 518.703L565.966 506.5L553.789 494.297Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_162" d="M644.056 494.308L631.879 506.511L644.056 518.714L656.233 506.511L644.056 494.308Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_163" d="M734.331 494.289L722.154 506.492L734.331 518.696L746.508 506.492L734.331 494.289Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_164" d="M824.598 494.3L812.421 506.503L824.598 518.706L836.775 506.503L824.598 494.3Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_165" d="M914.867 494.3L902.689 506.503L914.867 518.706L927.044 506.503L914.867 494.3Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_166" d="M1005.13 494.3L992.956 506.503L1005.13 518.706L1017.31 506.503L1005.13 494.3Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_167" d="M1095.4 494.3L1083.22 506.503L1095.4 518.706L1107.58 506.503L1095.4 494.3Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_168" d="M1185.68 494.3L1173.5 506.503L1185.68 518.706L1197.86 506.503L1185.68 494.3Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_169" d="M1275.94 494.302L1263.76 506.505L1275.94 518.708L1288.12 506.505L1275.94 494.302Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_170" d="M1366.22 494.295L1354.04 506.498L1366.22 518.701L1378.39 506.498L1366.22 494.295Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_171" d="M1456.48 494.296L1444.31 506.499L1456.48 518.702L1468.66 506.499L1456.48 494.296Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_172" d="M1546.75 494.295L1534.57 506.498L1546.75 518.701L1558.93 506.498L1546.75 494.295Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_173" d="M1637.02 494.299L1624.84 506.502L1637.02 518.705L1649.2 506.502L1637.02 494.299Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_174" d="M1727.29 494.297L1715.11 506.5L1727.29 518.703L1739.46 506.5L1727.29 494.297Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_175" d="M1817.56 494.301L1805.38 506.504L1817.56 518.707L1829.73 506.504L1817.56 494.301Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_176" d="M1907.82 494.302L1895.65 506.505L1907.82 518.708L1920 506.505L1907.82 494.302Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_177" d="M12.189 569.201L0.00878906 581.401L12.189 593.601L24.3693 581.401L12.189 569.201Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_178" d="M102.453 569.198L90.2764 581.401L102.453 593.605L114.631 581.401L102.453 569.198Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_179" d="M192.72 569.198L180.543 581.401L192.72 593.605L204.897 581.401L192.72 569.198Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_180" d="M282.989 569.198L270.812 581.401L282.989 593.605L295.166 581.401L282.989 569.198Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_181" d="M373.255 569.198L361.078 581.401L373.255 593.605L385.432 581.401L373.255 569.198Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_182" d="M463.523 569.198L451.346 581.401L463.523 593.605L475.7 581.401L463.523 569.198Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_183" d="M553.791 569.198L541.614 581.401L553.791 593.605L565.968 581.401L553.791 569.198Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_184" d="M644.058 569.198L631.881 581.401L644.058 593.605L656.235 581.401L644.058 569.198Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_185" d="M734.332 569.19L722.155 581.393L734.332 593.597L746.509 581.394L734.332 569.19Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_186" d="M824.6 569.201L812.423 581.404L824.6 593.608L836.777 581.404L824.6 569.201Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_187" d="M914.869 569.201L902.691 581.404L914.869 593.608L927.046 581.404L914.869 569.201Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_188" d="M1005.14 569.201L992.958 581.404L1005.14 593.608L1017.31 581.404L1005.14 569.201Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_189" d="M1095.4 569.19L1083.23 581.393L1095.4 593.597L1107.58 581.393L1095.4 569.19Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_190" d="M1185.67 569.201L1173.49 581.404L1185.67 593.608L1197.85 581.404L1185.67 569.201Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_191" d="M1275.94 569.201L1263.76 581.404L1275.94 593.608L1288.12 581.404L1275.94 569.201Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_192" d="M1366.22 569.194L1354.04 581.398L1366.22 593.601L1378.39 581.398L1366.22 569.194Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_193" d="M1456.48 569.195L1444.31 581.398L1456.48 593.602L1468.66 581.398L1456.48 569.195Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_194" d="M1546.75 569.194L1534.57 581.398L1546.75 593.601L1558.93 581.398L1546.75 569.194Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_195" d="M1637.02 569.198L1624.84 581.401L1637.02 593.605L1649.2 581.401L1637.02 569.198Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_196" d="M1727.29 569.196L1715.11 581.399L1727.29 593.603L1739.46 581.399L1727.29 569.196Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_197" d="M1817.56 569.2L1805.38 581.403L1817.56 593.607L1829.73 581.403L1817.56 569.2Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_198" d="M1907.82 569.201L1895.65 581.404L1907.82 593.608L1920 581.404L1907.82 569.201Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_199" d="M12.191 644.092L0.0107422 656.292L12.191 668.492L24.3712 656.292L12.191 644.092Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_200" d="M102.454 644.098L90.2773 656.302L102.454 668.505L114.632 656.302L102.454 644.098Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_201" d="M192.722 644.098L180.545 656.302L192.722 668.505L204.899 656.302L192.722 644.098Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_202" d="M282.991 644.098L270.813 656.302L282.991 668.505L295.168 656.302L282.991 644.098Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_203" d="M373.257 644.098L361.08 656.302L373.257 668.505L385.434 656.302L373.257 644.098Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_204" d="M463.525 644.098L451.348 656.302L463.525 668.505L475.702 656.302L463.525 644.098Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_205" d="M553.792 644.099L541.615 656.302L553.792 668.505L565.969 656.302L553.792 644.099Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_206" d="M644.06 644.098L631.883 656.302L644.06 668.505L656.237 656.302L644.06 644.098Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_207" d="M734.334 644.091L722.157 656.295L734.334 668.498L746.511 656.295L734.334 644.091Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_208" d="M824.602 644.101L812.425 656.305L824.602 668.508L836.779 656.305L824.602 644.101Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_209" d="M914.869 644.102L902.692 656.306L914.869 668.509L927.047 656.306L914.869 644.102Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_210" d="M1005.14 644.101L992.96 656.305L1005.14 668.508L1017.31 656.305L1005.14 644.101Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_211" d="M1095.4 644.091L1083.23 656.295L1095.4 668.498L1107.58 656.295L1095.4 644.091Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_212" d="M1185.67 644.098L1173.5 656.302L1185.67 668.505L1197.85 656.302L1185.67 644.098Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_213" d="M1275.94 644.099L1263.76 656.303L1275.94 668.506L1288.12 656.303L1275.94 644.099Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_214" d="M1366.22 644.093L1354.04 656.297L1366.22 668.5L1378.39 656.297L1366.22 644.093Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_215" d="M1456.48 644.094L1444.31 656.298L1456.48 668.501L1468.66 656.298L1456.48 644.094Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_216" d="M1546.75 644.093L1534.57 656.296L1546.75 668.499L1558.93 656.296L1546.75 644.093Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_217" d="M1637.02 644.097L1624.84 656.3L1637.02 668.503L1649.2 656.3L1637.02 644.097Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_218" d="M1727.29 644.094L1715.11 656.298L1727.29 668.501L1739.46 656.298L1727.29 644.094Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_219" d="M1817.56 644.098L1805.38 656.302L1817.56 668.505L1829.73 656.302L1817.56 644.098Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_220" d="M1907.82 644.099L1895.65 656.303L1907.82 668.506L1920 656.303L1907.82 644.099Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_221" d="M12.1822 718.993L0.00195312 731.193L12.1822 743.394L24.3624 731.194L12.1822 718.993Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_222" d="M102.447 718.99L90.2695 731.193L102.447 743.397L114.624 731.194L102.447 718.99Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_223" d="M192.714 719L180.537 731.203L192.714 743.406L204.891 731.203L192.714 719Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_224" d="M282.992 719L270.814 731.203L282.992 743.406L295.169 731.203L282.992 719Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_225" d="M373.259 719L361.082 731.203L373.259 743.406L385.436 731.203L373.259 719Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_226" d="M463.527 719L451.35 731.203L463.527 743.406L475.704 731.203L463.527 719Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_227" d="M553.794 719L541.617 731.203L553.794 743.406L565.971 731.203L553.794 719Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_228" d="M644.062 719L631.885 731.203L644.062 743.406L656.239 731.203L644.062 719Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_229" d="M734.336 718.992L722.159 731.195L734.336 743.399L746.513 731.195L734.336 718.992Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_230" d="M824.604 718.992L812.427 731.195L824.604 743.399L836.781 731.195L824.604 718.992Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_231" d="M914.871 718.992L902.694 731.195L914.871 743.399L927.049 731.195L914.871 718.992Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_232" d="M1005.14 719.004L992.962 731.207L1005.14 743.41L1017.32 731.207L1005.14 719.004Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_233" d="M1095.41 718.992L1083.23 731.195L1095.41 743.399L1107.58 731.195L1095.41 718.992Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_234" d="M1185.67 718.998L1173.5 731.201L1185.67 743.405L1197.85 731.201L1185.67 718.998Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_235" d="M1275.94 719L1263.76 731.203L1275.94 743.406L1288.12 731.203L1275.94 719Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_236" d="M1366.22 718.992L1354.04 731.195L1366.22 743.399L1378.39 731.195L1366.22 718.992Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_237" d="M1456.48 718.994L1444.31 731.197L1456.48 743.401L1468.66 731.197L1456.48 718.994Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_238" d="M1546.75 718.992L1534.57 731.195L1546.75 743.399L1558.93 731.195L1546.75 718.992Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_239" d="M1637.02 718.996L1624.84 731.199L1637.02 743.402L1649.2 731.199L1637.02 718.996Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_240" d="M1727.29 718.994L1715.11 731.197L1727.29 743.401L1739.46 731.197L1727.29 718.994Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_241" d="M1817.56 718.998L1805.38 731.201L1817.56 743.405L1829.73 731.201L1817.56 718.998Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_242" d="M1907.82 719L1895.65 731.203L1907.82 743.406L1920 731.203L1907.82 719Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_243" d="M12.1841 793.893L0.00390625 806.093L12.1842 818.293L24.3644 806.093L12.1841 793.893Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_244" d="M102.448 793.89L90.2705 806.093L102.448 818.296L114.625 806.093L102.448 793.89Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_245" d="M192.716 793.89L180.539 806.093L192.716 818.296L204.893 806.093L192.716 793.89Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_246" d="M282.983 793.9L270.806 806.103L282.983 818.307L295.16 806.103L282.983 793.9Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_247" d="M373.25 793.89L361.073 806.093L373.25 818.296L385.427 806.093L373.25 793.89Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_248" d="M463.518 793.9L451.341 806.103L463.518 818.307L475.695 806.103L463.518 793.9Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_249" d="M553.785 793.9L541.608 806.103L553.785 818.307L565.963 806.103L553.785 793.9Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_250" d="M644.064 793.9L631.887 806.103L644.064 818.307L656.241 806.103L644.064 793.9Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_251" d="M734.338 793.893L722.161 806.097L734.338 818.3L746.515 806.097L734.338 793.893Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_252" d="M824.605 793.893L812.428 806.097L824.605 818.3L836.782 806.097L824.605 793.893Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_253" d="M914.873 793.893L902.696 806.097L914.873 818.3L927.05 806.097L914.873 793.893Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_254" d="M1005.14 793.893L992.964 806.097L1005.14 818.3L1017.32 806.097L1005.14 793.893Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_255" d="M1095.41 793.893L1083.23 806.097L1095.41 818.3L1107.58 806.097L1095.41 793.893Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_256" d="M1185.67 793.897L1173.5 806.1L1185.67 818.304L1197.85 806.1L1185.67 793.897Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_257" d="M1275.94 793.898L1263.76 806.102L1275.94 818.305L1288.12 806.102L1275.94 793.898Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_258" d="M1366.22 793.892L1354.04 806.095L1366.22 818.298L1378.39 806.095L1366.22 793.892Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_259" d="M1456.48 793.893L1444.31 806.096L1456.48 818.299L1468.66 806.096L1456.48 793.893Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_260" d="M1546.75 793.891L1534.57 806.094L1546.75 818.297L1558.93 806.094L1546.75 793.891Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_261" d="M1637.02 793.895L1624.84 806.099L1637.02 818.302L1649.2 806.099L1637.02 793.895Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_262" d="M1727.29 793.893L1715.11 806.096L1727.29 818.299L1739.46 806.096L1727.29 793.893Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_263" d="M1817.56 793.897L1805.38 806.1L1817.56 818.304L1829.73 806.1L1817.56 793.897Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_264" d="M1907.82 793.898L1895.65 806.102L1907.82 818.305L1920 806.102L1907.82 793.898Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_265" d="M12.1861 868.794L0.00585938 880.994L12.1861 893.194L24.3663 880.994L12.1861 868.794Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_266" d="M102.45 868.791L90.2725 880.994L102.45 893.197L114.627 880.994L102.45 868.791Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_267" d="M192.718 868.791L180.541 880.994L192.718 893.197L204.895 880.994L192.718 868.791Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_268" d="M282.985 868.791L270.808 880.994L282.985 893.197L295.162 880.994L282.985 868.791Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_269" d="M373.252 868.791L361.075 880.994L373.252 893.197L385.429 880.994L373.252 868.791Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_270" d="M463.52 868.802L451.343 881.005L463.52 893.208L475.697 881.005L463.52 868.802Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_271" d="M553.787 868.802L541.61 881.005L553.787 893.208L565.965 881.005L553.787 868.802Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_272" d="M644.055 868.802L631.878 881.005L644.055 893.208L656.232 881.005L644.055 868.802Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_273" d="M734.329 868.794L722.152 880.997L734.329 893.2L746.506 880.997L734.329 868.794Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_274" d="M824.597 868.794L812.42 880.997L824.597 893.2L836.774 880.997L824.597 868.794Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_275" d="M914.875 868.794L902.698 880.997L914.875 893.2L927.052 880.997L914.875 868.794Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_276" d="M1005.14 868.794L992.965 880.997L1005.14 893.2L1017.32 880.997L1005.14 868.794Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_277" d="M1095.4 868.793L1083.23 880.996L1095.4 893.199L1107.58 880.996L1095.4 868.793Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_278" d="M1185.67 868.797L1173.5 881L1185.67 893.203L1197.85 881L1185.67 868.797Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_279" d="M1275.94 868.798L1263.76 881.001L1275.94 893.204L1288.12 881.001L1275.94 868.798Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_280" d="M1366.22 868.791L1354.04 880.994L1366.22 893.197L1378.39 880.994L1366.22 868.791Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_281" d="M1456.48 868.792L1444.31 880.995L1456.48 893.198L1468.66 880.995L1456.48 868.792Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_282" d="M1546.75 868.79L1534.57 880.993L1546.75 893.196L1558.93 880.993L1546.75 868.79Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_283" d="M1637.02 868.795L1624.84 880.998L1637.02 893.201L1649.2 880.998L1637.02 868.795Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_284" d="M1727.29 868.792L1715.11 880.995L1727.29 893.198L1739.46 880.995L1727.29 868.792Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_285" d="M1817.56 868.797L1805.38 881L1817.56 893.203L1829.73 881L1817.56 868.797Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_286" d="M1907.82 868.798L1895.65 881.001L1907.82 893.204L1920 881.001L1907.82 868.798Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_287" d="M12.1871 943.695L0.00683594 955.896L12.1871 968.096L24.3673 955.896L12.1871 943.695Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_288" d="M102.451 943.692L90.2744 955.896L102.452 968.099L114.629 955.896L102.451 943.692Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_289" d="M192.719 943.692L180.542 955.896L192.719 968.099L204.896 955.896L192.719 943.692Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_290" d="M282.987 943.692L270.81 955.896L282.987 968.099L295.164 955.896L282.987 943.692Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_291" d="M373.254 943.692L361.077 955.896L373.254 968.099L385.431 955.896L373.254 943.692Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_292" d="M463.521 943.692L451.344 955.896L463.521 968.099L475.698 955.896L463.521 943.692Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_293" d="M553.789 943.703L541.612 955.906L553.789 968.109L565.966 955.906L553.789 943.703Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_294" d="M644.056 943.703L631.879 955.906L644.056 968.109L656.233 955.906L644.056 943.703Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_295" d="M734.331 943.684L722.154 955.888L734.331 968.091L746.508 955.888L734.331 943.684Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_296" d="M824.598 943.695L812.421 955.898L824.598 968.102L836.775 955.898L824.598 943.695Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_297" d="M914.867 943.695L902.689 955.898L914.867 968.102L927.044 955.898L914.867 943.695Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_298" d="M1005.13 943.695L992.956 955.898L1005.13 968.102L1017.31 955.898L1005.13 943.695Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_299" d="M1095.41 943.692L1083.23 955.896L1095.41 968.099L1107.58 955.895L1095.41 943.692Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_300" d="M1185.67 943.696L1173.5 955.9L1185.67 968.103L1197.85 955.9L1185.67 943.696Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_301" d="M1275.94 943.697L1263.76 955.9L1275.94 968.104L1288.12 955.9L1275.94 943.697Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_302" d="M1366.22 943.69L1354.04 955.894L1366.22 968.097L1378.39 955.894L1366.22 943.69Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_303" d="M1456.48 943.692L1444.31 955.896L1456.48 968.099L1468.66 955.895L1456.48 943.692Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_304" d="M1546.75 943.689L1534.57 955.893L1546.75 968.096L1558.93 955.893L1546.75 943.689Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_305" d="M1637.02 943.694L1624.84 955.897L1637.02 968.101L1649.2 955.897L1637.02 943.694Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_306" d="M1727.29 943.691L1715.11 955.895L1727.29 968.098L1739.46 955.895L1727.29 943.691Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_307" d="M1817.56 943.696L1805.38 955.9L1817.56 968.103L1829.73 955.9L1817.56 943.696Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_308" d="M1907.82 943.697L1895.65 955.9L1907.82 968.104L1920 955.9L1907.82 943.697Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_309" d="M12.189 1018.6L0.00878906 1030.8L12.189 1043L24.3693 1030.8L12.189 1018.6Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_310" d="M102.453 1018.59L90.2764 1030.8L102.453 1043L114.631 1030.8L102.453 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_311" d="M192.72 1018.59L180.543 1030.8L192.72 1043L204.897 1030.8L192.72 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_312" d="M282.989 1018.59L270.812 1030.8L282.989 1043L295.166 1030.8L282.989 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_313" d="M373.256 1018.59L361.079 1030.8L373.256 1043L385.433 1030.8L373.256 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_314" d="M463.523 1018.6L451.346 1030.81L463.523 1043.01L475.7 1030.81L463.523 1018.6Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_315" d="M553.791 1018.6L541.614 1030.81L553.791 1043.01L565.968 1030.81L553.791 1018.6Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_316" d="M644.058 1018.6L631.881 1030.81L644.058 1043.01L656.235 1030.81L644.058 1018.6Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_317" d="M734.333 1018.6L722.156 1030.8L734.333 1043L746.51 1030.8L734.333 1018.6Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_318" d="M824.6 1018.6L812.423 1030.8L824.6 1043L836.777 1030.8L824.6 1018.6Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_319" d="M914.869 1018.6L902.691 1030.8L914.869 1043L927.046 1030.8L914.869 1018.6Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_320" d="M1005.14 1018.6L992.958 1030.8L1005.14 1043L1017.31 1030.8L1005.14 1018.6Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_321" d="M1095.41 1018.59L1083.23 1030.8L1095.41 1043L1107.58 1030.8L1095.41 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_322" d="M1185.67 1018.59L1173.5 1030.8L1185.67 1043L1197.85 1030.8L1185.67 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_323" d="M1275.94 1018.59L1263.76 1030.8L1275.94 1043L1288.12 1030.8L1275.94 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_324" d="M1366.22 1018.59L1354.04 1030.79L1366.22 1043L1378.39 1030.79L1366.22 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_325" d="M1456.48 1018.59L1444.31 1030.79L1456.48 1043L1468.66 1030.79L1456.48 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_326" d="M1546.75 1018.59L1534.57 1030.79L1546.75 1043L1558.93 1030.79L1546.75 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_327" d="M1637.02 1018.59L1624.84 1030.8L1637.02 1043L1649.2 1030.79L1637.02 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_328" d="M1727.29 1018.59L1715.11 1030.8L1727.29 1043L1739.46 1030.8L1727.29 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_329" d="M1817.56 1018.59L1805.38 1030.8L1817.56 1043L1829.73 1030.8L1817.56 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
<path id="Vector_330" d="M1907.82 1018.59L1895.65 1030.8L1907.82 1043L1920 1030.8L1907.82 1018.59Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_0_4">
|
||||
<rect width="1920" height="923" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 45 KiB |
BIN
public/assets/cta-phone-art.png
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
14
public/assets/cta-talkpro-logo.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 187.801 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Frame 175584">
|
||||
<path id="Vector" d="M98.5724 56.3166C105.506 56.2187 112.442 56.3695 119.363 56.7677C139.793 57.9357 161.687 61.7026 181.076 68.5661C182.332 69.0109 184.68 69.7326 185.539 70.686C186.04 73.7965 174.791 70.4433 173.623 70.1805C151.914 65.356 129.759 62.7571 107.511 62.4274C79.8146 61.5564 50.3772 65.6841 23.4228 71.8478C22.387 72.0842 20.7438 72.1091 20.2019 71.0375C20.4422 69.5599 25.0328 68.1695 26.4037 67.6983C49.4098 59.7943 74.3118 56.8874 98.5724 56.3166Z" fill="var(--fill-0, #F28A4B)"/>
|
||||
<path id="Vector_2" d="M75.4035 6.21199C76.7201 6.19147 79.1802 5.90736 80.0807 6.88122C80.1912 8.30019 78.1779 17.6553 77.7802 19.6472C77.2517 22.2942 76.3512 27.9716 75.6538 30.486C78.383 28.2763 81.1036 25.653 83.6485 23.3327C86.8357 20.4285 87.7271 18.8091 92.4044 19.3757C93.6438 19.5257 95.8122 18.8675 96.518 20.1633C96.4756 20.599 96.5059 20.659 96.148 21.0078C92.2107 24.8448 87.7751 28.2905 83.7268 32.0076C85.7591 36.0561 88.8657 40.9428 91.2019 44.9614C91.7282 45.8011 92.2751 46.5019 92.3641 47.4758C92.2416 47.8688 92.1027 48.0266 91.7456 48.2413C90.3863 49.0589 85.5677 48.8789 84.0591 48.3896C82.4325 47.864 77.9547 38.1996 77.0221 36.3813C76.0324 37.2178 75.047 38.0591 74.0661 38.9067C73.4359 41.399 73.3222 44.0222 72.7116 46.4877C72.0698 48.931 70.0181 48.7874 68.1382 48.6785C65.2884 48.5128 63.8111 49.3651 64.5221 45.7427C65.0535 43.0373 65.7052 40.1157 66.2335 37.4435L69.572 20.4317C70.3942 16.4084 71.1016 12.3567 71.9067 8.33019C72.3425 6.15044 73.518 6.24829 75.4035 6.21199Z" fill="var(--fill-0, #2E2A28)"/>
|
||||
<path id="Vector_3" d="M2.26688 7.06162C7.84809 6.79575 13.5415 7.01572 19.1336 7.01572C23.1192 7.01572 27.689 6.75302 31.6032 7.04105C31.937 7.06637 32.1813 7.10594 32.4709 7.28952C32.7869 7.48892 32.8937 7.88455 32.917 8.2343C32.9949 9.40064 31.9229 13.0658 31.0763 13.8555C29.9695 14.8874 21.8044 14.3588 19.9426 14.343C17.9995 22.5928 16.5948 31.243 14.729 39.6005C14.2627 41.8192 13.8554 46.4166 12.5416 48.0846C11.7926 49.0341 5.81729 49.1022 4.7692 47.9501C4.55502 46.5685 10.5752 17.9765 11.2797 14.3762C8.96011 14.3271 1.48486 14.8557 0.129146 13.7068C-0.147233 13.1038 0.0772667 12.0783 0.270193 11.4532C0.837388 9.61586 0.304144 7.98741 2.26688 7.06162Z" fill="var(--fill-0, #2E2A28)"/>
|
||||
<path id="Vector_4" d="M61.3185 6.19364C62.4629 6.17462 65.1478 6.02728 66.1459 6.51209C67.1634 7.00798 66.1443 10.2305 65.95 11.3205C65.7031 12.7036 65.3428 14.2943 65.0538 15.7487L62.0133 31.2053C61.0281 36.2799 60.238 41.4178 59.2086 46.4877C58.8027 48.4871 58.4112 48.7516 56.489 48.7548C55.0398 48.7326 52.0926 49.0859 51.0794 48.1939C50.8676 48.0086 50.8634 47.9294 50.8898 47.5919C51.2324 43.1923 52.5386 38.4171 53.3681 34.1157L56.7259 16.6565C57.2967 13.7413 57.8475 10.8183 58.4947 7.91896C58.8906 6.14611 59.8524 6.23166 61.3185 6.19364Z" fill="var(--fill-0, #2E2A28)"/>
|
||||
<g id="Vector_5">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M172.511 18.4678C179.813 17.8626 186.731 21.2812 187.682 29.1226C188.224 33.7457 186.906 38.396 184.018 42.0481C180.612 46.3068 176.228 48.4003 170.885 48.9772C163.285 49.7083 156.062 46.239 155.27 37.9863C154.853 33.2608 156.328 28.5619 159.375 24.924C162.79 20.8638 167.327 18.9391 172.511 18.4678ZM177.677 38.0589C180.95 32.2679 180.364 24.3375 171.813 25.0562C166.51 26.1061 163.575 30.6158 163.622 35.8739C163.664 40.746 166.59 42.866 171.278 42.4893C174.03 41.873 176.284 40.5239 177.677 38.0589Z" fill="var(--fill-0, #F28A4B)"/>
|
||||
<path d="M154.323 18.1443C155.081 18.0545 157.117 18.3623 157.124 19.09C157.141 20.7764 155.914 25.1174 155.125 26.4767C154.068 26.5344 152.803 26.4367 151.758 26.5601C145.24 27.3231 144.18 32.3085 143.166 37.5632C142.72 39.8683 142.315 42.1831 141.951 44.5043C141.477 47.4554 141.657 49.1851 138.015 48.7346C136.711 48.5727 134.325 49.1482 133.381 48.2537C133.113 47.6846 133.163 47.6686 133.255 47.0611C134.12 43.4831 138.198 20.1112 138.967 19.3866C139.38 18.9971 140.247 18.8752 140.781 18.8496C141.93 18.7951 145.228 18.6268 146.021 19.3449C146.474 20.2378 145.87 22.8571 145.717 24.0418C147.895 20.7684 150.316 18.545 154.323 18.1443Z" fill="var(--fill-0, #F28A4B)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M117.845 6.5344C122.685 6.53913 128.878 6.45055 132.584 10.0897C137.724 15.1383 135.648 25.2847 130.794 29.8605C125.591 34.7686 119.629 35.0041 112.919 34.9584L111.04 34.9454C110.65 36.8636 109.09 47.2003 108.28 47.976C107.387 48.8318 103.97 48.5673 102.667 48.5783C101.84 48.5846 101 48.5431 100.382 47.9378C100.063 46.6792 103.641 30.1446 104.083 27.7993L106.598 14.8972C107.036 12.6685 107.406 10.3927 107.907 8.17661C108.12 7.2357 108.586 7.05573 109.39 6.59864C110.052 6.57815 110.716 6.5622 111.378 6.55116C113.534 6.53225 115.689 6.5281 117.845 6.5344ZM122.145 13.9942C119.913 13.6852 117.433 13.8019 115.162 13.8145C114.659 16.6043 114.134 19.3895 113.584 22.1698C113.259 23.8422 112.725 26.2246 112.615 27.8654C116.55 27.8859 119.441 28.1819 122.962 26.2623C127.653 23.2959 129.119 14.9558 122.145 13.9942Z" fill="var(--fill-0, #F28A4B)"/>
|
||||
</g>
|
||||
<path id="Subtract" fill-rule="evenodd" clip-rule="evenodd" d="M35.7559 18.7795C47.4524 17.4446 50.8083 23.7072 48.0883 34.0974C47.7767 35.2873 46.6482 40.6423 46.4982 41.7071C45.7424 47.0851 49.1571 48.8275 41.216 48.6967C38.6382 48.6304 38.2689 47.2962 38.3859 45.025C34.9164 48.5399 31.0461 50.1656 26.0144 48.9695C24.1421 48.5234 22.93 47.432 21.7078 46.0323C18.7908 41.4867 20.9746 35.2155 25.6206 32.796C30.1405 30.4427 35.8227 30.5767 40.8138 30.4695C41.9075 25.0553 38.9224 23.9042 34.0355 25.1761C31.8107 25.7545 30.9207 26.9825 29.0809 28.1505L28.9134 28.2557C28.716 28.1533 28.5217 28.0449 28.3315 27.9298C22.041 24.1817 27.5943 20.9045 31.9017 19.5363C33.2009 19.1234 34.4071 18.9465 35.7559 18.7795ZM39.6827 35.7192C38.1738 35.7144 36.5907 35.6734 35.094 35.8057C34.1157 35.9019 33.4599 35.9877 32.3896 36.2005C29.5592 36.7632 26.623 40.4941 29.5948 42.7544C30.4858 43.4336 31.9375 43.5058 33.1027 43.4349C37.3247 42.4782 39.1261 39.8362 39.6827 35.7192Z" fill="var(--fill-0, #2E2A28)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.1 KiB |
BIN
public/assets/exp-card-1.png
Normal file
|
After Width: | Height: | Size: 369 KiB |
BIN
public/assets/exp-card-2.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
public/assets/exp-card-3.png
Normal file
|
After Width: | Height: | Size: 206 KiB |
|
Before Width: | Height: | Size: 559 B After Width: | Height: | Size: 559 B |
6
public/assets/footer-apple-icon.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 22.0004 26.9856" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Group">
|
||||
<path id="Vector" d="M16.1918 0C16.2546 0 16.3174 0 16.3838 0C16.5378 1.90308 15.8115 3.32506 14.9286 4.35481C14.0624 5.37746 12.8762 6.36929 10.9578 6.21879C10.8298 4.34297 11.5574 3.02645 12.439 1.99907C13.2566 1.0416 14.7556 0.189597 16.1918 0Z" fill="var(--fill-0, white)"/>
|
||||
<path id="Vector_2" d="M22.0004 19.8082C22.0004 19.8271 22.0004 19.8437 22.0004 19.8615C21.4612 21.4944 20.6922 22.8939 19.7537 24.1926C18.8969 25.3717 17.847 26.9584 15.9724 26.9584C14.3525 26.9584 13.2766 25.9168 11.6164 25.8883C9.86025 25.8599 8.89449 26.7593 7.28883 26.9856C7.10516 26.9856 6.92149 26.9856 6.74137 26.9856C5.56231 26.815 4.61077 25.8812 3.91756 25.0399C1.87346 22.5538 0.293876 19.3425 0 15.233C0 14.8301 0 14.4284 0 14.0255C0.124423 11.0843 1.55351 8.69304 3.45304 7.53413C4.45554 6.91794 5.83367 6.39299 7.36823 6.62762C8.02589 6.72953 8.69778 6.95467 9.28672 7.17745C9.84484 7.39193 10.5428 7.77231 11.204 7.75217C11.6519 7.73913 12.0975 7.50569 12.549 7.34098C13.8714 6.86343 15.1678 6.31597 16.8765 6.57311C18.9301 6.88357 20.3876 7.79601 21.2882 9.20377C19.551 10.3094 18.1776 11.9754 18.4123 14.8206C18.6208 17.405 20.1234 18.9171 22.0004 19.8082Z" fill="var(--fill-0, white)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 1180 1" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<line id="Line" y1="0.5" x2="1180" y2="0.5" stroke="var(--stroke-0, #E3D9D1)"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 258 B |
BIN
public/assets/footer-logo.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
5
public/assets/header-globe.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Electric Cars, Solar & Clean Energy _ Tesla-6 1">
|
||||
<path id="Vector" d="M23.8327 13.0003C23.8327 18.9836 18.9826 23.8337 12.9993 23.8337C7.0161 23.8337 2.16602 18.9836 2.16602 13.0003C2.16602 7.01708 7.0161 2.16699 12.9993 2.16699C18.9826 2.16699 23.8327 7.01708 23.8327 13.0003ZM10.0245 21.7179C9.69954 21.2484 9.4209 20.7484 9.19252 20.2251C8.75485 19.2392 8.41035 18.0747 8.1796 16.792H4.6046C5.12443 17.9392 5.87339 18.968 6.80545 19.8151C7.73752 20.6622 8.83298 21.3098 10.0245 21.7179ZM10.6778 19.5642C11.0418 20.3843 11.4556 20.9986 11.8727 21.3951C12.2865 21.7894 12.6657 21.9378 12.9993 21.9378C13.333 21.9378 13.7122 21.7894 14.126 21.3962C14.5431 20.9986 14.9569 20.3843 15.3209 19.5653C15.6687 18.7821 15.9579 17.8428 16.1659 16.792H9.83168C10.0397 17.8428 10.3289 18.7821 10.6767 19.5653L10.6778 19.5642ZM9.47852 13.0003C9.47852 13.7489 9.51751 14.4737 9.5901 15.167H16.4086C16.4812 14.4737 16.5202 13.7489 16.5202 13.0003C16.5202 12.2517 16.4812 11.527 16.4086 10.8337H9.5901C9.51751 11.527 9.47852 12.2517 9.47852 13.0003ZM7.95643 10.8337H4.04777C3.87684 11.5432 3.79066 12.2705 3.79102 13.0003C3.79102 13.7467 3.87985 14.4726 4.04777 15.167H7.95643C7.81688 13.7259 7.81688 12.2747 7.95643 10.8337ZM9.83276 9.20866H16.1648C15.959 8.15783 15.6687 7.21858 15.3209 6.43533C14.9569 5.61633 14.5431 5.00208 14.126 4.60449C13.7122 4.21124 13.333 4.06283 12.9993 4.06283C12.6657 4.06283 12.2865 4.21124 11.8727 4.60449C11.4556 5.00208 11.0418 5.61633 10.6778 6.43533C10.33 7.21858 10.0408 8.15783 9.83276 9.20866ZM18.0412 10.8337C18.1809 12.2747 18.1809 13.7259 18.0412 15.167H21.952C22.1226 14.4574 22.2084 13.7301 22.2077 13.0003C22.2081 12.2705 22.1219 11.5432 21.9509 10.8337H18.0412ZM21.393 9.20866C20.8733 8.06154 20.1245 7.03282 19.1926 6.18572C18.2608 5.33862 17.1655 4.69102 15.9742 4.28274C16.2851 4.72474 16.5624 5.22849 16.8062 5.77558C17.2438 6.76141 17.5883 7.92599 17.8191 9.20866H21.3941H21.393ZM8.1796 9.20866C8.41035 7.92599 8.75485 6.76033 9.19252 5.77558C9.43627 5.22849 9.71251 4.72474 10.0245 4.28274C8.83318 4.69102 7.73793 5.33862 6.80606 6.18572C5.87419 7.03282 5.12539 8.06154 4.60568 9.20866H8.1796ZM16.8062 20.2251C16.5624 20.7722 16.2862 21.2759 15.9742 21.7179C17.1655 21.3096 18.2608 20.662 19.1926 19.8149C20.1245 18.9678 20.8733 17.9391 21.393 16.792H17.818C17.5883 18.0747 17.2438 19.2403 16.8062 20.2251Z" fill="var(--fill-0, #2E2A28)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 570 KiB After Width: | Height: | Size: 880 KiB |
|
Before Width: | Height: | Size: 716 KiB |
|
Before Width: | Height: | Size: 427 KiB |
|
Before Width: | Height: | Size: 602 KiB |
|
Before Width: | Height: | Size: 417 KiB |
|
Before Width: | Height: | Size: 161 KiB |
5
public/assets/preview-arrow-left.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Frame 175571">
|
||||
<path id="Vector" d="M5.5925 11.0298L14.0925 4.33982C15.1125 3.52982 16.6125 4.25982 16.6125 5.55982V18.9398C16.6125 20.2398 15.1125 20.9698 14.0925 20.1598L5.5925 13.4698C4.8025 12.8498 4.8025 11.6498 5.5925 11.0198V11.0298Z" fill="var(--fill-0, white)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 461 B |
5
public/assets/preview-arrow-right.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Frame 175571">
|
||||
<path id="Vector" d="M5.5925 11.0298L14.0925 4.33982C15.1125 3.52982 16.6125 4.25982 16.6125 5.55982V18.9398C16.6125 20.2398 15.1125 20.9698 14.0925 20.1598L5.5925 13.4698C4.8025 12.8498 4.8025 11.6498 5.5925 11.0198V11.0298Z" fill="var(--fill-0, white)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 461 B |
BIN
public/assets/preview-phone.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
3
public/assets/trust-divider.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 1 118" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Vector 16" d="M0.5 0V118" stroke="var(--stroke-0, #F08458)" stroke-opacity="0.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 270 B |
BIN
public/assets/trust-icon-improvement.png
Normal file
|
After Width: | Height: | Size: 370 KiB |
BIN
public/assets/trust-icon-sprite.png
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
3
public/assets/why-icon-connected.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 44.0005 43.9141" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Vector" d="M30.717 41.8428C27.9992 43.2162 25.0668 43.9141 22.0002 43.9141C18.9337 43.914 16.0021 43.2162 13.2844 41.8428L14.4474 39.542C19.1554 41.9236 24.845 41.9235 29.5529 39.542L30.717 41.8428ZM3.22186 28.0195C6.36294 26.2075 10.2762 27.349 12.0265 30.3789C13.8073 33.4615 12.7515 37.4018 9.66717 39.1836C6.57694 40.9653 2.64108 39.9046 0.861506 36.8242C-0.914556 33.7465 0.144168 29.797 3.22186 28.0195ZM31.9738 30.3789C33.7241 27.3491 37.6372 26.2075 40.7785 28.0195C43.8563 29.7971 44.9151 33.7464 43.1388 36.8242C41.3615 39.9009 37.4278 40.968 34.3332 39.1836C31.2509 37.4029 30.1921 33.4632 31.9738 30.3789ZM12.8234 10.5527C8.38347 13.4645 5.55977 18.3585 5.26776 23.6406L2.69451 23.499C3.02938 17.4013 6.28762 11.757 11.4084 8.39844L12.8234 10.5527ZM32.592 8.39844C37.7129 11.757 40.9709 17.4013 41.3058 23.499L38.7326 23.6406C38.4406 18.3585 35.6169 13.4654 31.1769 10.5537L32.592 8.39844ZM22.0002 0C25.5539 0 28.4455 2.89155 28.4455 6.44531C28.4455 9.99907 25.5539 12.8906 22.0002 12.8906C18.4465 12.8906 15.5549 9.99903 15.5549 6.44531C15.5549 2.89159 18.4465 6.78247e-05 22.0002 0Z" fill="var(--fill-0, white)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
3
public/assets/why-icon-familiar.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 38 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Vector" d="M38 0V40H0V0H38ZM20.5771 2.35254V37.6475H35.4229V2.35254H20.5771Z" fill="var(--fill-0, white)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 295 B |
3
public/assets/why-icon-modern.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 24.168 44.001" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Union" d="M24.168 36.0859V44.001H0V24.0576L24.168 36.0859ZM6.02539 36.1299C5.60296 37.1749 4.75786 38.0199 3.71289 38.4424C4.75786 38.8648 5.60296 39.7099 6.02539 40.7549C6.44783 39.7099 7.29292 38.8648 8.33789 38.4424C7.29292 38.0199 6.44783 37.1749 6.02539 36.1299ZM24.168 21.1445V28.8379L0 16.8096V9.09375L24.168 21.1445ZM24.168 18.9658L0 6.9375V0H24.168V18.9658Z" fill="var(--fill-0, white)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 593 B |
3
public/assets/why-icon-simple.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 44.001 43.9639" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Vector" d="M31.7793 34.1846L22.001 43.9639L12.2217 34.1846L22.001 24.4062L31.7793 34.1846ZM19.5576 22.0107L9.77832 31.7891L0 22.0107L9.77832 12.2314L19.5576 22.0107ZM44.001 21.9902L34.2227 31.7686L24.4434 21.9902L34.2227 12.2109L44.001 21.9902ZM31.7529 9.7793L21.9746 19.5576L12.1953 9.7793L21.9746 0L31.7529 9.7793Z" fill="var(--fill-0, white)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 544 B |
BIN
public/assets/why-illustration.mp4
Normal file
BIN
public/assets/why-illustration.png
Normal file
|
After Width: | Height: | Size: 325 KiB |
3
public/assets/why-underline.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 295.5 1" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Vector 15" d="M0 0.5H295.5" stroke="var(--stroke-0, #F08458)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 253 B |
310
public/site-links-client.js
Normal file
@@ -0,0 +1,310 @@
|
||||
/**
|
||||
* Mirrors talkpro static site: /api/site-links, APK default, in-app + App Store modals.
|
||||
* Strings come from #site-links-i18n (JSON) rendered by DownloadCTA.astro.
|
||||
*/
|
||||
(function () {
|
||||
const DEFAULT_APK = 'https://talkspro.xyz/download';
|
||||
let apkDownloadUrl = DEFAULT_APK;
|
||||
|
||||
function getApkDownloadUrl() {
|
||||
return apkDownloadUrl;
|
||||
}
|
||||
|
||||
function getI18n() {
|
||||
const el = document.getElementById('site-links-i18n');
|
||||
if (!el || !el.textContent.trim()) return {};
|
||||
try {
|
||||
return JSON.parse(el.textContent);
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function detectInAppBrowser() {
|
||||
const ua = navigator.userAgent || '';
|
||||
if (/MicroMessenger/i.test(ua)) return 'wechat';
|
||||
try {
|
||||
if (typeof window.WeixinJSBridge !== 'undefined') return 'wechat';
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
if (/QQ\//i.test(ua) && /MQQBrowser/i.test(ua)) return 'qq';
|
||||
if (/Weibo/i.test(ua)) return 'weibo';
|
||||
return '';
|
||||
}
|
||||
|
||||
function isIOSDevice() {
|
||||
const ua = navigator.userAgent || '';
|
||||
if (/iPhone|iPad|iPod/i.test(ua)) return true;
|
||||
if (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function isAndroidDevice() {
|
||||
const ua = navigator.userAgent || '';
|
||||
return /Android/i.test(ua) && !isIOSDevice();
|
||||
}
|
||||
|
||||
const MODAL_WRAP =
|
||||
'position:fixed;inset:0;z-index:10050;display:flex;align-items:center;justify-content:center;padding:16px;box-sizing:border-box;';
|
||||
const MODAL_BACK = 'position:absolute;inset:0;background:rgba(0,0,0,.45);cursor:pointer;';
|
||||
const MODAL_PANEL =
|
||||
'position:relative;max-width:420px;width:100%;margin:auto;padding:20px 22px;border-radius:12px;background:#fff;color:#1a1a1a;font:15px/1.45 system-ui,-apple-system,sans-serif;box-shadow:0 12px 40px rgba(0,0,0,.18);';
|
||||
const MODAL_TITLE = 'margin:0 0 10px;font-size:18px;font-weight:700;line-height:1.25;';
|
||||
const MODAL_BODY = 'margin:0 0 18px;font-size:14px;color:#444;';
|
||||
const MODAL_ACTIONS = 'display:flex;flex-wrap:wrap;gap:10px;justify-content:flex-end;';
|
||||
const BTN =
|
||||
'cursor:pointer;border-radius:8px;padding:10px 14px;font-size:14px;font-weight:600;border:1px solid #ccc;background:#f5f5f5;color:#1a1a1a;';
|
||||
const BTN_PRIMARY = 'border-color:#1a6cff;background:#1a6cff;color:#fff;';
|
||||
const BTN_ORANGE = 'cursor:pointer;border-radius:14px;padding:10px 14px;font-size:14px;font-weight:600;border:1px solid #f28a4b;background:#f28a4b;color:#fff;';
|
||||
|
||||
function initInAppBrowserModal() {
|
||||
if (document.getElementById('inapp-browser-modal')) return;
|
||||
const wrap = document.createElement('div');
|
||||
wrap.id = 'inapp-browser-modal';
|
||||
wrap.setAttribute('role', 'dialog');
|
||||
wrap.setAttribute('aria-modal', 'true');
|
||||
wrap.setAttribute('aria-hidden', 'true');
|
||||
wrap.style.cssText = MODAL_WRAP + 'display:none;';
|
||||
wrap.innerHTML =
|
||||
'<div data-inapp-close style="' +
|
||||
MODAL_BACK +
|
||||
'"></div>' +
|
||||
'<div style="' +
|
||||
MODAL_PANEL +
|
||||
'">' +
|
||||
'<h3 id="inapp-modal-title" style="' +
|
||||
MODAL_TITLE +
|
||||
'"></h3>' +
|
||||
'<p id="inapp-modal-body" style="' +
|
||||
MODAL_BODY +
|
||||
'"></p>' +
|
||||
'<div style="' +
|
||||
MODAL_ACTIONS +
|
||||
'">' +
|
||||
'<button type="button" id="inapp-copy-apk" style="' +
|
||||
BTN +
|
||||
BTN_PRIMARY +
|
||||
'"></button>' +
|
||||
'<button type="button" id="inapp-try-chrome" style="' +
|
||||
BTN +
|
||||
'" hidden></button>' +
|
||||
'<button type="button" id="inapp-got-it" data-inapp-close style="' +
|
||||
BTN +
|
||||
'"></button>' +
|
||||
'</div></div>';
|
||||
document.body.appendChild(wrap);
|
||||
|
||||
const close = () => {
|
||||
wrap.style.display = 'none';
|
||||
wrap.setAttribute('aria-hidden', 'true');
|
||||
};
|
||||
wrap.querySelectorAll('[data-inapp-close]').forEach((el) => {
|
||||
el.addEventListener('click', close);
|
||||
});
|
||||
|
||||
const i18n = () => getI18n();
|
||||
document.getElementById('inapp-copy-apk').addEventListener('click', async () => {
|
||||
const btn = document.getElementById('inapp-copy-apk');
|
||||
const dict = i18n();
|
||||
const done = dict.inapp_browser_copied || 'Copied';
|
||||
try {
|
||||
await navigator.clipboard.writeText(getApkDownloadUrl());
|
||||
const prev = btn.textContent;
|
||||
btn.textContent = done;
|
||||
setTimeout(() => {
|
||||
btn.textContent = dict.inapp_browser_copy || prev;
|
||||
}, 1600);
|
||||
} catch {
|
||||
window.prompt(dict.inapp_browser_copy || 'Copy', getApkDownloadUrl());
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('inapp-try-chrome').addEventListener('click', () => {
|
||||
const enc = encodeURIComponent(getApkDownloadUrl());
|
||||
const intent =
|
||||
getApkDownloadUrl().replace(/^https:/i, 'intent:') +
|
||||
'#Intent;' +
|
||||
'scheme=https;action=android.intent.action.VIEW;category=android.intent.category.BROWSABLE;' +
|
||||
'package=com.android.chrome;S.browser_fallback_url=' +
|
||||
enc +
|
||||
';end';
|
||||
window.location.href = intent;
|
||||
});
|
||||
}
|
||||
|
||||
function openInAppBrowserModal() {
|
||||
const modal = document.getElementById('inapp-browser-modal');
|
||||
if (!modal) return;
|
||||
const dict = getI18n();
|
||||
const tryChrome = modal.querySelector('#inapp-try-chrome');
|
||||
const showChrome = isAndroidDevice() && !!detectInAppBrowser();
|
||||
if (tryChrome) {
|
||||
tryChrome.hidden = !showChrome;
|
||||
tryChrome.setAttribute('aria-hidden', showChrome ? 'false' : 'true');
|
||||
}
|
||||
modal.style.display = 'flex';
|
||||
modal.setAttribute('aria-hidden', 'false');
|
||||
const titleEl = modal.querySelector('#inapp-modal-title');
|
||||
const bodyEl = modal.querySelector('#inapp-modal-body');
|
||||
if (titleEl) titleEl.textContent = dict.inapp_browser_title || '';
|
||||
if (bodyEl) {
|
||||
const iosWechat = isIOSDevice() && detectInAppBrowser() === 'wechat';
|
||||
const bodyKey = iosWechat ? 'inapp_browser_body_ios' : 'inapp_browser_body';
|
||||
bodyEl.innerHTML =
|
||||
dict[bodyKey] || dict.inapp_browser_body || '';
|
||||
}
|
||||
const copyBtn = modal.querySelector('#inapp-copy-apk');
|
||||
const gotBtn = modal.querySelector('#inapp-got-it');
|
||||
if (copyBtn) copyBtn.textContent = dict.inapp_browser_copy || '';
|
||||
if (tryChrome) tryChrome.textContent = dict.inapp_browser_try_chrome || '';
|
||||
if (gotBtn) gotBtn.textContent = dict.inapp_browser_got_it || 'OK';
|
||||
}
|
||||
|
||||
function initAppStoreSoonModal() {
|
||||
if (document.getElementById('app-store-soon-modal')) return;
|
||||
const wrap = document.createElement('div');
|
||||
wrap.id = 'app-store-soon-modal';
|
||||
wrap.setAttribute('role', 'dialog');
|
||||
wrap.setAttribute('aria-modal', 'true');
|
||||
wrap.setAttribute('aria-hidden', 'true');
|
||||
wrap.style.cssText = MODAL_WRAP + 'display:none;';
|
||||
wrap.innerHTML =
|
||||
'<div data-app-soon-close style="' +
|
||||
MODAL_BACK +
|
||||
'"></div>' +
|
||||
'<div style="' +
|
||||
MODAL_PANEL +
|
||||
'">' +
|
||||
'<h3 id="app-soon-title" style="' +
|
||||
MODAL_TITLE +
|
||||
'"></h3>' +
|
||||
'<p id="app-soon-body" style="' +
|
||||
MODAL_BODY +
|
||||
'"></p>' +
|
||||
'<div style="' +
|
||||
MODAL_ACTIONS +
|
||||
'">' +
|
||||
'<button type="button" data-app-soon-close style="' +
|
||||
BTN_ORANGE +
|
||||
'"></button>' +
|
||||
'</div></div>';
|
||||
document.body.appendChild(wrap);
|
||||
const close = () => {
|
||||
wrap.style.display = 'none';
|
||||
wrap.setAttribute('aria-hidden', 'true');
|
||||
};
|
||||
wrap.querySelectorAll('[data-app-soon-close]').forEach((el) => {
|
||||
el.addEventListener('click', close);
|
||||
});
|
||||
}
|
||||
|
||||
function openAppStoreSoonModal() {
|
||||
const modal = document.getElementById('app-store-soon-modal');
|
||||
if (!modal) return;
|
||||
const dict = getI18n();
|
||||
const tEl = modal.querySelector('#app-soon-title');
|
||||
const bEl = modal.querySelector('#app-soon-body');
|
||||
const ok = modal.querySelector('button[data-app-soon-close]');
|
||||
if (tEl) tEl.textContent = dict.app_store_soon_title || '';
|
||||
if (bEl) bEl.innerHTML = dict.app_store_soon_body || '';
|
||||
if (ok) ok.textContent = dict.app_store_soon_ok || 'OK';
|
||||
modal.style.display = 'flex';
|
||||
modal.setAttribute('aria-hidden', 'false');
|
||||
}
|
||||
|
||||
function bindBrowserDownloadLinks() {
|
||||
document.querySelectorAll('a.store-badge--browser').forEach((a) => {
|
||||
const openForInApp = (e) => {
|
||||
if (!detectInAppBrowser()) return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
openInAppBrowserModal();
|
||||
};
|
||||
a.addEventListener('click', openForInApp);
|
||||
a.addEventListener(
|
||||
'touchend',
|
||||
(e) => {
|
||||
if (!detectInAppBrowser()) return;
|
||||
e.preventDefault();
|
||||
openInAppBrowserModal();
|
||||
},
|
||||
{ passive: false }
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function bindAppStoreAppleBadges() {
|
||||
document.querySelectorAll('a.store-badge--apple[data-app-soon]').forEach((a) => {
|
||||
const stopAndOpen = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
openAppStoreSoonModal();
|
||||
};
|
||||
a.addEventListener('click', stopAndOpen);
|
||||
a.addEventListener(
|
||||
'touchend',
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
openAppStoreSoonModal();
|
||||
},
|
||||
{ passive: false }
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function loadSiteLinksThenBind() {
|
||||
if (window.location.protocol === 'file:') {
|
||||
bindBrowserDownloadLinks();
|
||||
bindAppStoreAppleBadges();
|
||||
return;
|
||||
}
|
||||
fetch('/api/site-links', { credentials: 'same-origin' })
|
||||
.then((r) => {
|
||||
if (!r.ok) throw new Error('bad status');
|
||||
return r.json();
|
||||
})
|
||||
.then((j) => {
|
||||
const apk = String(j.apk_download_url || '').trim();
|
||||
const ios = String(j.app_store_url || '').trim();
|
||||
if (apk.startsWith('https://')) apkDownloadUrl = apk;
|
||||
document.querySelectorAll('a.store-badge--browser').forEach((a) => {
|
||||
if (apk.startsWith('https://')) a.setAttribute('href', apk);
|
||||
});
|
||||
document.querySelectorAll('a.store-badge--apple').forEach((a) => {
|
||||
if (ios.startsWith('https://')) {
|
||||
a.setAttribute('href', ios);
|
||||
a.removeAttribute('data-app-soon');
|
||||
a.setAttribute('rel', 'noopener noreferrer');
|
||||
a.setAttribute('target', '_blank');
|
||||
}
|
||||
});
|
||||
const meta = document.getElementById('site-links-meta');
|
||||
if (meta) {
|
||||
const dict = getI18n();
|
||||
const u = String(j.updated_at || '').trim();
|
||||
if (u) {
|
||||
meta.textContent =
|
||||
(dict.linksMetaPrefix || 'Store links file updated: ') +
|
||||
u +
|
||||
(dict.linksMetaSuffix || ' (GMT+8)');
|
||||
meta.hidden = false;
|
||||
} else {
|
||||
meta.hidden = true;
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
/* keep defaults */
|
||||
})
|
||||
.finally(() => {
|
||||
bindBrowserDownloadLinks();
|
||||
bindAppStoreAppleBadges();
|
||||
});
|
||||
}
|
||||
|
||||
initInAppBrowserModal();
|
||||
initAppStoreSoonModal();
|
||||
loadSiteLinksThenBind();
|
||||
})();
|
||||
71
scripts/deploy-talkpro.sh
Executable file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build Astro dist/ and sync to the Talk Pro marketing host (talkpro.info).
|
||||
# Used by Gitea Actions and for manual deploys from this repo.
|
||||
#
|
||||
# Required (CI): TALKPRO_SSH_PRIVATE_KEY — PEM contents (Gitea secret)
|
||||
# Optional: TALKPRO_SSH_KEY_FILE — path to PEM (local)
|
||||
# Defaults match .env.deploy.example / Gitea workflow job env:
|
||||
# TALKPRO_HOST=13.214.179.69 TALKPRO_USER=ubuntu TALKPRO_REMOTE_ROOT=/home/ubuntu/talkpro
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
HOST="${TALKPRO_HOST:-13.214.179.69}"
|
||||
USER="${TALKPRO_USER:-ubuntu}"
|
||||
REMOTE_ROOT="${TALKPRO_REMOTE_ROOT:-/home/ubuntu/talkpro}"
|
||||
[[ -n "$HOST" ]] || HOST=13.214.179.69
|
||||
[[ -n "$USER" ]] || USER=ubuntu
|
||||
[[ -n "$REMOTE_ROOT" ]] || REMOTE_ROOT=/home/ubuntu/talkpro
|
||||
|
||||
KEY_FILE="${TALKPRO_SSH_KEY_FILE:-}"
|
||||
TMP_KEY=""
|
||||
cleanup() {
|
||||
[[ -n "$TMP_KEY" && -f "$TMP_KEY" ]] && rm -f "$TMP_KEY"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
if [[ -n "${TALKPRO_SSH_PRIVATE_KEY:-}" ]]; then
|
||||
TMP_KEY="$(mktemp)"
|
||||
chmod 600 "$TMP_KEY"
|
||||
printf '%s\n' "$TALKPRO_SSH_PRIVATE_KEY" | tr -d '\r' > "$TMP_KEY"
|
||||
KEY_FILE="$TMP_KEY"
|
||||
elif [[ -z "$KEY_FILE" || ! -f "$KEY_FILE" ]]; then
|
||||
echo "ERROR: Set TALKPRO_SSH_PRIVATE_KEY (Gitea secret / env) or TALKPRO_SSH_KEY_FILE (local path)" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -s "$KEY_FILE" ]]; then
|
||||
echo "ERROR: SSH key file is empty — check TALKPRO_SSH_PRIVATE_KEY secret in Gitea" >&2
|
||||
exit 1
|
||||
fi
|
||||
chmod 600 "$KEY_FILE"
|
||||
|
||||
SSH_OPTS=(-i "$KEY_FILE" -o BatchMode=yes -o StrictHostKeyChecking=accept-new)
|
||||
RSYNC_SSH="ssh -i \"$KEY_FILE\" -o BatchMode=yes -o StrictHostKeyChecking=accept-new"
|
||||
REMOTE="${USER}@${HOST}"
|
||||
|
||||
if [[ -f package-lock.json ]]; then
|
||||
npm ci
|
||||
else
|
||||
npm install
|
||||
fi
|
||||
npm run build
|
||||
|
||||
command -v ssh >/dev/null || { echo "ERROR: ssh not found (install openssh-client)" >&2; exit 127; }
|
||||
|
||||
ssh "${SSH_OPTS[@]}" "$REMOTE" "mkdir -p ${REMOTE_ROOT}"
|
||||
|
||||
if command -v rsync >/dev/null 2>&1; then
|
||||
echo "Uploading with rsync..."
|
||||
rsync -avz --delete \
|
||||
-e "$RSYNC_SSH" \
|
||||
dist/ \
|
||||
"${REMOTE}:${REMOTE_ROOT}/"
|
||||
else
|
||||
command -v tar >/dev/null || { echo "ERROR: need rsync or tar on the runner" >&2; exit 127; }
|
||||
echo "Uploading with tar over ssh (rsync not available on runner)..."
|
||||
ssh "${SSH_OPTS[@]}" "$REMOTE" "mkdir -p ${REMOTE_ROOT} && rm -rf ${REMOTE_ROOT:?}/*"
|
||||
tar -C dist -cf - . | ssh "${SSH_OPTS[@]}" "$REMOTE" "tar -C ${REMOTE_ROOT} -xf -"
|
||||
fi
|
||||
|
||||
echo "Deployed dist/ → ${REMOTE}:${REMOTE_ROOT}/"
|
||||
5
src/assets.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
const assetVersion = '20260518-1'
|
||||
|
||||
export function assetPath(path: string) {
|
||||
return `${path}?v=${assetVersion}`
|
||||
}
|
||||
91
src/components/AppPreview.astro
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
import { assetPath } from '../assets'
|
||||
import type { Translations } from '../i18n/translations'
|
||||
|
||||
export interface Props {
|
||||
t: Translations['preview']
|
||||
}
|
||||
|
||||
const { t } = Astro.props
|
||||
const slides = [
|
||||
assetPath("/assets/preview-phone.png"),
|
||||
assetPath("/assets/preview-phone.png"),
|
||||
assetPath("/assets/preview-phone.png"),
|
||||
]
|
||||
const arrowLeft = assetPath("/assets/preview-arrow-left.svg")
|
||||
const arrowRight = assetPath("/assets/preview-arrow-right.svg")
|
||||
---
|
||||
|
||||
<section class="app-preview">
|
||||
<div class="app-preview__header">
|
||||
<p class="app-preview__title">
|
||||
{t.title}
|
||||
</p>
|
||||
<p class="app-preview__description">
|
||||
{t.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="app-preview__carousel" id="carousel">
|
||||
<div class="app-preview__side-phone">
|
||||
<img id="phone-left" alt="" class="app-preview__phone-image" src={slides[slides.length - 1]} />
|
||||
</div>
|
||||
|
||||
<div class="app-preview__control-wrap">
|
||||
<div class="app-preview__control-inner">
|
||||
<button id="btn-prev" class="app-preview__button">
|
||||
<img alt={t.previous} class="app-preview__button-icon" src={arrowLeft} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app-preview__center-phone">
|
||||
<img id="phone-center" alt={t.phoneAlt} class="app-preview__phone-image" src={slides[0]} />
|
||||
</div>
|
||||
|
||||
<div class="app-preview__control-wrap">
|
||||
<div class="app-preview__control-inner">
|
||||
<button id="btn-next" class="app-preview__button">
|
||||
<img alt={t.next} class="app-preview__button-icon app-preview__button-icon--next" src={arrowRight} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app-preview__side-phone">
|
||||
<img id="phone-right" alt="" class="app-preview__phone-image" src={slides[1]} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
const carousel = document.getElementById('carousel')!;
|
||||
const allSlides: string[] = JSON.parse(carousel.dataset.slides || '[]');
|
||||
|
||||
const leftImg = document.getElementById('phone-left') as HTMLImageElement;
|
||||
const centerImg = document.getElementById('phone-center') as HTMLImageElement;
|
||||
const rightImg = document.getElementById('phone-right') as HTMLImageElement;
|
||||
const btnPrev = document.getElementById('btn-prev')!;
|
||||
const btnNext = document.getElementById('btn-next')!;
|
||||
|
||||
let current = 0;
|
||||
|
||||
function mod(n: number, m: number) { return ((n % m) + m) % m; }
|
||||
|
||||
function transition(next: number) {
|
||||
[leftImg, centerImg, rightImg].forEach(img => img && (img.style.opacity = '0'));
|
||||
setTimeout(() => {
|
||||
current = mod(next, allSlides.length);
|
||||
if (leftImg) leftImg.src = allSlides[mod(current - 1, allSlides.length)];
|
||||
if (centerImg) centerImg.src = allSlides[current];
|
||||
if (rightImg) rightImg.src = allSlides[mod(current + 1, allSlides.length)];
|
||||
[leftImg, centerImg, rightImg].forEach(img => img && (img.style.opacity = '1'));
|
||||
}, 200);
|
||||
}
|
||||
|
||||
if (btnPrev) btnPrev.addEventListener('click', () => transition(current - 1));
|
||||
if (btnNext) btnNext.addEventListener('click', () => transition(current + 1));
|
||||
</script>
|
||||
|
||||
<script define:vars={{ slides }}>
|
||||
document.getElementById('carousel').dataset.slides = JSON.stringify(slides);
|
||||
</script>
|
||||
@@ -1,43 +1,46 @@
|
||||
---
|
||||
const cards = [
|
||||
{ img: '/assets/icon-messaging.png', title: 'Private Messaging', desc: 'Stay connected through fast and familiar one-on-one conversations.' },
|
||||
{ img: '/assets/icon-groups.png', title: 'Group Chats', desc: 'Create spaces for friends, teams, communities, and shared discussions.' },
|
||||
{ img: '/assets/icon-channels.png', title: 'Channels', desc: 'Follow updates, announcements, and content from the people or communities you care about.' },
|
||||
{ img: '/assets/icon-voice.png', title: 'Voice Calls', desc: 'Talk in real time whenever messages are not enough.' },
|
||||
{ img: '/assets/icon-video.png', title: 'Video Calls', desc: 'Connect face-to-face with a simple and reliable video call experience.' },
|
||||
{ img: '/assets/icon-media.png', title: 'Media Sharing', desc: 'Share photos, videos, files, and updates in your conversations.' },
|
||||
import { assetPath } from '../assets'
|
||||
import type { Translations } from '../i18n/translations'
|
||||
|
||||
export interface Props {
|
||||
t: Translations['core']
|
||||
}
|
||||
|
||||
const { t } = Astro.props
|
||||
const halftone = assetPath("/assets/core-halftone-bg.png");
|
||||
const icons = [
|
||||
assetPath("/assets/core-icon-private.png"),
|
||||
assetPath("/assets/core-icon-groups.png"),
|
||||
assetPath("/assets/core-icon-channels.png"),
|
||||
assetPath("/assets/core-icon-voice.png"),
|
||||
assetPath("/assets/core-icon-video.png"),
|
||||
assetPath("/assets/core-icon-media.png"),
|
||||
]
|
||||
const rows = [cards.slice(0, 3), cards.slice(3)]
|
||||
---
|
||||
|
||||
<section class="flex flex-col items-center px-[130px] py-[110px] max-w-[1440px] mx-auto">
|
||||
<div class="flex flex-col items-center pb-[60px] w-full">
|
||||
<p class="font-bold text-brand text-[13px] tracking-[-0.04px]">CORE SYSTEM</p>
|
||||
<div class="h-[15px]"></div>
|
||||
<div class="font-bold text-text-primary text-[52px] text-center tracking-[-1.16px] leading-[0.96]">
|
||||
<p>Built for how modern</p>
|
||||
<p>communication actually works.</p>
|
||||
<section id="features" class="features">
|
||||
<img alt="" class="features__bg" src={halftone} />
|
||||
|
||||
<div class="features__header">
|
||||
<div class="section-eyebrow">
|
||||
<span class="section-eyebrow__text">{t.eyebrow}</span>
|
||||
</div>
|
||||
<div class="h-5"></div>
|
||||
<p class="text-text-secondary text-[18px] font-normal leading-[1.5] text-center tracking-[-0.26px] max-w-[900px]">
|
||||
Different identities, different conversations, and different privacy levels should not be forced into one flat interface. Talk Pro lets them exist in order inside one platform.
|
||||
<p class="features__title">{t.title}</p>
|
||||
<p class="features__description">
|
||||
{t.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-[22px] w-[1280px]">
|
||||
{rows.map((row) => (
|
||||
<div class="flex gap-[22px]">
|
||||
{row.map((card) => (
|
||||
<div class="flex-1 flex flex-col items-center bg-[rgba(255,255,255,0.78)] border border-white rounded-[30px] p-8">
|
||||
<div class="size-[240px] shrink-0 overflow-hidden rounded-2xl">
|
||||
<img src={card.img} alt={card.title} class="w-full h-full object-cover" />
|
||||
</div>
|
||||
<div class="h-[22px]"></div>
|
||||
<p class="font-bold text-text-primary text-[25px] tracking-[-0.5px] w-full">{card.title}</p>
|
||||
<div class="h-[14px]"></div>
|
||||
<p class="text-text-secondary text-[15px] font-normal leading-[1.5] tracking-[-0.13px] w-full">{card.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
<div class="features__grid">
|
||||
{t.cards.map((card, index) => (
|
||||
<div class="feature-card">
|
||||
<div class="feature-card__icon-frame">
|
||||
<img alt={card.title} class="feature-card__icon" src={icons[index]} />
|
||||
</div>
|
||||
<div class="feature-card__copy">
|
||||
<p class="feature-card__title">{card.title}</p>
|
||||
<p class="feature-card__description">{card.desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -1,40 +1,81 @@
|
||||
---
|
||||
import { assetPath } from '../assets'
|
||||
import type { Translations } from '../i18n/translations'
|
||||
|
||||
export interface Props {
|
||||
t: Translations['download']
|
||||
siteLinks: Translations['siteLinks']
|
||||
}
|
||||
|
||||
const { t, siteLinks } = Astro.props
|
||||
const bgPattern = assetPath("/assets/cta-bg-pattern.svg");
|
||||
const talkproLogo = assetPath("/assets/cta-talkpro-logo.svg");
|
||||
const androidIcon = assetPath("/assets/cta-android-icon.svg");
|
||||
const appleIcon = assetPath("/assets/cta-apple-icon.svg");
|
||||
const phoneArt = assetPath("/assets/cta-phone-art.png");
|
||||
const defaultApkHref = "https://talkspro.xyz/download";
|
||||
const siteLinksJson = JSON.stringify(siteLinks);
|
||||
---
|
||||
|
||||
<section class="flex flex-col items-center bg-surface-alt px-[130px] py-[110px] w-full">
|
||||
<div class="bg-[rgba(255,255,255,0.78)] rounded-[34px] p-[52px] flex flex-col items-center max-w-[1180px] w-full">
|
||||
<p class="font-bold text-brand text-[13px] tracking-[2.86px]">DOWNLOAD</p>
|
||||
<div class="h-[15px]"></div>
|
||||
<div class="font-bold text-text-primary text-[44px] text-center tracking-[-2.2px] leading-[1.04] max-w-[1076px]">
|
||||
<p>Start with one conversation.</p>
|
||||
<p>Build your own communication space.</p>
|
||||
</div>
|
||||
<div class="h-5"></div>
|
||||
<p class="text-text-secondary text-[18px] font-normal leading-[1.75] text-center max-w-[800px]">
|
||||
Talk Pro supports iOS and Android. Official store links, QR codes, version information, and compatibility notes are reserved on the download page.
|
||||
</p>
|
||||
<div class="h-8"></div>
|
||||
<section id="download" class="download-cta">
|
||||
<img alt="" class="download-cta__pattern" src={bgPattern} />
|
||||
|
||||
<div class="flex gap-2 items-center">
|
||||
<!-- Android badge -->
|
||||
<div class="bg-brand border border-border-light rounded-[20px] flex items-center gap-2 h-[70px] px-4 py-3">
|
||||
<img src="/assets/badge-android-icon.png" alt="Android" class="size-[44px]" />
|
||||
<div class="flex flex-col gap-[3px]">
|
||||
<p class="font-bold text-[#ffd6bc] text-[11px] tracking-[0.66px]">ANDROID</p>
|
||||
<p class="font-bold text-white text-[15px]">Download APK</p>
|
||||
</div>
|
||||
<div class="download-cta__inner">
|
||||
<div class="download-cta__content">
|
||||
<div class="section-eyebrow">
|
||||
<span class="section-eyebrow__text">{t.eyebrow}</span>
|
||||
</div>
|
||||
|
||||
<!-- iOS badge -->
|
||||
<div class="bg-[rgba(18,18,18,0.94)] border border-border-light rounded-[20px] flex items-center gap-2 h-[70px] px-4 py-3">
|
||||
<div class="bg-[#323232] rounded-[12px] size-[44px] flex items-center justify-center">
|
||||
<img src="/assets/badge-ios-icon.png" alt="Apple" class="w-[22px] h-[27px]" />
|
||||
</div>
|
||||
<div class="flex flex-col gap-[3px]">
|
||||
<p class="font-bold text-[#ccc] text-[11px] tracking-[0.66px]">IOS</p>
|
||||
<p class="font-bold text-white text-[15px]">Coming on App Store</p>
|
||||
<div class="download-cta__copy">
|
||||
<div class="download-cta__heading">
|
||||
<p class="download-cta__title">{t.title}</p>
|
||||
<div class="download-cta__logo-frame">
|
||||
<img alt={t.logoAlt} class="download-cta__logo" src={talkproLogo} />
|
||||
</div>
|
||||
</div>
|
||||
<p class="download-cta__description">
|
||||
{t.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="store-badges">
|
||||
<a
|
||||
class="store-badge store-badge--android store-badge--browser"
|
||||
href={defaultApkHref}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<div class="store-badge__icon-frame">
|
||||
<img alt={t.androidAlt} class="store-badge__android-icon" src={androidIcon} />
|
||||
</div>
|
||||
<div class="store-badge__copy">
|
||||
<p class="store-badge__platform">{t.android}</p>
|
||||
<p class="store-badge__label">{t.androidCta}</p>
|
||||
</div>
|
||||
</a>
|
||||
<a
|
||||
class="store-badge store-badge--ios store-badge--apple"
|
||||
href="#"
|
||||
data-app-soon="1"
|
||||
>
|
||||
<div class="store-badge__icon-frame">
|
||||
<img alt={t.appleAlt} class="store-badge__apple-icon" src={appleIcon} />
|
||||
</div>
|
||||
<div class="store-badge__copy">
|
||||
<p class="store-badge__platform">{t.ios}</p>
|
||||
<p class="store-badge__label">{t.iosCta}</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="download-cta__phone">
|
||||
<div class="download-cta__phone-crop">
|
||||
<img alt={t.phoneAlt} class="download-cta__phone-image" src={phoneArt} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script type="application/json" id="site-links-i18n" set:html={siteLinksJson} />
|
||||
|
||||
52
src/components/Experience.astro
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
import { assetPath } from '../assets'
|
||||
import type { Translations } from '../i18n/translations'
|
||||
|
||||
export interface Props {
|
||||
t: Translations['experience']
|
||||
}
|
||||
|
||||
const { t } = Astro.props
|
||||
const images = [
|
||||
assetPath("/assets/exp-card-1.png"),
|
||||
assetPath("/assets/exp-card-2.png"),
|
||||
assetPath("/assets/exp-card-3.png"),
|
||||
]
|
||||
const imageClasses = ['experience-card__image--one', 'experience-card__image--two', 'experience-card__image--three']
|
||||
---
|
||||
|
||||
<section id="experience" class="experience">
|
||||
<div class="experience__inner">
|
||||
<div class="experience__heading">
|
||||
<p class="experience__title">
|
||||
{t.title}
|
||||
</p>
|
||||
|
||||
<p class="experience__caption">
|
||||
{t.caption}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="experience__body">
|
||||
<div class="experience__grid">
|
||||
{t.cards.map((card, index) => (
|
||||
<div class="experience-card">
|
||||
<div class={`experience-card__media ${index > 0 ? 'experience-card__media--tinted' : ''}`}>
|
||||
<div class="experience-card__media-crop">
|
||||
<img
|
||||
alt={card.alt}
|
||||
class={`experience-card__image ${imageClasses[index]}`}
|
||||
src={images[index]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="experience-card__copy">
|
||||
<p class="experience-card__title">{card.title}</p>
|
||||
<p class="experience-card__description">{card.desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,42 +1,34 @@
|
||||
---
|
||||
const columns: Record<string, string[]> = {
|
||||
Product: ['Features', 'Product', 'Download'],
|
||||
Privacy: ['Privacy Policy', 'Protected Space', 'Security'],
|
||||
Company: ['About', 'Support', 'Contact'],
|
||||
import { assetPath } from '../assets'
|
||||
import type { Translations } from '../i18n/translations'
|
||||
|
||||
export interface Props {
|
||||
t: Translations['footer']
|
||||
}
|
||||
|
||||
const { t } = Astro.props
|
||||
const logoFull = assetPath("/assets/footer-logo.png");
|
||||
---
|
||||
|
||||
<footer class="bg-surface-footer px-[130px] pt-[58px] pb-[30px] w-full">
|
||||
<div class="flex gap-[42px] items-start max-w-[1180px]">
|
||||
<!-- Brand -->
|
||||
<div class="flex flex-col gap-[14px] w-[280px]">
|
||||
<div class="bg-brand rounded-[12px] size-9"></div>
|
||||
<p class="font-bold text-text-primary text-[18px] tracking-[-0.54px]">Talk Pro</p>
|
||||
<div class="text-text-secondary text-[14px] font-normal leading-[1.7]">
|
||||
<p>Designed for modern communication,</p>
|
||||
<p>privacy, and intelligent connection.</p>
|
||||
<footer class="site-footer">
|
||||
<div class="site-footer__inner">
|
||||
<div class="site-footer__top">
|
||||
<div class="site-footer__brand">
|
||||
<div class="site-footer__logo-frame">
|
||||
<img alt={t.logoAlt} class="site-footer__logo" src={logoFull} />
|
||||
</div>
|
||||
<p class="site-footer__description">
|
||||
{t.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1"></div>
|
||||
<div class="site-footer__divider"></div>
|
||||
|
||||
{Object.entries(columns).map(([heading, items]) => (
|
||||
<div class="flex flex-col gap-3">
|
||||
<p class="font-bold text-text-primary text-[15px]">{heading}</p>
|
||||
{items.map((item) => (
|
||||
<a href="#" class="text-text-secondary text-[14px] font-normal hover:text-text-primary transition-colors whitespace-nowrap">{item}</a>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div class="h-11"></div>
|
||||
<div class="max-w-[1180px] border-t border-border-light"></div>
|
||||
<div class="h-6"></div>
|
||||
|
||||
<div class="flex items-center gap-5 max-w-[1180px]">
|
||||
<p class="text-text-secondary text-[14px] font-normal">© 2026 Talk Pro. All rights reserved.</p>
|
||||
<div class="flex-1"></div>
|
||||
<p class="text-text-secondary text-[14px] font-normal">Terms of Use · Privacy Policy · Support</p>
|
||||
<div class="site-footer__bottom">
|
||||
<p class="site-footer__legal">{t.copyright}</p>
|
||||
<div class="site-footer__spacer"></div>
|
||||
<p class="site-footer__legal">{t.legal}</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -1,28 +1,181 @@
|
||||
---
|
||||
import { assetPath } from '../assets'
|
||||
import { getLocalePath, languageLabels, languageNames, languages, type Lang, type Translations } from '../i18n/translations'
|
||||
|
||||
export interface Props {
|
||||
lang: Lang
|
||||
t: Translations['header']
|
||||
}
|
||||
|
||||
const { lang, t } = Astro.props
|
||||
const logoIcon = assetPath("/assets/header-logo-icon.png");
|
||||
const logoWordmark = assetPath("/assets/header-logo-wordmark.svg");
|
||||
const globeIcon = assetPath("/assets/header-globe.svg");
|
||||
const navItems = [
|
||||
{ href: '#hero', label: t.nav.home },
|
||||
{ href: '#features', label: t.nav.features },
|
||||
{ href: '#experience', label: t.nav.experience },
|
||||
{ href: '#use-cases', label: t.nav.useCases },
|
||||
{ href: '#reliability', label: t.nav.reliability },
|
||||
]
|
||||
const languageOptions = languages.map(item => ({
|
||||
lang: item,
|
||||
href: getLocalePath(item),
|
||||
label: `${languageLabels[item]} - ${languageNames[item]}`,
|
||||
}))
|
||||
---
|
||||
|
||||
<header class="fixed top-0 left-0 w-full h-[78px] bg-[rgba(248,243,238,0.84)] border-b border-border-light backdrop-blur-sm z-50 flex items-center justify-center">
|
||||
<div class="w-[1280px] flex items-center">
|
||||
<div class="flex-1">
|
||||
<a href="/" class="flex items-center gap-2 w-fit">
|
||||
<img src="/assets/logo-icon.png" alt="Talk Pro icon" class="h-[42px] w-[53px] object-cover" />
|
||||
<img src="/assets/logo-wordmark.png" alt="Talk Pro" class="h-6" />
|
||||
<header id="site-header" class="site-header">
|
||||
<div class="site-header__bar">
|
||||
<div class="site-header__brand">
|
||||
<a href={getLocalePath(lang)} class="site-logo">
|
||||
<div class="site-logo__icon-frame">
|
||||
<img alt={t.logoIconAlt} class="site-logo__icon" src={logoIcon} />
|
||||
</div>
|
||||
<div class="site-logo__wordmark-frame">
|
||||
<img alt={t.logoAlt} class="site-logo__wordmark" src={logoWordmark} />
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<nav class="flex items-center gap-7 font-bold text-[14px] text-text-secondary tracking-[-0.09px]">
|
||||
<a href="#" class="hover:text-text-primary transition-colors">Home</a>
|
||||
<a href="#" class="hover:text-text-primary transition-colors">Features</a>
|
||||
<a href="#" class="hover:text-text-primary transition-colors">Product</a>
|
||||
<a href="#" class="hover:text-text-primary transition-colors">Privacy</a>
|
||||
<a href="#" class="hover:text-text-primary transition-colors">About</a>
|
||||
<nav class="site-nav" aria-label={t.navLabel}>
|
||||
{navItems.map((item, index) => (
|
||||
<a href={item.href} class={`site-nav__link ${index === 0 ? 'is-active' : ''}`} data-nav-link>{item.label}</a>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<div class="flex-1 flex justify-end">
|
||||
<button class="bg-brand text-white font-bold text-[14px] px-[22px] py-[13px] rounded-[17px] hover:opacity-90 transition-opacity">
|
||||
Download
|
||||
<div class="site-header__actions">
|
||||
<div class="language-switcher">
|
||||
<button
|
||||
id="language-toggle"
|
||||
class="language-switcher__button"
|
||||
type="button"
|
||||
aria-label={t.languageAlt}
|
||||
aria-expanded="false"
|
||||
aria-controls="language-menu"
|
||||
>
|
||||
<img alt="" class="language-switcher__icon" src={globeIcon} />
|
||||
<span class="language-switcher__current">{languageLabels[lang]}</span>
|
||||
</button>
|
||||
<div id="language-menu" class="language-switcher__menu is-hidden" aria-hidden="true">
|
||||
{languageOptions.map(option => (
|
||||
<a
|
||||
href={option.href}
|
||||
class={`language-switcher__option ${option.lang === lang ? 'is-active' : ''}`}
|
||||
aria-current={option.lang === lang ? 'page' : undefined}
|
||||
>
|
||||
{option.label}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="#download" class="site-header__download">
|
||||
<span class="site-header__download-label">{t.download}</span>
|
||||
</a>
|
||||
|
||||
<button
|
||||
id="menu-toggle"
|
||||
class="menu-toggle"
|
||||
type="button"
|
||||
aria-label={t.openMenu}
|
||||
aria-expanded="false"
|
||||
aria-controls="mobile-nav"
|
||||
data-open-label={t.openMenu}
|
||||
data-close-label={t.closeMenu}
|
||||
>
|
||||
<span id="bar-1" class="menu-toggle__bar"></span>
|
||||
<span id="bar-2" class="menu-toggle__bar"></span>
|
||||
<span id="bar-3" class="menu-toggle__bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="mobile-nav" class="mobile-nav is-hidden" aria-hidden="true">
|
||||
<ul class="mobile-nav__list">
|
||||
{navItems.map((item, index) => (
|
||||
<li><a href={item.href} class={`mobile-nav__link ${index === navItems.length - 1 ? 'mobile-nav__link--last' : ''}`} data-nav-link>{item.label}</a></li>
|
||||
))}
|
||||
<li class="mobile-nav__languages">
|
||||
{languages.map(item => (
|
||||
<a href={getLocalePath(item)} class={`mobile-nav__language-link ${item === lang ? 'is-active' : ''}`} aria-current={item === lang ? 'page' : undefined}>
|
||||
{languageNames[item]}
|
||||
</a>
|
||||
))}
|
||||
</li>
|
||||
<li class="mobile-nav__download-item">
|
||||
<a href="#download" class="mobile-nav__download">
|
||||
{t.download}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div class="h-[78px]"></div>
|
||||
|
||||
<script>
|
||||
const toggle = document.getElementById('menu-toggle') as HTMLButtonElement;
|
||||
const nav = document.getElementById('mobile-nav') as HTMLDivElement;
|
||||
const bar1 = document.getElementById('bar-1') as HTMLSpanElement;
|
||||
const bar2 = document.getElementById('bar-2') as HTMLSpanElement;
|
||||
const bar3 = document.getElementById('bar-3') as HTMLSpanElement;
|
||||
const languageToggle = document.getElementById('language-toggle') as HTMLButtonElement | null;
|
||||
const languageMenu = document.getElementById('language-menu') as HTMLDivElement | null;
|
||||
|
||||
function closeLanguageMenu() {
|
||||
if (!languageToggle || !languageMenu) return;
|
||||
languageToggle.setAttribute('aria-expanded', 'false');
|
||||
languageMenu.classList.add('is-hidden');
|
||||
languageMenu.setAttribute('aria-hidden', 'true');
|
||||
}
|
||||
|
||||
function openLanguageMenu() {
|
||||
if (!languageToggle || !languageMenu) return;
|
||||
languageToggle.setAttribute('aria-expanded', 'true');
|
||||
languageMenu.classList.remove('is-hidden');
|
||||
languageMenu.removeAttribute('aria-hidden');
|
||||
}
|
||||
|
||||
function openMenu() {
|
||||
toggle.setAttribute('aria-expanded', 'true');
|
||||
toggle.setAttribute('aria-label', toggle.dataset.closeLabel || 'Close menu');
|
||||
nav.classList.remove('is-hidden');
|
||||
nav.removeAttribute('aria-hidden');
|
||||
bar1.style.transform = 'translateY(7px) rotate(45deg)';
|
||||
bar2.style.opacity = '0';
|
||||
bar3.style.transform = 'translateY(-7px) rotate(-45deg)';
|
||||
}
|
||||
|
||||
function closeMenu() {
|
||||
toggle.setAttribute('aria-expanded', 'false');
|
||||
toggle.setAttribute('aria-label', toggle.dataset.openLabel || 'Open menu');
|
||||
nav.classList.add('is-hidden');
|
||||
nav.setAttribute('aria-hidden', 'true');
|
||||
bar1.style.transform = '';
|
||||
bar2.style.opacity = '';
|
||||
bar3.style.transform = '';
|
||||
}
|
||||
|
||||
toggle.addEventListener('click', () => {
|
||||
toggle.getAttribute('aria-expanded') === 'true' ? closeMenu() : openMenu();
|
||||
});
|
||||
|
||||
languageToggle?.addEventListener('click', event => {
|
||||
event.stopPropagation();
|
||||
languageToggle.getAttribute('aria-expanded') === 'true' ? closeLanguageMenu() : openLanguageMenu();
|
||||
});
|
||||
|
||||
languageMenu?.addEventListener('click', event => event.stopPropagation());
|
||||
|
||||
document.addEventListener('click', closeLanguageMenu);
|
||||
|
||||
document.addEventListener('keydown', event => {
|
||||
if (event.key === 'Escape') closeLanguageMenu();
|
||||
});
|
||||
|
||||
nav.querySelectorAll('a').forEach(a => a.addEventListener('click', closeMenu));
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
if (window.innerWidth >= 1024) closeMenu();
|
||||
if (window.innerWidth < 1024) closeLanguageMenu();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,82 +1,83 @@
|
||||
---
|
||||
const floatCards = [
|
||||
{
|
||||
icon: '☷',
|
||||
title: 'Work / Private / Protected',
|
||||
desc: 'One account, multiple communication worlds.',
|
||||
pos: 'left-[-40px] top-[75.5px]',
|
||||
},
|
||||
{
|
||||
icon: '✦',
|
||||
title: 'AI Summary Ready',
|
||||
desc: 'Long conversations and group highlights organized automatically.',
|
||||
pos: 'left-[180px] top-[270px]',
|
||||
},
|
||||
{
|
||||
icon: '◌',
|
||||
title: 'Protected Hidden Space',
|
||||
desc: 'When privacy needs more, enter a protected space.',
|
||||
pos: 'left-[20px] top-[540px]',
|
||||
},
|
||||
]
|
||||
import { assetPath } from '../assets'
|
||||
import type { Translations } from '../i18n/translations'
|
||||
|
||||
export interface Props {
|
||||
t: Translations['hero']
|
||||
download: Translations['download']
|
||||
}
|
||||
|
||||
const { t, download } = Astro.props
|
||||
const heroBg = assetPath("/assets/hero-bg.png");
|
||||
const phoneMockup = assetPath("/assets/hero-phone.png");
|
||||
const androidIcon = assetPath("/assets/cta-android-icon.svg");
|
||||
const appleIcon = assetPath("/assets/cta-apple-icon.svg");
|
||||
const defaultApkHref = "https://talkspro.xyz/download";
|
||||
---
|
||||
|
||||
<section class="relative w-full overflow-hidden">
|
||||
<img src="/assets/hero-bg.png" alt="" class="absolute inset-0 w-full h-full object-cover pointer-events-none" aria-hidden="true" />
|
||||
<section id="hero" class="hero">
|
||||
<img alt="" class="hero__bg" src={heroBg} />
|
||||
|
||||
<div class="relative flex items-center gap-[70px] h-[683px] px-[130px] py-[80px] max-w-[1440px] mx-auto">
|
||||
<!-- Left column -->
|
||||
<div class="flex flex-col gap-[30px] items-start w-[600px] shrink-0">
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="bg-[rgba(255,255,255,0.62)] border border-white px-[14px] py-[9px] rounded-full w-fit">
|
||||
<p class="font-bold text-text-secondary text-[14px] tracking-[-0.09px] whitespace-pre">✦ Available on iOS and Android</p>
|
||||
<div class="hero__inner">
|
||||
<div class="hero__phone-column">
|
||||
<div class="hero__phone-frame">
|
||||
<div class="hero__phone-crop">
|
||||
<img alt={t.phoneAlt} class="hero__phone" src={phoneMockup} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="font-bold text-text-primary text-[72px] tracking-[-1.61px] leading-[0.96] w-[560px]">
|
||||
<p>One User.</p>
|
||||
<p>Multiple Worlds.</p>
|
||||
<div class="hero__content">
|
||||
<div class="hero__badge">
|
||||
<p class="hero__badge-text">{t.badge}</p>
|
||||
</div>
|
||||
|
||||
<div class="hero__copy">
|
||||
<div class="hero__title">
|
||||
<p class="hero__title-line">{t.titleLine1}</p>
|
||||
<p class="hero__title-line">{t.titleLine2}</p>
|
||||
</div>
|
||||
|
||||
<p class="text-text-secondary text-[20px] font-normal leading-[1.5] tracking-[-0.33px]">
|
||||
Talk Pro is a modern messaging app designed for clear, simple, and reliable communication. From private chats to group conversations, channels, voice calls, and video calls, Talk Pro helps people stay connected in one familiar experience.
|
||||
<p class="hero__description">
|
||||
{t.description}
|
||||
</p>
|
||||
<div class="hero__actions">
|
||||
<a
|
||||
href={defaultApkHref}
|
||||
class="store-badge store-badge--android store-badge--browser hero__store-badge"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<div class="store-badge__icon-frame">
|
||||
<img alt={download.androidAlt} class="store-badge__android-icon" src={androidIcon} />
|
||||
</div>
|
||||
<div class="store-badge__copy">
|
||||
<p class="store-badge__platform">{download.android}</p>
|
||||
<p class="store-badge__label">{download.androidCta}</p>
|
||||
</div>
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
class="store-badge store-badge--ios store-badge--apple hero__store-badge"
|
||||
data-app-soon="1"
|
||||
>
|
||||
<div class="store-badge__icon-frame">
|
||||
<img alt={download.appleAlt} class="store-badge__apple-icon" src={appleIcon} />
|
||||
</div>
|
||||
<div class="store-badge__copy">
|
||||
<p class="store-badge__platform">{download.ios}</p>
|
||||
<p class="store-badge__label">{download.iosCta}</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-[14px]">
|
||||
<button class="bg-brand text-white font-bold text-[15px] px-6 py-[14px] rounded-[17px] tracking-[-0.13px] hover:opacity-90 transition-opacity whitespace-pre">
|
||||
Download Talk Pro ↓
|
||||
</button>
|
||||
<button class="bg-[rgba(255,255,255,0.55)] border border-border-light text-text-primary font-bold text-[15px] px-6 py-[14px] rounded-[17px] tracking-[-0.13px] hover:bg-white transition-colors whitespace-pre">
|
||||
Explore Features →
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-[10px]">
|
||||
{['Identity Layer', 'AI Native Messaging', 'Adaptive Privacy'].map((tag) => (
|
||||
<div class="bg-[rgba(255,255,255,0.68)] border border-white px-[14px] py-[9px] rounded-full">
|
||||
<p class="font-bold text-text-secondary text-[14px] tracking-[-0.09px] whitespace-nowrap">{tag}</p>
|
||||
<div class="hero__tags">
|
||||
{t.tags.map(tag => (
|
||||
<div class="hero__tag">
|
||||
<span class="hero__tag-text">{tag}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Phone mockup -->
|
||||
<div class="relative h-[690px] w-[430px] shrink-0">
|
||||
<div class="absolute bg-text-primary h-[620px] left-[63px] rounded-[44px] top-[35px] w-[304px] overflow-hidden">
|
||||
<img src="/assets/hero-phone.png" alt="Talk Pro app" class="absolute left-3 top-3 w-[280px] h-[596px] rounded-[34px] object-cover" />
|
||||
</div>
|
||||
|
||||
{floatCards.map((card) => (
|
||||
<div class={`absolute ${card.pos} flex items-start gap-3 bg-[rgba(255,255,255,0.86)] border border-white backdrop-blur-[3.7px] rounded-[24px] pl-4 pr-[18px] py-4`}>
|
||||
<div class="bg-[#fff0e5] rounded-[14px] size-[38px] flex items-center justify-center shrink-0">
|
||||
<span class="text-brand font-bold text-[18px]">{card.icon}</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<p class="font-bold text-text-primary text-[14px] tracking-[-0.09px] whitespace-nowrap">{card.title}</p>
|
||||
<p class="text-text-secondary text-[12px] font-normal leading-[1.45] tracking-[0.01px] w-[185px]">{card.desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
62
src/components/Trust.astro
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
import { assetPath } from '../assets'
|
||||
import type { Translations } from '../i18n/translations'
|
||||
|
||||
export interface Props {
|
||||
t: Translations['trust']
|
||||
}
|
||||
|
||||
const { t } = Astro.props
|
||||
const trustIconSprite = assetPath("/assets/trust-icon-sprite.png")
|
||||
const trustIconImprovement = assetPath("/assets/trust-icon-improvement.png")
|
||||
const trustDivider = assetPath("/assets/trust-divider.svg")
|
||||
const iconClasses = [
|
||||
'trust-card__icon--one',
|
||||
'trust-card__icon--two',
|
||||
'trust-card__icon--three',
|
||||
'trust-card__icon--four',
|
||||
]
|
||||
---
|
||||
|
||||
<section id="reliability" class="trust">
|
||||
<div class="trust__inner">
|
||||
<div class="trust__header">
|
||||
<div class="section-eyebrow">
|
||||
<span class="section-eyebrow__text">{t.eyebrow}</span>
|
||||
</div>
|
||||
<p class="trust__title">{t.title}</p>
|
||||
<p class="trust__description">
|
||||
{t.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="trust__grid">
|
||||
{t.cards.map((card, index) => (
|
||||
<>
|
||||
<div class="trust-card">
|
||||
<div class="trust-card__icon-frame">
|
||||
<div class="trust-card__icon-crop">
|
||||
<img
|
||||
alt=""
|
||||
class={`trust-card__icon ${iconClasses[index]}`}
|
||||
src={index === 3 ? trustIconImprovement : trustIconSprite}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="trust-card__copy">
|
||||
<p class="trust-card__title">{card.title}</p>
|
||||
<p class="trust-card__description">{card.desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
{index < t.cards.length - 1 && (
|
||||
<div class="trust__divider">
|
||||
<div class="trust__divider-frame">
|
||||
<img alt="" class="trust__divider-image" src={trustDivider} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,31 +1,38 @@
|
||||
---
|
||||
const cases = [
|
||||
{ title: 'Work Identity', desc: 'Keep work communication clear, organized, and easier to review.' },
|
||||
{ title: 'Private Identity', desc: 'Keep personal conversations natural, focused, and separate from work noise.' },
|
||||
{ title: 'Protected Space', desc: 'Some conversations are not only private. They require stronger boundaries and another layer of protection.' },
|
||||
]
|
||||
import type { Translations } from '../i18n/translations'
|
||||
|
||||
export interface Props {
|
||||
t: Translations['useCases']
|
||||
}
|
||||
|
||||
const { t } = Astro.props
|
||||
---
|
||||
|
||||
<section class="flex flex-col items-center bg-surface px-[130px] py-[110px] w-full">
|
||||
<div class="flex flex-col items-center pb-[60px] max-w-[1180px] w-full">
|
||||
<p class="font-bold text-brand text-[13px] tracking-[2.86px]">USE CASES</p>
|
||||
<div class="h-[15px]"></div>
|
||||
<p class="font-bold text-text-primary text-[52px] text-center tracking-[-2.6px] leading-[1.04]">
|
||||
Designed for the worlds you already live in.
|
||||
</p>
|
||||
<div class="h-5"></div>
|
||||
<p class="text-text-secondary text-[18px] font-normal leading-[1.75] text-center max-w-[900px]">
|
||||
Work, private life, and protected conversations should not interfere with each other inside one identity.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-[22px]">
|
||||
{cases.map((c) => (
|
||||
<div class="bg-[rgba(255,255,255,0.78)] border border-white rounded-[30px] p-8 h-[245px] w-[378px] flex flex-col">
|
||||
<p class="font-bold text-text-primary text-[25px] tracking-[-0.75px]">{c.title}</p>
|
||||
<div class="h-4"></div>
|
||||
<p class="text-text-secondary text-[15px] font-normal leading-[1.72]">{c.desc}</p>
|
||||
<section id="use-cases" class="use-cases">
|
||||
<div class="use-cases__inner">
|
||||
<div class="use-cases__copy">
|
||||
<div class="section-eyebrow">
|
||||
<span class="section-eyebrow__text">{t.eyebrow}</span>
|
||||
</div>
|
||||
))}
|
||||
<p class="use-cases__title">
|
||||
{t.title}
|
||||
</p>
|
||||
<p class="use-cases__description">
|
||||
{t.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="use-cases__rows">
|
||||
{t.rows.map(row => (
|
||||
<div class="use-case-row">
|
||||
<div class="use-case-row__title-cell">
|
||||
<p class="use-case-row__title">{row.title}</p>
|
||||
</div>
|
||||
<div class="use-case-row__description-cell">
|
||||
<p class="use-case-row__description">{row.desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
73
src/components/WhyTalkPro.astro
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
import { assetPath } from '../assets'
|
||||
import type { Translations } from '../i18n/translations'
|
||||
|
||||
export interface Props {
|
||||
t: Translations['why']
|
||||
}
|
||||
|
||||
const { t } = Astro.props
|
||||
const underline = assetPath("/assets/why-underline.svg");
|
||||
const icons = [
|
||||
assetPath("/assets/why-icon-simple.svg"),
|
||||
assetPath("/assets/why-icon-familiar.svg"),
|
||||
assetPath("/assets/why-icon-connected.svg"),
|
||||
assetPath("/assets/why-icon-modern.svg"),
|
||||
]
|
||||
const illustrationVideo = assetPath("/assets/why-illustration.mp4")
|
||||
const iconClasses = ['why-card__icon--simple', 'why-card__icon--familiar', 'why-card__icon--connected', 'why-card__icon--modern']
|
||||
---
|
||||
|
||||
<section class="why">
|
||||
<div class="why__inner">
|
||||
<div class="why__intro">
|
||||
<div class="why__copy">
|
||||
<div class="section-eyebrow">
|
||||
<span class="section-eyebrow__text">{t.eyebrow}</span>
|
||||
</div>
|
||||
<div class="why__text">
|
||||
<div class="why__title">
|
||||
<p class="why__title-line">{t.titleLine1}</p>
|
||||
<p class="why__title-line">{t.titleLine2}</p>
|
||||
</div>
|
||||
<div class="why__underline">
|
||||
<div class="why__underline-frame">
|
||||
<img alt="" class="why__underline-image" src={underline} />
|
||||
</div>
|
||||
</div>
|
||||
<p class="why__description">
|
||||
{t.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="why__illustration">
|
||||
<video
|
||||
aria-label={t.illustrationAlt}
|
||||
class="why__illustration-image"
|
||||
autoplay
|
||||
loop
|
||||
muted
|
||||
playsinline
|
||||
preload="metadata"
|
||||
>
|
||||
<source src={illustrationVideo} type="video/mp4" />
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="why__grid">
|
||||
{t.cards.map((card, index) => (
|
||||
<div class="why-card">
|
||||
<div class="why-card__icon-frame">
|
||||
<img alt="" class={`why-card__icon ${iconClasses[index]}`} src={icons[index]} />
|
||||
</div>
|
||||
<div class="why-card__copy">
|
||||
<p class="why-card__title">{card.title}</p>
|
||||
<p class="why-card__description">{card.desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
2738
src/i18n/translations.ts
Normal file
@@ -3,22 +3,106 @@ import '../styles/global.css'
|
||||
|
||||
export interface Props {
|
||||
title?: string
|
||||
description?: string
|
||||
lang?: string
|
||||
}
|
||||
const { title = 'Talk Pro — One User. Multiple Worlds.' } = Astro.props
|
||||
|
||||
const {
|
||||
title = 'Talk Pro - One User. Multiple Worlds.',
|
||||
description = 'Talk Pro is a modern messaging app for private chats, group conversations, channels, voice and video calls.',
|
||||
lang = 'en',
|
||||
} = Astro.props
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html lang={lang}>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Talk Pro is a modern messaging app for private chats, group conversations, channels, voice and video calls." />
|
||||
<meta name="description" content={description} />
|
||||
<title>{title}</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
</head>
|
||||
<body class="bg-surface font-sans overflow-x-hidden">
|
||||
<slot />
|
||||
<script src="/site-links-client.js?v=2" defer></script>
|
||||
<script>
|
||||
(() => {
|
||||
const header = document.getElementById('site-header');
|
||||
const getOffset = () => header ? header.offsetHeight : 0;
|
||||
let activeScrollAnimation = 0;
|
||||
|
||||
const easeInOutCubic = (t: number) => (
|
||||
t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2
|
||||
);
|
||||
|
||||
const animateScrollTo = (targetTop: number) => {
|
||||
const startTop = window.scrollY;
|
||||
const distance = targetTop - startTop;
|
||||
|
||||
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
||||
window.scrollTo(0, targetTop);
|
||||
return;
|
||||
}
|
||||
|
||||
if (activeScrollAnimation) {
|
||||
cancelAnimationFrame(activeScrollAnimation);
|
||||
}
|
||||
|
||||
const duration = Math.min(1300, Math.max(650, Math.abs(distance) * 0.7));
|
||||
const startTime = performance.now();
|
||||
|
||||
const step = (now: number) => {
|
||||
const elapsed = now - startTime;
|
||||
const progress = Math.min(elapsed / duration, 1);
|
||||
const easedProgress = easeInOutCubic(progress);
|
||||
|
||||
window.scrollTo(0, startTop + distance * easedProgress);
|
||||
|
||||
if (progress < 1) {
|
||||
activeScrollAnimation = requestAnimationFrame(step);
|
||||
} else {
|
||||
activeScrollAnimation = 0;
|
||||
}
|
||||
};
|
||||
|
||||
activeScrollAnimation = requestAnimationFrame(step);
|
||||
};
|
||||
|
||||
document.querySelectorAll('a[href^="#"]').forEach(link => {
|
||||
link.addEventListener('click', e => {
|
||||
const href = link.getAttribute('href');
|
||||
if (!href || href === '#') return;
|
||||
const target = document.querySelector(href);
|
||||
if (!target) return;
|
||||
e.preventDefault();
|
||||
const top = target.getBoundingClientRect().top + window.scrollY - getOffset();
|
||||
animateScrollTo(top);
|
||||
history.pushState(null, '', href);
|
||||
});
|
||||
});
|
||||
|
||||
const navLinks = document.querySelectorAll('[data-nav-link]');
|
||||
const sections = Array.from(navLinks)
|
||||
.map(l => document.querySelector(l.getAttribute('href') ?? ''))
|
||||
.filter(Boolean) as Element[];
|
||||
|
||||
if ('IntersectionObserver' in window && sections.length) {
|
||||
const observer = new IntersectionObserver(entries => {
|
||||
const visible = entries
|
||||
.filter(e => e.isIntersecting)
|
||||
.sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0];
|
||||
if (!visible) return;
|
||||
navLinks.forEach(link => {
|
||||
const active = link.getAttribute('href') === `#${visible.target.id}`;
|
||||
link.classList.toggle('is-active', active);
|
||||
});
|
||||
}, { rootMargin: '-30% 0px -60% 0px', threshold: 0 });
|
||||
sections.forEach(s => observer.observe(s));
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
36
src/pages/[lang]/index.astro
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
import Base from '../../layouts/Base.astro'
|
||||
import Header from '../../components/Header.astro'
|
||||
import Hero from '../../components/Hero.astro'
|
||||
import WhyTalkPro from '../../components/WhyTalkPro.astro'
|
||||
import CoreSystem from '../../components/CoreSystem.astro'
|
||||
import Experience from '../../components/Experience.astro'
|
||||
import UseCases from '../../components/UseCases.astro'
|
||||
import Trust from '../../components/Trust.astro'
|
||||
import DownloadCTA from '../../components/DownloadCTA.astro'
|
||||
import Footer from '../../components/Footer.astro'
|
||||
import { defaultLang, getTranslations, isLang, languages } from '../../i18n/translations'
|
||||
|
||||
export function getStaticPaths() {
|
||||
return languages
|
||||
.filter(lang => lang !== defaultLang)
|
||||
.map(lang => ({ params: { lang } }))
|
||||
}
|
||||
|
||||
const currentLang = Astro.params.lang
|
||||
const lang = isLang(currentLang) ? currentLang : defaultLang
|
||||
const t = getTranslations(lang)
|
||||
---
|
||||
|
||||
<Base lang={lang} title={t.meta.title} description={t.meta.description}>
|
||||
<Header lang={lang} t={t.header} />
|
||||
<Hero t={t.hero} download={t.download} />
|
||||
<WhyTalkPro t={t.why} />
|
||||
<CoreSystem t={t.core} />
|
||||
<Experience t={t.experience} />
|
||||
<UseCases t={t.useCases} />
|
||||
<Trust t={t.trust} />
|
||||
<!-- AppPreview section disabled per lead request. -->
|
||||
<DownloadCTA t={t.download} siteLinks={t.siteLinks} />
|
||||
<Footer t={t.footer} />
|
||||
</Base>
|
||||
@@ -2,17 +2,28 @@
|
||||
import Base from '../layouts/Base.astro'
|
||||
import Header from '../components/Header.astro'
|
||||
import Hero from '../components/Hero.astro'
|
||||
import WhyTalkPro from '../components/WhyTalkPro.astro'
|
||||
import CoreSystem from '../components/CoreSystem.astro'
|
||||
import Experience from '../components/Experience.astro'
|
||||
import UseCases from '../components/UseCases.astro'
|
||||
import Trust from '../components/Trust.astro'
|
||||
import DownloadCTA from '../components/DownloadCTA.astro'
|
||||
import Footer from '../components/Footer.astro'
|
||||
import { defaultLang, getTranslations } from '../i18n/translations'
|
||||
|
||||
const lang = defaultLang
|
||||
const t = getTranslations(lang)
|
||||
---
|
||||
|
||||
<Base>
|
||||
<Header />
|
||||
<Hero />
|
||||
<CoreSystem />
|
||||
<UseCases />
|
||||
<DownloadCTA />
|
||||
<Footer />
|
||||
<Base lang={lang} title={t.meta.title} description={t.meta.description}>
|
||||
<Header lang={lang} t={t.header} />
|
||||
<Hero t={t.hero} download={t.download} />
|
||||
<WhyTalkPro t={t.why} />
|
||||
<CoreSystem t={t.core} />
|
||||
<Experience t={t.experience} />
|
||||
<UseCases t={t.useCases} />
|
||||
<Trust t={t.trust} />
|
||||
<!-- AppPreview section disabled per lead request. -->
|
||||
<DownloadCTA t={t.download} siteLinks={t.siteLinks} />
|
||||
<Footer t={t.footer} />
|
||||
</Base>
|
||||
|
||||
344
src/styles/download.css
Normal file
@@ -0,0 +1,344 @@
|
||||
.download-cta {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
min-height: 400px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
border-top: 1px solid #eec8b8;
|
||||
}
|
||||
|
||||
.download-cta__pattern {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 1920px;
|
||||
max-width: none;
|
||||
height: 923px;
|
||||
pointer-events: none;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.download-cta__inner {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
gap: 0px;
|
||||
margin: 0 auto;
|
||||
padding: 60px 16px;
|
||||
}
|
||||
|
||||
.download-cta__content {
|
||||
display: flex;
|
||||
order: 2;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 0;
|
||||
gap: 36px;
|
||||
overflow: clip;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.download-cta__copy {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.download-cta__heading {
|
||||
--download-heading-title-size: 32px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
gap: 16px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.download-cta__title {
|
||||
position: relative;
|
||||
top: -4px;
|
||||
margin: 0;
|
||||
flex-shrink: 0;
|
||||
font-size: var(--download-heading-title-size);
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
letter-spacing: var(--ls-32);
|
||||
color: #1a1a1a;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.download-cta__logo-frame {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
width: calc(var(--download-heading-title-size) * 3.9167);
|
||||
height: calc(var(--download-heading-title-size) * 1.5);
|
||||
}
|
||||
|
||||
.download-cta__logo {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.download-cta__description {
|
||||
max-width: 542px;
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-16);
|
||||
color: #7a726d;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.store-badges {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
gap: 16px;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
.store-badge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
width: 260px;
|
||||
max-width: 100%;
|
||||
height: 70px;
|
||||
gap: 8px;
|
||||
padding: 12px 16px;
|
||||
overflow: clip;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
a.store-badge {
|
||||
box-sizing: border-box;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.download-cta__links-meta {
|
||||
font-size: 13px;
|
||||
color: #7a726d;
|
||||
margin: 14px auto 0;
|
||||
max-width: min(1180px, calc(100% - 40px));
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.store-badge--android {
|
||||
background: #f28a4b;
|
||||
border: 1px solid #c5834e;
|
||||
}
|
||||
|
||||
.store-badge--ios {
|
||||
background: #121212F0;
|
||||
border: 1px solid #2C2C2C;
|
||||
}
|
||||
|
||||
.store-badge__icon {
|
||||
display: block;
|
||||
flex-shrink: 0;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.store-badge__icon-frame {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
background: #323232;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.store-badge__apple-icon {
|
||||
display: block;
|
||||
width: 22px;
|
||||
height: 27px;
|
||||
}
|
||||
|
||||
.store-badge--android .store-badge__icon-frame {
|
||||
background: #d55f31;
|
||||
}
|
||||
|
||||
.store-badge__android-icon {
|
||||
display: block;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.store-badge__copy {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
flex-shrink: 0;
|
||||
gap: 3px;
|
||||
overflow: clip;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.store-badge__platform {
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
letter-spacing: var(--ls-13);
|
||||
}
|
||||
|
||||
.store-badge--android .store-badge__platform {
|
||||
color: #ffd6bc;
|
||||
}
|
||||
|
||||
.store-badge--ios .store-badge__platform {
|
||||
color: #949494;
|
||||
}
|
||||
|
||||
.store-badge__label {
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
letter-spacing: var(--ls-15);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.download-cta__phone {
|
||||
position: relative;
|
||||
display: block;
|
||||
order: 1;
|
||||
flex-shrink: 0;
|
||||
width: 240px;
|
||||
height: 292px;
|
||||
}
|
||||
|
||||
@media (min-width: 578px) {
|
||||
.download-cta__phone {
|
||||
width: min(418px, calc(100vw - 32px));
|
||||
height: auto;
|
||||
aspect-ratio: 418 / 510;
|
||||
}
|
||||
}
|
||||
|
||||
.download-cta__phone-crop {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.download-cta__phone-image {
|
||||
position: absolute;
|
||||
top: -18.05%;
|
||||
left: 3.8%;
|
||||
width: 92.43%;
|
||||
max-width: none;
|
||||
height: 136.1%;
|
||||
}
|
||||
|
||||
@media (max-width: 397px) {
|
||||
.download-cta__heading {
|
||||
--download-heading-title-size: clamp(24px, 8vw, 32px);
|
||||
gap: clamp(8px, 2.5vw, 12px);
|
||||
}
|
||||
|
||||
.download-cta__title {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 569px) {
|
||||
.store-badge {
|
||||
width: min(100%, calc(100vw - 32px));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 570px) {
|
||||
.download-cta__heading {
|
||||
--download-heading-title-size: 40px;
|
||||
}
|
||||
|
||||
.download-cta__title {
|
||||
letter-spacing: var(--ls-40);
|
||||
}
|
||||
|
||||
.download-cta__description {
|
||||
font-size: 18px;
|
||||
letter-spacing: var(--ls-18);
|
||||
}
|
||||
|
||||
.store-badges {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.download-cta {
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
.download-cta__inner {
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.download-cta__content {
|
||||
order: 1;
|
||||
align-items: flex-start;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.download-cta__copy {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.download-cta__description {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.store-badges {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.download-cta__heading {
|
||||
--download-heading-title-size: 48px;
|
||||
}
|
||||
|
||||
.download-cta__title {
|
||||
letter-spacing: var(--ls-48);
|
||||
}
|
||||
|
||||
.download-cta__phone {
|
||||
order: 2;
|
||||
width: 418px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.download-cta__inner {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
209
src/styles/features.css
Normal file
@@ -0,0 +1,209 @@
|
||||
.features {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: 60px;
|
||||
padding: 60px 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.features__bg {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 2363px;
|
||||
height: 1319px;
|
||||
object-fit: cover;
|
||||
opacity: 0.2;
|
||||
pointer-events: none;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.features__header {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
gap: 24px;
|
||||
margin: 0 auto;
|
||||
padding: 0 16px;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
.features__title {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
letter-spacing: var(--ls-28);
|
||||
color: #1a1a1a;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.features__description {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-15);
|
||||
color: #7a726d;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.features__grid {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
gap: 22px;
|
||||
margin: 0 auto;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
padding: 36px;
|
||||
background: rgba(255, 255, 255, 0.78);
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
.feature-card__icon-frame {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.feature-card__icon {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.feature-card__copy {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
gap: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.feature-card__title {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
letter-spacing: var(--ls-20);
|
||||
color: #2e2a28;
|
||||
}
|
||||
|
||||
.feature-card__description {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-15);
|
||||
color: #7a726d;
|
||||
}
|
||||
|
||||
@media (min-width: 440px) {
|
||||
.features__header,
|
||||
.features__grid {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.features__title {
|
||||
font-size: 32px;
|
||||
letter-spacing: var(--ls-32);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
.features__header,
|
||||
.features__grid {
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
.features__title {
|
||||
font-size: 36px;
|
||||
letter-spacing: var(--ls-36);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.features__header,
|
||||
.features__grid {
|
||||
padding-left: 36px;
|
||||
padding-right: 36px;
|
||||
}
|
||||
|
||||
.features__title {
|
||||
font-size: 42px;
|
||||
letter-spacing: var(--ls-42);
|
||||
}
|
||||
|
||||
.features__grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.feature-card__title {
|
||||
font-size: 24px;
|
||||
letter-spacing: var(--ls-24);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.features__header {
|
||||
padding: 0 clamp(36px, 14vw, 180px);
|
||||
}
|
||||
|
||||
.features__grid {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
padding: 0 36px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.features__title {
|
||||
font-size: 48px;
|
||||
letter-spacing: var(--ls-48);
|
||||
}
|
||||
|
||||
.features__description {
|
||||
font-size: 18px;
|
||||
letter-spacing: var(--ls-18);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.features__grid {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1376px) {
|
||||
.features {
|
||||
padding-top: 120px;
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
}
|
||||
131
src/styles/footer.css
Normal file
@@ -0,0 +1,131 @@
|
||||
.site-footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding: 60px 0;
|
||||
background: #fef0eb;
|
||||
}
|
||||
|
||||
.site-footer__inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
gap: 36px;
|
||||
margin: 0 auto;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.site-footer__top {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
gap: 40px;
|
||||
}
|
||||
|
||||
.site-footer__brand {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
gap: 24px;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
.site-footer__logo-frame {
|
||||
position: relative;
|
||||
width: 220px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.site-footer__logo {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.site-footer__description {
|
||||
max-width: 320px;
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-14);
|
||||
color: #7a726d;
|
||||
}
|
||||
|
||||
.site-footer__divider {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: #e3d9d1;
|
||||
}
|
||||
|
||||
.site-footer__bottom {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
gap: 12px;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
.site-footer__legal {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: normal;
|
||||
letter-spacing: var(--ls-14);
|
||||
color: #7a726d;
|
||||
}
|
||||
|
||||
.site-footer__spacer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.site-footer__bottom {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.site-footer__spacer {
|
||||
display: block;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.site-footer {
|
||||
padding: 60px 0;
|
||||
}
|
||||
|
||||
.site-footer__inner {
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.site-footer__top {
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.site-footer__inner {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.site-footer__legal {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
@@ -1 +1,79 @@
|
||||
/* UnoCSS handles reset and utilities via astro.config.mjs injectReset */
|
||||
@import './header.css';
|
||||
@import './hero.css';
|
||||
@import './sections.css';
|
||||
@import './download.css';
|
||||
@import './footer.css';
|
||||
@import './why.css';
|
||||
@import './features.css';
|
||||
@import './trust.css';
|
||||
@import './preview.css';
|
||||
|
||||
body {
|
||||
font-family: "Inter", sans-serif;
|
||||
--ls-12: 0.01px;
|
||||
--ls-13: -0.04px;
|
||||
--ls-14: -0.09px;
|
||||
--ls-15: -0.13px;
|
||||
--ls-16: -0.18px;
|
||||
--ls-17: -0.22px;
|
||||
--ls-18: -0.26px;
|
||||
--ls-19: -0.30px;
|
||||
--ls-20: -0.33px;
|
||||
--ls-21: -0.37px;
|
||||
--ls-22: -0.40px;
|
||||
--ls-23: -0.44px;
|
||||
--ls-24: -0.47px;
|
||||
--ls-25: -0.50px;
|
||||
--ls-26: -0.53px;
|
||||
--ls-27: -0.56px;
|
||||
--ls-28: -0.59px;
|
||||
--ls-29: -0.61px;
|
||||
--ls-30: -0.64px;
|
||||
--ls-31: -0.67px;
|
||||
--ls-32: -0.69px;
|
||||
--ls-33: -0.72px;
|
||||
--ls-34: -0.74px;
|
||||
--ls-35: -0.77px;
|
||||
--ls-36: -0.79px;
|
||||
--ls-37: -0.81px;
|
||||
--ls-38: -0.84px;
|
||||
--ls-39: -0.86px;
|
||||
--ls-40: -0.89px;
|
||||
--ls-41: -0.91px;
|
||||
--ls-42: -0.93px;
|
||||
--ls-43: -0.95px;
|
||||
--ls-44: -0.98px;
|
||||
--ls-45: -1.00px;
|
||||
--ls-46: -1.02px;
|
||||
--ls-47: -1.05px;
|
||||
--ls-48: -1.07px;
|
||||
--ls-49: -1.09px;
|
||||
--ls-50: -1.11px;
|
||||
--ls-51: -1.14px;
|
||||
--ls-52: -1.16px;
|
||||
--ls-53: -1.18px;
|
||||
--ls-54: -1.20px;
|
||||
--ls-55: -1.23px;
|
||||
--ls-56: -1.25px;
|
||||
--ls-57: -1.27px;
|
||||
--ls-58: -1.29px;
|
||||
--ls-59: -1.32px;
|
||||
--ls-60: -1.34px;
|
||||
--ls-61: -1.36px;
|
||||
--ls-62: -1.38px;
|
||||
--ls-63: -1.40px;
|
||||
--ls-64: -1.43px;
|
||||
--ls-65: -1.45px;
|
||||
--ls-66: -1.47px;
|
||||
--ls-67: -1.49px;
|
||||
--ls-68: -1.52px;
|
||||
--ls-69: -1.54px;
|
||||
--ls-70: -1.56px;
|
||||
--ls-71: -1.58px;
|
||||
--ls-72: -1.61px;
|
||||
}
|
||||
|
||||
:target {
|
||||
scroll-margin-top: 72px;
|
||||
}
|
||||
|
||||
354
src/styles/header.css
Normal file
@@ -0,0 +1,354 @@
|
||||
.site-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #e3d9d1;
|
||||
}
|
||||
|
||||
.site-header__bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
height: 72px;
|
||||
gap: 24px;
|
||||
margin: 0 auto;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.site-header__brand,
|
||||
.site-header__actions {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.site-header__brand {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.site-header__actions {
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.site-logo {
|
||||
position: relative;
|
||||
display: block;
|
||||
flex-shrink: 0;
|
||||
width: 143px;
|
||||
height: 42px;
|
||||
}
|
||||
|
||||
.site-logo__icon-frame {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 53px;
|
||||
height: 42px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.site-logo__icon {
|
||||
position: absolute;
|
||||
top: -13.49%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
height: 126.98%;
|
||||
}
|
||||
|
||||
.site-logo__wordmark-frame {
|
||||
position: absolute;
|
||||
inset: 26.97% 0 7.92% 45.45%;
|
||||
}
|
||||
|
||||
.site-logo__wordmark {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.site-nav {
|
||||
display: none;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.site-nav__link {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
letter-spacing: var(--ls-14);
|
||||
color: #7a726d;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
transition: color 160ms ease;
|
||||
}
|
||||
|
||||
.site-nav__link:hover,
|
||||
.site-nav__link.is-active {
|
||||
color: #f28a4b;
|
||||
}
|
||||
|
||||
.language-switcher {
|
||||
position: relative;
|
||||
display: none;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.language-switcher__button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 43px;
|
||||
gap: 8px;
|
||||
padding: 0 16px 0 12px;
|
||||
background: #fff;
|
||||
border: 1px solid rgba(46, 42, 40, 0.3);
|
||||
border-radius: 17px;
|
||||
cursor: pointer;
|
||||
transition: border-color 160ms ease;
|
||||
}
|
||||
|
||||
.language-switcher__button:hover,
|
||||
.language-switcher__button[aria-expanded="true"] {
|
||||
border-color: #f28a4b;
|
||||
}
|
||||
|
||||
.language-switcher__icon {
|
||||
display: block;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.language-switcher__current {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 14px;
|
||||
letter-spacing: var(--ls-14);
|
||||
color: #2e2a28;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.language-switcher__menu {
|
||||
position: absolute;
|
||||
top: 52px;
|
||||
right: 0;
|
||||
z-index: 60;
|
||||
width: 240px;
|
||||
max-height: min(520px, calc(100vh - 96px));
|
||||
overflow-y: auto;
|
||||
background: #fff;
|
||||
border: 1px solid #e3d9d1;
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 16px 40px rgba(46, 42, 40, 0.16);
|
||||
}
|
||||
|
||||
.language-switcher__menu.is-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.language-switcher__option {
|
||||
display: block;
|
||||
padding: 14px 24px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
letter-spacing: var(--ls-14);
|
||||
color: #7a726d;
|
||||
text-decoration: none;
|
||||
transition:
|
||||
background-color 160ms ease,
|
||||
color 160ms ease;
|
||||
}
|
||||
|
||||
.language-switcher__option:hover {
|
||||
color: #f28a4b;
|
||||
background: #fef0eb;
|
||||
}
|
||||
|
||||
.language-switcher__option.is-active {
|
||||
color: #2e2a28;
|
||||
background: #f8f3ee;
|
||||
}
|
||||
|
||||
.site-header__download {
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
padding: 13px 22px;
|
||||
background: #f28a4b;
|
||||
border-radius: 17px;
|
||||
text-decoration: none;
|
||||
transition: background-color 160ms ease;
|
||||
}
|
||||
|
||||
.site-header__download:hover {
|
||||
background: #e07a3b;
|
||||
}
|
||||
|
||||
.site-header__download-label {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
letter-spacing: var(--ls-14);
|
||||
color: #fff;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.menu-toggle {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
gap: 5px;
|
||||
padding: 8px;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu-toggle__bar {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background: #2e2a28;
|
||||
border-radius: 2px;
|
||||
transform-origin: center;
|
||||
transition:
|
||||
transform 240ms ease,
|
||||
opacity 240ms ease;
|
||||
}
|
||||
|
||||
.mobile-nav {
|
||||
max-height: calc(100vh - 72px);
|
||||
overflow-y: auto;
|
||||
background: #fff;
|
||||
border-top: 1px solid #e3d9d1;
|
||||
}
|
||||
|
||||
.mobile-nav.is-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobile-nav__list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 16px 24px;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.mobile-nav__link {
|
||||
display: block;
|
||||
padding: 16px 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
letter-spacing: var(--ls-16);
|
||||
color: #2e2a28;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid #e3d9d1;
|
||||
transition: color 160ms ease;
|
||||
}
|
||||
|
||||
.mobile-nav__link.is-active {
|
||||
color: #f28a4b;
|
||||
}
|
||||
|
||||
.mobile-nav__link--last {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.mobile-nav__languages {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
align-items: center;
|
||||
gap: 12px 16px;
|
||||
padding: 16px 0;
|
||||
border-top: 1px solid #e3d9d1;
|
||||
}
|
||||
|
||||
.mobile-nav__language-link {
|
||||
min-width: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 1.25;
|
||||
letter-spacing: var(--ls-14);
|
||||
color: #2e2a28;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.mobile-nav__language-link.is-active {
|
||||
color: #f28a4b;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.mobile-nav__languages {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 501px) and (max-width: 1024px) {
|
||||
.mobile-nav__languages {
|
||||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-nav__download-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 16px 0 8px;
|
||||
}
|
||||
|
||||
.mobile-nav__download {
|
||||
display: block;
|
||||
width: 250px;
|
||||
max-width: 100%;
|
||||
padding: 14px 24px;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
letter-spacing: var(--ls-15);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
background: #f28a4b;
|
||||
border-radius: 17px;
|
||||
transition: background-color 160ms ease;
|
||||
}
|
||||
|
||||
.mobile-nav__download:hover {
|
||||
background: #e07a3b;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.site-header__bar {
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.site-nav,
|
||||
.language-switcher,
|
||||
.site-header__download {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.menu-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobile-nav {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
382
src/styles/hero.css
Normal file
@@ -0,0 +1,382 @@
|
||||
.hero {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
min-height: 600px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero__bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.hero__inner {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
height: 100%;
|
||||
gap: 40px;
|
||||
margin: 0 auto;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.hero__phone-column {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding-top: 24px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.hero__phone-frame {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: min(320px, 100%);
|
||||
height: 527px;
|
||||
}
|
||||
|
||||
.hero__phone-crop {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.hero__phone {
|
||||
position: absolute;
|
||||
top: -7.18%;
|
||||
left: -2.67%;
|
||||
width: 105.35%;
|
||||
max-width: none;
|
||||
height: 114.36%;
|
||||
}
|
||||
|
||||
.hero__content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
gap: 60px;
|
||||
padding: 32px 0;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
.hero__badge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
padding: 12px 16px;
|
||||
overflow: clip;
|
||||
background: #fff;
|
||||
border: 1px solid #f08458;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.hero__badge-text {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
letter-spacing: var(--ls-14);
|
||||
color: #0d0d0d;
|
||||
}
|
||||
|
||||
.hero__copy {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.hero__title {
|
||||
width: 100%;
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
line-height: 1.1;
|
||||
letter-spacing: var(--ls-36);
|
||||
color: #2e2a28;
|
||||
}
|
||||
|
||||
.hero__title-line {
|
||||
margin: 0;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.hero__description {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-15);
|
||||
color: #7a726d;
|
||||
}
|
||||
|
||||
.hero__actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
gap: 14px;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
.hero__store-badge {
|
||||
text-decoration: none;
|
||||
transition:
|
||||
transform 160ms ease,
|
||||
filter 160ms ease;
|
||||
}
|
||||
|
||||
.hero__store-badge:hover {
|
||||
filter: brightness(0.96);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.hero__tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
gap: 10px;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
.hero__tag {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
padding: 9px 14px;
|
||||
overflow: clip;
|
||||
background: rgba(255, 255, 255, 0.68);
|
||||
border: 1px solid #fff;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.hero__tag-text {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
letter-spacing: var(--ls-14);
|
||||
color: #7a726d;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 433px) {
|
||||
.hero__store-badge {
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.hero__actions {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.hero__store-badge {
|
||||
flex: 1 1 calc((100% - 14px) / 2);
|
||||
width: calc((100% - 14px) / 2);
|
||||
min-width: 0;
|
||||
padding-right: 10px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.hero__store-badge .store-badge__copy,
|
||||
.hero__store-badge .store-badge__label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 540px) {
|
||||
.hero__actions {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.hero__store-badge {
|
||||
flex-basis: auto;
|
||||
width: min(100%, calc(100vw - 32px));
|
||||
}
|
||||
|
||||
.hero__tags {
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 440px) {
|
||||
.hero__title {
|
||||
font-size: 42px;
|
||||
letter-spacing: var(--ls-42);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
.hero__title {
|
||||
font-size: 48px;
|
||||
letter-spacing: var(--ls-48);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.hero__title {
|
||||
font-size: 56px;
|
||||
letter-spacing: var(--ls-56);
|
||||
}
|
||||
|
||||
.hero__phone-column {
|
||||
padding-top: 60px;
|
||||
}
|
||||
|
||||
.hero__phone-frame {
|
||||
width: min(580px, 100%);
|
||||
height: auto;
|
||||
aspect-ratio: 116 / 191;
|
||||
}
|
||||
|
||||
.hero__phone-crop {
|
||||
position: relative;
|
||||
inset: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.hero__phone {
|
||||
position: static;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.hero {
|
||||
height: 891px;
|
||||
}
|
||||
|
||||
.hero__inner {
|
||||
flex-direction: row;
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.hero__phone-column {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero__phone-frame {
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero__phone-crop {
|
||||
position: relative;
|
||||
inset: auto;
|
||||
height: 100%;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.hero__phone {
|
||||
position: static;
|
||||
width: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.hero__actions {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.hero__store-badge {
|
||||
flex: 0 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.hero__content {
|
||||
width: clamp(560px, 44vw, 600px);
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.hero__title {
|
||||
font-size: 64px;
|
||||
letter-spacing: var(--ls-64);
|
||||
}
|
||||
|
||||
.hero__description {
|
||||
font-size: 18px;
|
||||
letter-spacing: var(--ls-18);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.hero__inner {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.hero__phone-column {
|
||||
align-items: flex-start;
|
||||
padding-top: 60px;
|
||||
}
|
||||
|
||||
.hero__phone-frame {
|
||||
position: static;
|
||||
top: auto;
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
overflow: visible;
|
||||
flex: 1 0 0;
|
||||
width: auto;
|
||||
max-width: calc(955px * 116 / 191);
|
||||
height: 955px;
|
||||
aspect-ratio: 116 / 191;
|
||||
}
|
||||
|
||||
.hero__phone-crop {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.hero__phone {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.hero__content {
|
||||
width: clamp(560px, 52vw, 660px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1376px) {
|
||||
.hero__title {
|
||||
font-size: 72px;
|
||||
letter-spacing: var(--ls-72);
|
||||
}
|
||||
}
|
||||
243
src/styles/preview.css
Normal file
@@ -0,0 +1,243 @@
|
||||
.app-preview {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: 60px;
|
||||
padding: 64px 16px 0;
|
||||
overflow: hidden;
|
||||
background: #fef0eb;
|
||||
}
|
||||
|
||||
.app-preview__header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
max-width: 940px;
|
||||
gap: 40px;
|
||||
margin: 0 auto;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
.app-preview__title {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
color: #1a1a1a;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.app-preview__description {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-15);
|
||||
color: #7a726d;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.app-preview__carousel {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
gap: 24px;
|
||||
padding: 0 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.app-preview__side-phone {
|
||||
position: relative;
|
||||
display: none;
|
||||
flex-shrink: 0;
|
||||
width: 336px;
|
||||
height: 396px;
|
||||
overflow: hidden;
|
||||
opacity: 0.2;
|
||||
pointer-events: none;
|
||||
transition: opacity 300ms ease;
|
||||
}
|
||||
|
||||
.app-preview__phone-image {
|
||||
position: absolute;
|
||||
top: -0.03%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
height: 175.34%;
|
||||
transition: opacity 300ms ease;
|
||||
}
|
||||
|
||||
.app-preview__control-wrap {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
align-self: stretch;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.app-preview__control-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.app-preview__button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: #f08458;
|
||||
border: 0;
|
||||
border-radius: 9999px;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background-color 160ms ease,
|
||||
transform 160ms ease;
|
||||
}
|
||||
|
||||
.app-preview__button:hover {
|
||||
background: #e07a3b;
|
||||
}
|
||||
|
||||
.app-preview__button:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.app-preview__button-icon {
|
||||
display: block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.app-preview__button-icon--next {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.app-preview__center-phone {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
width: min(420px, calc(100vw - 168px));
|
||||
aspect-ratio: 459 / 542;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (max-width: 594px) {
|
||||
.app-preview__carousel {
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.app-preview__button {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.app-preview__button-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.app-preview__center-phone {
|
||||
width: min(420px, calc(100vw - 120px));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 554px) {
|
||||
.app-preview__carousel {
|
||||
gap: 8px;
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.app-preview__button {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.app-preview__button-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.app-preview__center-phone {
|
||||
width: min(420px, calc(100vw - 104px));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 540px) {
|
||||
.app-preview__center-phone {
|
||||
width: min(390px, calc(100vw - 120px));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.app-preview__title {
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.app-preview__carousel {
|
||||
gap: clamp(10px, 1.4vw, 16px);
|
||||
padding: 0 clamp(16px, 3vw, 32px);
|
||||
}
|
||||
|
||||
.app-preview__side-phone,
|
||||
.app-preview__control-wrap {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.app-preview__side-phone {
|
||||
display: block;
|
||||
width: clamp(128px, 17vw, 190px);
|
||||
height: auto;
|
||||
aspect-ratio: 336 / 396;
|
||||
}
|
||||
|
||||
.app-preview__center-phone {
|
||||
width: clamp(220px, 31vw, 320px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.app-preview {
|
||||
padding: 120px clamp(32px, 6vw, 130px) 0;
|
||||
}
|
||||
|
||||
.app-preview__title {
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.app-preview__description {
|
||||
font-size: 18px;
|
||||
letter-spacing: var(--ls-18);
|
||||
}
|
||||
|
||||
.app-preview__side-phone,
|
||||
.app-preview__control-wrap {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.app-preview__carousel {
|
||||
gap: clamp(16px, 1.4vw, 20px);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.app-preview__side-phone {
|
||||
display: block;
|
||||
width: clamp(190px, 20vw, 336px);
|
||||
}
|
||||
|
||||
.app-preview__center-phone {
|
||||
width: clamp(300px, 27vw, 459px);
|
||||
height: auto;
|
||||
aspect-ratio: 459 / 542;
|
||||
}
|
||||
}
|
||||
488
src/styles/sections.css
Normal file
@@ -0,0 +1,488 @@
|
||||
.experience {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding: 60px 16px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.experience__inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
max-width: 1008px;
|
||||
gap: 40px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.experience__heading {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.experience__title {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
letter-spacing: var(--ls-28);
|
||||
color: #1a1a1a;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.experience__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.experience__grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.experience-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: 36px;
|
||||
padding: 0 0 36px;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(to bottom, #fef0eb, #fff);
|
||||
border-radius: 30px 30px 0 0;
|
||||
}
|
||||
|
||||
.experience-card__media {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
aspect-ratio: 320 / 232;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.experience-card__media--tinted {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
background: #ffeddf;
|
||||
}
|
||||
|
||||
.experience-card__media-crop {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.experience-card__image {
|
||||
position: absolute;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.experience-card__image--one {
|
||||
top: -86.5%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 298.5%;
|
||||
}
|
||||
|
||||
.experience-card__image--two {
|
||||
top: -137.86%;
|
||||
left: -3.13%;
|
||||
width: 130.62%;
|
||||
height: 389.91%;
|
||||
}
|
||||
|
||||
.experience-card__image--three {
|
||||
top: -115.66%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 298.5%;
|
||||
}
|
||||
|
||||
.experience-card__copy {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
gap: 16px;
|
||||
max-width: 248px;
|
||||
padding: 0;
|
||||
overflow: clip;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.experience-card__title {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
letter-spacing: var(--ls-24);
|
||||
color: #0d0d0d;
|
||||
}
|
||||
|
||||
.experience-card__description {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-16);
|
||||
color: #7a726d;
|
||||
}
|
||||
|
||||
.experience__caption {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-15);
|
||||
color: #7a726d;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.use-cases {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding: 60px 16px;
|
||||
background: #fef0eb;
|
||||
}
|
||||
|
||||
.use-cases__inner {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
gap: 32px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.use-cases__copy {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
gap: 24px;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
@media (max-width: 1294px) {
|
||||
.use-cases__inner {
|
||||
grid-template-columns: minmax(0, 1128px);
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.use-cases__copy {
|
||||
justify-self: start;
|
||||
width: min(580px, 100%);
|
||||
max-width: 580px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.use-cases__title,
|
||||
.use-cases__description {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.section-eyebrow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
padding: 12px 24px;
|
||||
background: #fff;
|
||||
border: 1px solid #fbbfa3;
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.section-eyebrow__text {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
letter-spacing: var(--ls-14);
|
||||
color: #f08458;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.use-cases__title {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
letter-spacing: var(--ls-28);
|
||||
color: #1a1a1a;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.use-cases__description {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-15);
|
||||
color: #7a726d;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.use-cases__copy {
|
||||
align-items: flex-start;
|
||||
justify-self: stretch;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.use-cases__title,
|
||||
.use-cases__description {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.use-cases__rows {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
width: 100%;
|
||||
max-width: 1128px;
|
||||
min-width: 0;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
border-radius: 30px;
|
||||
gap: 1px;
|
||||
}
|
||||
|
||||
.use-case-row {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
background: #faede8;
|
||||
}
|
||||
|
||||
.use-case-row__title-cell,
|
||||
.use-case-row__description-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
padding: 16px 24px;
|
||||
}
|
||||
|
||||
.use-case-row__title-cell {
|
||||
background: #f08458;
|
||||
}
|
||||
|
||||
.use-case-row__description-cell {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.use-case-row__title {
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
letter-spacing: var(--ls-18);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.use-case-row__description {
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-15);
|
||||
color: #7a726d;
|
||||
}
|
||||
|
||||
@media (max-width: 578px) {
|
||||
.use-cases__rows {
|
||||
gap: 24px;
|
||||
overflow: visible;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.use-case-row {
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.use-case-row__title-cell,
|
||||
.use-case-row__description-cell {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.use-case-row__title {
|
||||
font-size: 20px;
|
||||
letter-spacing: var(--ls-20);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 440px) {
|
||||
.experience,
|
||||
.use-cases {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.experience__title,
|
||||
.use-cases__title {
|
||||
font-size: 32px;
|
||||
letter-spacing: var(--ls-32);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
.experience,
|
||||
.use-cases {
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
.experience__title,
|
||||
.use-cases__title {
|
||||
font-size: 36px;
|
||||
letter-spacing: var(--ls-36);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 578px) {
|
||||
.experience__grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 320px));
|
||||
}
|
||||
|
||||
.experience-card {
|
||||
max-width: 320px;
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
.experience-card:nth-child(3):last-child {
|
||||
grid-column: 1 / -1;
|
||||
justify-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 578px) {
|
||||
.use-case-row {
|
||||
grid-template-columns: minmax(220px, 300px) minmax(280px, 1fr);
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.use-case-row__title-cell,
|
||||
.use-case-row__description-cell {
|
||||
padding: 24px 36px;
|
||||
}
|
||||
|
||||
.use-case-row__title {
|
||||
font-size: 20px;
|
||||
letter-spacing: var(--ls-20);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.experience,
|
||||
.use-cases {
|
||||
padding-left: 36px;
|
||||
padding-right: 36px;
|
||||
}
|
||||
|
||||
.experience__title,
|
||||
.use-cases__title {
|
||||
font-size: 42px;
|
||||
letter-spacing: var(--ls-42);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.experience__grid {
|
||||
grid-template-columns: repeat(3, minmax(0, 320px));
|
||||
}
|
||||
|
||||
.experience-card:nth-child(3):last-child {
|
||||
grid-column: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
.experience-card__title {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.experience {
|
||||
padding-top: 60px;
|
||||
padding-bottom: 60px;
|
||||
padding-left: 36px;
|
||||
padding-right: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.experience__title,
|
||||
.use-cases__title {
|
||||
font-size: 48px;
|
||||
letter-spacing: var(--ls-48);
|
||||
}
|
||||
|
||||
.experience__caption,
|
||||
.use-cases__description {
|
||||
font-size: 18px;
|
||||
letter-spacing: var(--ls-18);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1201px) {
|
||||
.use-cases {
|
||||
padding: 60px 64px;
|
||||
}
|
||||
|
||||
.use-cases__inner {
|
||||
grid-template-columns: minmax(420px, 540px) minmax(560px, 1fr);
|
||||
align-items: center;
|
||||
gap: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1376px) {
|
||||
.experience {
|
||||
padding-top: 120px;
|
||||
padding-bottom: 120px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.use-cases {
|
||||
padding-top: 120px;
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1440px) {
|
||||
.use-cases {
|
||||
padding-right: 130px;
|
||||
padding-left: 130px;
|
||||
}
|
||||
}
|
||||
328
src/styles/trust.css
Normal file
@@ -0,0 +1,328 @@
|
||||
.trust {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding: 60px 16px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.trust__inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
gap: 40px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.trust__header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
gap: 24px;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
.trust__title {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
letter-spacing: var(--ls-28);
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.trust__description {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-15);
|
||||
color: #7a726d;
|
||||
}
|
||||
|
||||
.trust__grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.trust-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
min-width: 0;
|
||||
gap: 16px;
|
||||
padding: 24px;
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
.trust-card__icon-frame {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
}
|
||||
|
||||
.trust-card__icon-crop {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.trust-card__icon {
|
||||
position: absolute;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.trust-card__icon--one {
|
||||
top: 7.04%;
|
||||
left: -31.48%;
|
||||
width: 312.73%;
|
||||
height: 174.55%;
|
||||
}
|
||||
|
||||
.trust-card__icon--two {
|
||||
top: 3.1%;
|
||||
left: -164.72%;
|
||||
width: 335.61%;
|
||||
height: 187.32%;
|
||||
}
|
||||
|
||||
.trust-card__icon--three {
|
||||
top: -105.62%;
|
||||
left: -187.93%;
|
||||
width: 378.86%;
|
||||
height: 211.46%;
|
||||
}
|
||||
|
||||
.trust-card__icon--four {
|
||||
top: 0;
|
||||
left: 4.14%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.trust-card__copy {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.trust-card__title {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
letter-spacing: var(--ls-16);
|
||||
color: #0d0d0d;
|
||||
}
|
||||
|
||||
.trust-card__description {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-15);
|
||||
color: #7a726d;
|
||||
}
|
||||
|
||||
.trust__divider {
|
||||
position: relative;
|
||||
display: none; /* shown only in desktop flex row via 1023px breakpoint */
|
||||
flex-shrink: 0;
|
||||
width: 0;
|
||||
height: 118px;
|
||||
}
|
||||
|
||||
.trust__divider-frame {
|
||||
position: absolute;
|
||||
inset: 0 -0.5px;
|
||||
}
|
||||
|
||||
.trust__divider-image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 1023px) {
|
||||
.trust-card__copy {
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.trust-card__title,
|
||||
.trust-card__description {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 440px) {
|
||||
.trust {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.trust__title {
|
||||
font-size: 32px;
|
||||
letter-spacing: var(--ls-32);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
.trust {
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
.trust__title {
|
||||
font-size: 36px;
|
||||
letter-spacing: var(--ls-36);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.trust {
|
||||
padding-left: 36px;
|
||||
padding-right: 36px;
|
||||
}
|
||||
|
||||
.trust__title {
|
||||
font-size: 42px;
|
||||
letter-spacing: var(--ls-42);
|
||||
}
|
||||
|
||||
.trust__grid {
|
||||
position: relative;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) and (max-width: 1023px) {
|
||||
.trust__grid > .trust-card:nth-child(1),
|
||||
.trust__grid > .trust-card:nth-child(5) {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.trust__grid > .trust-card:nth-child(1)::after,
|
||||
.trust__grid > .trust-card:nth-child(5)::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: -16px;
|
||||
transform: translateY(-50%);
|
||||
width: 0;
|
||||
height: 118px;
|
||||
border-left: 1px solid rgba(240, 132, 88, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.trust {
|
||||
padding-top: 60px;
|
||||
padding-bottom: 60px;
|
||||
padding-left: 28px;
|
||||
padding-right: 28px;
|
||||
}
|
||||
|
||||
.trust__grid {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.trust-card {
|
||||
flex: 1;
|
||||
padding: 16px 8px;
|
||||
}
|
||||
|
||||
.trust-card__icon-frame {
|
||||
width: 112px;
|
||||
height: 112px;
|
||||
}
|
||||
|
||||
.trust-card__copy {
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.trust-card__title {
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
letter-spacing: var(--ls-15);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.trust-card__description {
|
||||
font-size: 14px;
|
||||
line-height: 1.45;
|
||||
letter-spacing: var(--ls-14);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.trust__divider {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.trust__title {
|
||||
font-size: 48px;
|
||||
letter-spacing: var(--ls-48);
|
||||
}
|
||||
|
||||
.trust__description {
|
||||
font-size: 18px;
|
||||
letter-spacing: var(--ls-18);
|
||||
}
|
||||
|
||||
.trust__grid {
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.trust-card {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.trust-card__icon-frame {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
}
|
||||
|
||||
.trust-card__title {
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
letter-spacing: var(--ls-16);
|
||||
}
|
||||
|
||||
.trust-card__description {
|
||||
font-size: 15px;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-15);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1376px) {
|
||||
.trust {
|
||||
padding-top: 120px;
|
||||
padding-bottom: 120px;
|
||||
padding-left: 120px;
|
||||
padding-right: 120px;
|
||||
}
|
||||
}
|
||||
317
src/styles/why.css
Normal file
@@ -0,0 +1,317 @@
|
||||
.why {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding: 60px 16px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.why__inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
gap: 40px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.why__intro {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
gap: 36px;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
.why__copy {
|
||||
display: flex;
|
||||
order: 2;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
min-width: 0;
|
||||
gap: 36px;
|
||||
}
|
||||
|
||||
.why__text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.why__title {
|
||||
width: 100%;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
letter-spacing: var(--ls-28);
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.why__title-line {
|
||||
margin: 0;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.why__underline {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
width: 295.5px;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.why__underline-frame {
|
||||
position: absolute;
|
||||
inset: -0.5px 0;
|
||||
}
|
||||
|
||||
.why__underline-image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.why__description {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-15);
|
||||
color: #7a726d;
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.why__description {
|
||||
font-size: 18px;
|
||||
letter-spacing: var(--ls-18);
|
||||
}
|
||||
}
|
||||
|
||||
.why__illustration {
|
||||
position: relative;
|
||||
display: block;
|
||||
order: 1;
|
||||
align-self: center;
|
||||
flex-shrink: 0;
|
||||
width: 480px;
|
||||
max-width: calc(100vw - 32px);
|
||||
height: 480px;
|
||||
max-height: calc(100vw - 32px);
|
||||
}
|
||||
|
||||
.why__illustration-image {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.why__grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
width: 100%;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.why-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
gap: 20px;
|
||||
padding: 20px 16px;
|
||||
overflow: clip;
|
||||
background: #fef0eb;
|
||||
border: 1px solid #e8e4de;
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
.why-card__icon-frame {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
overflow: clip;
|
||||
background: #f08458;
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.why-card__icon {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.why-card__icon--simple {
|
||||
width: 33.001px;
|
||||
height: 32.973px;
|
||||
}
|
||||
|
||||
.why-card__icon--familiar {
|
||||
width: 28.5px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.why-card__icon--connected {
|
||||
width: 33px;
|
||||
height: 32.936px;
|
||||
}
|
||||
|
||||
.why-card__icon--modern {
|
||||
width: 18.125px;
|
||||
height: 33px;
|
||||
}
|
||||
|
||||
.why-card__copy {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
min-width: 0;
|
||||
gap: 12px;
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
.why-card__title {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 23px;
|
||||
letter-spacing: var(--ls-20);
|
||||
color: #0d0d0d;
|
||||
}
|
||||
|
||||
.why-card__description {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 1.5;
|
||||
letter-spacing: var(--ls-16);
|
||||
color: #7a726d;
|
||||
}
|
||||
|
||||
@media (min-width: 440px) {
|
||||
.why {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.why-card {
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.why-card__icon-frame {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.why-card__icon--simple {
|
||||
width: 44.001px;
|
||||
height: 43.964px;
|
||||
}
|
||||
|
||||
.why-card__icon--familiar {
|
||||
width: 38px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.why-card__icon--connected {
|
||||
width: 44px;
|
||||
height: 43.914px;
|
||||
}
|
||||
|
||||
.why-card__icon--modern {
|
||||
width: 24.168px;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.why__title {
|
||||
font-size: 32px;
|
||||
letter-spacing: var(--ls-32);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
.why {
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
.why__title {
|
||||
font-size: 36px;
|
||||
letter-spacing: var(--ls-36);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.why {
|
||||
padding-left: 36px;
|
||||
padding-right: 36px;
|
||||
}
|
||||
|
||||
.why__title {
|
||||
font-size: 42px;
|
||||
letter-spacing: var(--ls-42);
|
||||
}
|
||||
|
||||
.why-card {
|
||||
padding: 36px;
|
||||
min-height: 152px;
|
||||
}
|
||||
|
||||
.why-card__title {
|
||||
font-size: 24px;
|
||||
letter-spacing: var(--ls-24);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.why {
|
||||
padding-top: 60px;
|
||||
padding-bottom: 60px;
|
||||
padding-left: 36px;
|
||||
padding-right: 36px;
|
||||
}
|
||||
|
||||
.why__grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.why__intro {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.why__copy {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.why__illustration {
|
||||
order: 2;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.why__title {
|
||||
font-size: 48px;
|
||||
letter-spacing: var(--ls-48);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1376px) {
|
||||
.why {
|
||||
padding-top: 120px;
|
||||
padding-bottom: 120px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,3 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {}
|
||||
}
|
||||
"extends": "./node_modules/astro/tsconfigs/strict.json"
|
||||
}
|
||||
|
||||