Compare commits
38 Commits
e5bcb7bad2
...
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 |
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.*
|
.env.*
|
||||||
!.env.example
|
!.env.example
|
||||||
|
!.env.deploy.example
|
||||||
|
.env.deploy
|
||||||
|
|||||||
57
README.md
@@ -26,6 +26,28 @@ Open [http://localhost:4321](http://localhost:4321)
|
|||||||
| `npm run build` | Build for production into `dist/` |
|
| `npm run build` | Build for production into `dist/` |
|
||||||
| `npm run preview` | Preview production build locally |
|
| `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
|
## 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
|
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
|
## Design Source
|
||||||
|
|
||||||
Figma: [Talk Pro — Home Page Desktop](https://www.figma.com/design/Gb8WMJ2RLlcZ0bigoiOQx9/Talk-Pro?node-id=9505-537&m=dev)
|
Figma: [Talk Pro — Home Page Desktop](https://www.figma.com/design/Gb8WMJ2RLlcZ0bigoiOQx9/Talk-Pro?node-id=9505-537&m=dev)
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 716 KiB After Width: | Height: | Size: 414 KiB |
|
Before Width: | Height: | Size: 427 KiB After Width: | Height: | Size: 386 KiB |
|
Before Width: | Height: | Size: 602 KiB After Width: | Height: | Size: 316 KiB |
|
Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 473 KiB |
@@ -1,6 +1,13 @@
|
|||||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g id="Icon">
|
<g clip-path="url(#clip0_9846_29800)">
|
||||||
<rect width="44" height="44" rx="12" fill="var(--fill-0, #D55F31)"/>
|
<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 id="Vector" d="M23.8954 10H15.6259C14.728 10 14 10.8028 14 11.793V32.207C14 33.1972 14.728 34 15.6259 34H28.3741C29.272 34 30 33.1972 30 32.207V16.7328C30 16.1165 29.7778 15.5252 29.3827 15.0895L25.3848 10.6807C24.9897 10.245 24.4536 10 23.8947 10H23.8954Z" fill="var(--fill-0, 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>
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_9846_29800">
|
||||||
|
<rect width="28" height="28" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 559 B After Width: | Height: | Size: 2.2 KiB |
@@ -1,4 +1,4 @@
|
|||||||
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 1920 923" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<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)">
|
<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" 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_2" d="M102.45 -30.0001L90.2725 -17.7969L102.45 -5.59361L114.627 -17.7969L102.45 -30.0001Z" fill="var(--fill-0, #FFF0E8)"/>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 343 KiB After Width: | Height: | Size: 369 KiB |
|
Before Width: | Height: | Size: 201 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 284 KiB After Width: | Height: | Size: 206 KiB |
|
Before Width: | Height: | Size: 848 KiB After Width: | Height: | Size: 880 KiB |
BIN
public/assets/why-illustration.mp4
Normal file
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}`
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
import { assetPath } from '../assets'
|
||||||
import type { Translations } from '../i18n/translations'
|
import type { Translations } from '../i18n/translations'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
@@ -7,10 +8,12 @@ export interface Props {
|
|||||||
|
|
||||||
const { t } = Astro.props
|
const { t } = Astro.props
|
||||||
const slides = [
|
const slides = [
|
||||||
"/assets/preview-phone.png",
|
assetPath("/assets/preview-phone.png"),
|
||||||
"/assets/preview-phone.png",
|
assetPath("/assets/preview-phone.png"),
|
||||||
"/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">
|
<section class="app-preview">
|
||||||
@@ -31,7 +34,7 @@ const slides = [
|
|||||||
<div class="app-preview__control-wrap">
|
<div class="app-preview__control-wrap">
|
||||||
<div class="app-preview__control-inner">
|
<div class="app-preview__control-inner">
|
||||||
<button id="btn-prev" class="app-preview__button">
|
<button id="btn-prev" class="app-preview__button">
|
||||||
<img alt={t.previous} class="app-preview__button-icon" src="/assets/preview-arrow-left.svg" />
|
<img alt={t.previous} class="app-preview__button-icon" src={arrowLeft} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,7 +46,7 @@ const slides = [
|
|||||||
<div class="app-preview__control-wrap">
|
<div class="app-preview__control-wrap">
|
||||||
<div class="app-preview__control-inner">
|
<div class="app-preview__control-inner">
|
||||||
<button id="btn-next" class="app-preview__button">
|
<button id="btn-next" class="app-preview__button">
|
||||||
<img alt={t.next} class="app-preview__button-icon app-preview__button-icon--next" src="/assets/preview-arrow-right.svg" />
|
<img alt={t.next} class="app-preview__button-icon app-preview__button-icon--next" src={arrowRight} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
import { assetPath } from '../assets'
|
||||||
import type { Translations } from '../i18n/translations'
|
import type { Translations } from '../i18n/translations'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
@@ -6,14 +7,14 @@ export interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { t } = Astro.props
|
const { t } = Astro.props
|
||||||
const halftone = "/assets/core-halftone-bg.png";
|
const halftone = assetPath("/assets/core-halftone-bg.png");
|
||||||
const icons = [
|
const icons = [
|
||||||
"/assets/core-icon-private.png",
|
assetPath("/assets/core-icon-private.png"),
|
||||||
"/assets/core-icon-groups.png",
|
assetPath("/assets/core-icon-groups.png"),
|
||||||
"/assets/core-icon-channels.png",
|
assetPath("/assets/core-icon-channels.png"),
|
||||||
"/assets/core-icon-voice.png",
|
assetPath("/assets/core-icon-voice.png"),
|
||||||
"/assets/core-icon-video.png",
|
assetPath("/assets/core-icon-video.png"),
|
||||||
"/assets/core-icon-media.png",
|
assetPath("/assets/core-icon-media.png"),
|
||||||
]
|
]
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
---
|
---
|
||||||
|
import { assetPath } from '../assets'
|
||||||
import type { Translations } from '../i18n/translations'
|
import type { Translations } from '../i18n/translations'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
t: Translations['download']
|
t: Translations['download']
|
||||||
|
siteLinks: Translations['siteLinks']
|
||||||
}
|
}
|
||||||
|
|
||||||
const { t } = Astro.props
|
const { t, siteLinks } = Astro.props
|
||||||
const bgPattern = "/assets/cta-bg-pattern.svg";
|
const bgPattern = assetPath("/assets/cta-bg-pattern.svg");
|
||||||
const talkproLogo = "/assets/cta-talkpro-logo.svg";
|
const talkproLogo = assetPath("/assets/cta-talkpro-logo.svg");
|
||||||
const androidIcon = "/assets/cta-android-icon.svg";
|
const androidIcon = assetPath("/assets/cta-android-icon.svg");
|
||||||
const appleIcon = "/assets/cta-apple-icon.svg";
|
const appleIcon = assetPath("/assets/cta-apple-icon.svg");
|
||||||
const phoneArt = "/assets/cta-phone-art.png";
|
const phoneArt = assetPath("/assets/cta-phone-art.png");
|
||||||
|
const defaultApkHref = "https://talkspro.xyz/download";
|
||||||
|
const siteLinksJson = JSON.stringify(siteLinks);
|
||||||
---
|
---
|
||||||
|
|
||||||
<section id="download" class="download-cta">
|
<section id="download" class="download-cta">
|
||||||
@@ -35,14 +39,25 @@ const phoneArt = "/assets/cta-phone-art.png";
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="store-badges">
|
<div class="store-badges">
|
||||||
<div class="store-badge store-badge--android">
|
<a
|
||||||
<img alt={t.androidAlt} class="store-badge__icon" src={androidIcon} />
|
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">
|
<div class="store-badge__copy">
|
||||||
<p class="store-badge__platform">{t.android}</p>
|
<p class="store-badge__platform">{t.android}</p>
|
||||||
<p class="store-badge__label">{t.androidCta}</p>
|
<p class="store-badge__label">{t.androidCta}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
<div class="store-badge store-badge--ios">
|
<a
|
||||||
|
class="store-badge store-badge--ios store-badge--apple"
|
||||||
|
href="#"
|
||||||
|
data-app-soon="1"
|
||||||
|
>
|
||||||
<div class="store-badge__icon-frame">
|
<div class="store-badge__icon-frame">
|
||||||
<img alt={t.appleAlt} class="store-badge__apple-icon" src={appleIcon} />
|
<img alt={t.appleAlt} class="store-badge__apple-icon" src={appleIcon} />
|
||||||
</div>
|
</div>
|
||||||
@@ -50,8 +65,9 @@ const phoneArt = "/assets/cta-phone-art.png";
|
|||||||
<p class="store-badge__platform">{t.ios}</p>
|
<p class="store-badge__platform">{t.ios}</p>
|
||||||
<p class="store-badge__label">{t.iosCta}</p>
|
<p class="store-badge__label">{t.iosCta}</p>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="download-cta__phone">
|
<div class="download-cta__phone">
|
||||||
@@ -61,3 +77,5 @@ const phoneArt = "/assets/cta-phone-art.png";
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<script type="application/json" id="site-links-i18n" set:html={siteLinksJson} />
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
import { assetPath } from '../assets'
|
||||||
import type { Translations } from '../i18n/translations'
|
import type { Translations } from '../i18n/translations'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
@@ -6,16 +7,26 @@ export interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { t } = Astro.props
|
const { t } = Astro.props
|
||||||
const images = ["/assets/exp-card-1.png", "/assets/exp-card-2.png", "/assets/exp-card-3.png"]
|
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']
|
const imageClasses = ['experience-card__image--one', 'experience-card__image--two', 'experience-card__image--three']
|
||||||
---
|
---
|
||||||
|
|
||||||
<section id="experience" class="experience">
|
<section id="experience" class="experience">
|
||||||
<div class="experience__inner">
|
<div class="experience__inner">
|
||||||
|
<div class="experience__heading">
|
||||||
<p class="experience__title">
|
<p class="experience__title">
|
||||||
{t.title}
|
{t.title}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p class="experience__caption">
|
||||||
|
{t.caption}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="experience__body">
|
<div class="experience__body">
|
||||||
<div class="experience__grid">
|
<div class="experience__grid">
|
||||||
{t.cards.map((card, index) => (
|
{t.cards.map((card, index) => (
|
||||||
@@ -36,10 +47,6 @@ const imageClasses = ['experience-card__image--one', 'experience-card__image--tw
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="experience__caption">
|
|
||||||
{t.caption}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
import { assetPath } from '../assets'
|
||||||
import type { Translations } from '../i18n/translations'
|
import type { Translations } from '../i18n/translations'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
@@ -6,9 +7,7 @@ export interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { t } = Astro.props
|
const { t } = Astro.props
|
||||||
const logoFull = "/assets/footer-logo.png";
|
const logoFull = assetPath("/assets/footer-logo.png");
|
||||||
const androidIcon = "/assets/footer-android-icon.svg";
|
|
||||||
const appleIcon = "/assets/footer-apple-icon.svg";
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<footer class="site-footer">
|
<footer class="site-footer">
|
||||||
@@ -21,37 +20,6 @@ const appleIcon = "/assets/footer-apple-icon.svg";
|
|||||||
<p class="site-footer__description">
|
<p class="site-footer__description">
|
||||||
{t.description}
|
{t.description}
|
||||||
</p>
|
</p>
|
||||||
<div class="store-badges">
|
|
||||||
<div class="store-badge store-badge--android">
|
|
||||||
<img alt="Android" class="store-badge__icon" src={androidIcon} />
|
|
||||||
<div class="store-badge__copy">
|
|
||||||
<p class="store-badge__platform">{t.android}</p>
|
|
||||||
<p class="store-badge__label">{t.androidCta}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="store-badge store-badge--ios">
|
|
||||||
<div class="store-badge__icon-frame">
|
|
||||||
<img alt="Apple" 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>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="site-footer__links">
|
|
||||||
<div class="site-footer__link-column">
|
|
||||||
<a href="#download" class="site-footer__link">{t.links.download}</a>
|
|
||||||
<a href="#features" class="site-footer__link">{t.links.features}</a>
|
|
||||||
<a href="#" class="site-footer__link">{t.links.about}</a>
|
|
||||||
</div>
|
|
||||||
<div class="site-footer__link-column">
|
|
||||||
<p class="site-footer__text site-footer__text--heading">{t.links.contact}</p>
|
|
||||||
<p class="site-footer__text">{t.email}</p>
|
|
||||||
<p class="site-footer__text">{t.phone}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
import { assetPath } from '../assets'
|
||||||
import { getLocalePath, languageLabels, languageNames, languages, type Lang, type Translations } from '../i18n/translations'
|
import { getLocalePath, languageLabels, languageNames, languages, type Lang, type Translations } from '../i18n/translations'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
@@ -7,9 +8,9 @@ export interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { lang, t } = Astro.props
|
const { lang, t } = Astro.props
|
||||||
const logoIcon = "/assets/header-logo-icon.png";
|
const logoIcon = assetPath("/assets/header-logo-icon.png");
|
||||||
const logoWordmark = "/assets/header-logo-wordmark.svg";
|
const logoWordmark = assetPath("/assets/header-logo-wordmark.svg");
|
||||||
const globeIcon = "/assets/header-globe.svg";
|
const globeIcon = assetPath("/assets/header-globe.svg");
|
||||||
const navItems = [
|
const navItems = [
|
||||||
{ href: '#hero', label: t.nav.home },
|
{ href: '#hero', label: t.nav.home },
|
||||||
{ href: '#features', label: t.nav.features },
|
{ href: '#features', label: t.nav.features },
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
---
|
---
|
||||||
|
import { assetPath } from '../assets'
|
||||||
import type { Translations } from '../i18n/translations'
|
import type { Translations } from '../i18n/translations'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
t: Translations['hero']
|
t: Translations['hero']
|
||||||
|
download: Translations['download']
|
||||||
}
|
}
|
||||||
|
|
||||||
const { t } = Astro.props
|
const { t, download } = Astro.props
|
||||||
const heroBg = "/assets/hero-bg.png";
|
const heroBg = assetPath("/assets/hero-bg.png");
|
||||||
const phoneMockup = "/assets/hero-phone.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 id="hero" class="hero">
|
<section id="hero" class="hero">
|
||||||
@@ -36,11 +41,32 @@ const phoneMockup = "/assets/hero-phone.png";
|
|||||||
{t.description}
|
{t.description}
|
||||||
</p>
|
</p>
|
||||||
<div class="hero__actions">
|
<div class="hero__actions">
|
||||||
<a href="#download" class="hero__button hero__button--primary">
|
<a
|
||||||
<span class="hero__button-label">{t.download}</span>
|
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>
|
||||||
<a href="#features" class="hero__button hero__button--secondary">
|
<a
|
||||||
<span class="hero__button-label">{t.explore}</span>
|
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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
import { assetPath } from '../assets'
|
||||||
import type { Translations } from '../i18n/translations'
|
import type { Translations } from '../i18n/translations'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
@@ -6,6 +7,9 @@ export interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { t } = Astro.props
|
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 = [
|
const iconClasses = [
|
||||||
'trust-card__icon--one',
|
'trust-card__icon--one',
|
||||||
'trust-card__icon--two',
|
'trust-card__icon--two',
|
||||||
@@ -35,7 +39,7 @@ const iconClasses = [
|
|||||||
<img
|
<img
|
||||||
alt=""
|
alt=""
|
||||||
class={`trust-card__icon ${iconClasses[index]}`}
|
class={`trust-card__icon ${iconClasses[index]}`}
|
||||||
src={index === 3 ? "/assets/trust-icon-improvement.png" : "/assets/trust-icon-sprite.png"}
|
src={index === 3 ? trustIconImprovement : trustIconSprite}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -47,7 +51,7 @@ const iconClasses = [
|
|||||||
{index < t.cards.length - 1 && (
|
{index < t.cards.length - 1 && (
|
||||||
<div class="trust__divider">
|
<div class="trust__divider">
|
||||||
<div class="trust__divider-frame">
|
<div class="trust__divider-frame">
|
||||||
<img alt="" class="trust__divider-image" src="/assets/trust-divider.svg" />
|
<img alt="" class="trust__divider-image" src={trustDivider} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
import { assetPath } from '../assets'
|
||||||
import type { Translations } from '../i18n/translations'
|
import type { Translations } from '../i18n/translations'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
@@ -6,14 +7,15 @@ export interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { t } = Astro.props
|
const { t } = Astro.props
|
||||||
const underline = "/assets/why-underline.svg";
|
const underline = assetPath("/assets/why-underline.svg");
|
||||||
const icons = [
|
const icons = [
|
||||||
"/assets/why-icon-simple.svg",
|
assetPath("/assets/why-icon-simple.svg"),
|
||||||
"/assets/why-icon-familiar.svg",
|
assetPath("/assets/why-icon-familiar.svg"),
|
||||||
"/assets/why-icon-connected.svg",
|
assetPath("/assets/why-icon-connected.svg"),
|
||||||
"/assets/why-icon-modern.svg",
|
assetPath("/assets/why-icon-modern.svg"),
|
||||||
]
|
]
|
||||||
const iconClasses = ['why-card__icon--square', 'why-card__icon--familiar', 'why-card__icon--square', 'why-card__icon--modern']
|
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">
|
<section class="why">
|
||||||
@@ -40,7 +42,17 @@ const iconClasses = ['why-card__icon--square', 'why-card__icon--familiar', 'why-
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="why__illustration">
|
<div class="why__illustration">
|
||||||
<img alt={t.illustrationAlt} class="why__illustration-image" src="/assets/why-illustration.png" />
|
<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>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -27,10 +27,49 @@ const {
|
|||||||
</head>
|
</head>
|
||||||
<body class="bg-surface font-sans overflow-x-hidden">
|
<body class="bg-surface font-sans overflow-x-hidden">
|
||||||
<slot />
|
<slot />
|
||||||
|
<script src="/site-links-client.js?v=2" defer></script>
|
||||||
<script>
|
<script>
|
||||||
(() => {
|
(() => {
|
||||||
const header = document.getElementById('site-header');
|
const header = document.getElementById('site-header');
|
||||||
const getOffset = () => header ? header.offsetHeight : 0;
|
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 => {
|
document.querySelectorAll('a[href^="#"]').forEach(link => {
|
||||||
link.addEventListener('click', e => {
|
link.addEventListener('click', e => {
|
||||||
@@ -40,7 +79,8 @@ const {
|
|||||||
if (!target) return;
|
if (!target) return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const top = target.getBoundingClientRect().top + window.scrollY - getOffset();
|
const top = target.getBoundingClientRect().top + window.scrollY - getOffset();
|
||||||
window.scrollTo({ top, behavior: 'smooth' });
|
animateScrollTo(top);
|
||||||
|
history.pushState(null, '', href);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import CoreSystem from '../../components/CoreSystem.astro'
|
|||||||
import Experience from '../../components/Experience.astro'
|
import Experience from '../../components/Experience.astro'
|
||||||
import UseCases from '../../components/UseCases.astro'
|
import UseCases from '../../components/UseCases.astro'
|
||||||
import Trust from '../../components/Trust.astro'
|
import Trust from '../../components/Trust.astro'
|
||||||
import AppPreview from '../../components/AppPreview.astro'
|
|
||||||
import DownloadCTA from '../../components/DownloadCTA.astro'
|
import DownloadCTA from '../../components/DownloadCTA.astro'
|
||||||
import Footer from '../../components/Footer.astro'
|
import Footer from '../../components/Footer.astro'
|
||||||
import { defaultLang, getTranslations, isLang, languages } from '../../i18n/translations'
|
import { defaultLang, getTranslations, isLang, languages } from '../../i18n/translations'
|
||||||
@@ -25,13 +24,13 @@ const t = getTranslations(lang)
|
|||||||
|
|
||||||
<Base lang={lang} title={t.meta.title} description={t.meta.description}>
|
<Base lang={lang} title={t.meta.title} description={t.meta.description}>
|
||||||
<Header lang={lang} t={t.header} />
|
<Header lang={lang} t={t.header} />
|
||||||
<Hero t={t.hero} />
|
<Hero t={t.hero} download={t.download} />
|
||||||
<WhyTalkPro t={t.why} />
|
<WhyTalkPro t={t.why} />
|
||||||
<CoreSystem t={t.core} />
|
<CoreSystem t={t.core} />
|
||||||
<Experience t={t.experience} />
|
<Experience t={t.experience} />
|
||||||
<UseCases t={t.useCases} />
|
<UseCases t={t.useCases} />
|
||||||
<Trust t={t.trust} />
|
<Trust t={t.trust} />
|
||||||
<AppPreview t={t.preview} />
|
<!-- AppPreview section disabled per lead request. -->
|
||||||
<DownloadCTA t={t.download} />
|
<DownloadCTA t={t.download} siteLinks={t.siteLinks} />
|
||||||
<Footer t={t.footer} />
|
<Footer t={t.footer} />
|
||||||
</Base>
|
</Base>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import CoreSystem from '../components/CoreSystem.astro'
|
|||||||
import Experience from '../components/Experience.astro'
|
import Experience from '../components/Experience.astro'
|
||||||
import UseCases from '../components/UseCases.astro'
|
import UseCases from '../components/UseCases.astro'
|
||||||
import Trust from '../components/Trust.astro'
|
import Trust from '../components/Trust.astro'
|
||||||
import AppPreview from '../components/AppPreview.astro'
|
|
||||||
import DownloadCTA from '../components/DownloadCTA.astro'
|
import DownloadCTA from '../components/DownloadCTA.astro'
|
||||||
import Footer from '../components/Footer.astro'
|
import Footer from '../components/Footer.astro'
|
||||||
import { defaultLang, getTranslations } from '../i18n/translations'
|
import { defaultLang, getTranslations } from '../i18n/translations'
|
||||||
@@ -18,13 +17,13 @@ const t = getTranslations(lang)
|
|||||||
|
|
||||||
<Base lang={lang} title={t.meta.title} description={t.meta.description}>
|
<Base lang={lang} title={t.meta.title} description={t.meta.description}>
|
||||||
<Header lang={lang} t={t.header} />
|
<Header lang={lang} t={t.header} />
|
||||||
<Hero t={t.hero} />
|
<Hero t={t.hero} download={t.download} />
|
||||||
<WhyTalkPro t={t.why} />
|
<WhyTalkPro t={t.why} />
|
||||||
<CoreSystem t={t.core} />
|
<CoreSystem t={t.core} />
|
||||||
<Experience t={t.experience} />
|
<Experience t={t.experience} />
|
||||||
<UseCases t={t.useCases} />
|
<UseCases t={t.useCases} />
|
||||||
<Trust t={t.trust} />
|
<Trust t={t.trust} />
|
||||||
<AppPreview t={t.preview} />
|
<!-- AppPreview section disabled per lead request. -->
|
||||||
<DownloadCTA t={t.download} />
|
<DownloadCTA t={t.download} siteLinks={t.siteLinks} />
|
||||||
<Footer t={t.footer} />
|
<Footer t={t.footer} />
|
||||||
</Base>
|
</Base>
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
width: 100%;
|
width: 1920px;
|
||||||
max-width: 1920px;
|
max-width: none;
|
||||||
height: 923px;
|
height: 923px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
@@ -28,43 +28,51 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 1280px;
|
max-width: 1280px;
|
||||||
gap: 32px;
|
gap: 0px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 48px 16px;
|
padding: 60px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.download-cta__content {
|
.download-cta__content {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
order: 2;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
gap: 36px;
|
gap: 36px;
|
||||||
overflow: clip;
|
overflow: clip;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.download-cta__copy {
|
.download-cta__copy {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.download-cta__heading {
|
.download-cta__heading {
|
||||||
|
--download-heading-title-size: 32px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: nowrap;
|
||||||
align-items: flex-start;
|
align-items: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
gap: 20px;
|
gap: 16px;
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.download-cta__title {
|
.download-cta__title {
|
||||||
|
position: relative;
|
||||||
|
top: -4px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 32px;
|
flex-shrink: 0;
|
||||||
|
font-size: var(--download-heading-title-size);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
|
letter-spacing: var(--ls-32);
|
||||||
color: #1a1a1a;
|
color: #1a1a1a;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@@ -72,8 +80,8 @@
|
|||||||
.download-cta__logo-frame {
|
.download-cta__logo-frame {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 188px;
|
width: calc(var(--download-heading-title-size) * 3.9167);
|
||||||
height: 72px;
|
height: calc(var(--download-heading-title-size) * 1.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.download-cta__logo {
|
.download-cta__logo {
|
||||||
@@ -88,16 +96,20 @@
|
|||||||
.download-cta__description {
|
.download-cta__description {
|
||||||
max-width: 542px;
|
max-width: 542px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 18px;
|
font-size: 16px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: var(--ls-16);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.store-badges {
|
.store-badges {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-direction: column;
|
||||||
|
flex-wrap: nowrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
@@ -108,7 +120,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 100%;
|
width: 260px;
|
||||||
|
max-width: 100%;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
@@ -116,14 +129,29 @@
|
|||||||
border-radius: 20px;
|
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 {
|
.store-badge--android {
|
||||||
background: #f28a4b;
|
background: #f28a4b;
|
||||||
border: 1px solid #c5834e;
|
border: 1px solid #c5834e;
|
||||||
}
|
}
|
||||||
|
|
||||||
.store-badge--ios {
|
.store-badge--ios {
|
||||||
background: #383838;
|
background: #121212F0;
|
||||||
border: 1px solid #141414;
|
border: 1px solid #2C2C2C;
|
||||||
}
|
}
|
||||||
|
|
||||||
.store-badge__icon {
|
.store-badge__icon {
|
||||||
@@ -140,7 +168,7 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 44px;
|
width: 44px;
|
||||||
height: 44px;
|
height: 44px;
|
||||||
background: #151515;
|
background: #323232;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +178,16 @@
|
|||||||
height: 27px;
|
height: 27px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.store-badge--android .store-badge__icon-frame {
|
||||||
|
background: #d55f31;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-badge__android-icon {
|
||||||
|
display: block;
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
.store-badge__copy {
|
.store-badge__copy {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -162,10 +200,10 @@
|
|||||||
|
|
||||||
.store-badge__platform {
|
.store-badge__platform {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 11px;
|
font-size: 13px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
letter-spacing: 0.05px;
|
letter-spacing: var(--ls-13);
|
||||||
}
|
}
|
||||||
|
|
||||||
.store-badge--android .store-badge__platform {
|
.store-badge--android .store-badge__platform {
|
||||||
@@ -173,7 +211,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.store-badge--ios .store-badge__platform {
|
.store-badge--ios .store-badge__platform {
|
||||||
color: #ccc;
|
color: #949494;
|
||||||
}
|
}
|
||||||
|
|
||||||
.store-badge__label {
|
.store-badge__label {
|
||||||
@@ -181,15 +219,25 @@
|
|||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
letter-spacing: var(--ls-15);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.download-cta__phone {
|
.download-cta__phone {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: none;
|
display: block;
|
||||||
|
order: 1;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 418px;
|
width: 240px;
|
||||||
height: 510px;
|
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 {
|
.download-cta__phone-crop {
|
||||||
@@ -208,15 +256,41 @@
|
|||||||
height: 136.1%;
|
height: 136.1%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
@media (max-width: 397px) {
|
||||||
.store-badge {
|
.download-cta__heading {
|
||||||
width: 260px;
|
--download-heading-title-size: clamp(24px, 8vw, 32px);
|
||||||
|
gap: clamp(8px, 2.5vw, 12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-cta__title {
|
||||||
|
line-height: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@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 {
|
.download-cta__title {
|
||||||
font-size: 40px;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,15 +301,44 @@
|
|||||||
|
|
||||||
.download-cta__inner {
|
.download-cta__inner {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
gap: 0;
|
gap: 16px;
|
||||||
padding: 0;
|
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 {
|
.download-cta__title {
|
||||||
font-size: 48px;
|
letter-spacing: var(--ls-48);
|
||||||
}
|
}
|
||||||
|
|
||||||
.download-cta__phone {
|
.download-cta__phone {
|
||||||
display: block;
|
order: 2;
|
||||||
|
width: 418px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1280px) {
|
||||||
|
.download-cta__inner {
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
gap: 60px;
|
gap: 60px;
|
||||||
padding: 64px 0;
|
padding: 60px 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,9 +38,10 @@
|
|||||||
.features__title {
|
.features__title {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 32px;
|
font-size: 28px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
|
letter-spacing: var(--ls-28);
|
||||||
color: #1a1a1a;
|
color: #1a1a1a;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
@@ -48,9 +49,10 @@
|
|||||||
.features__description {
|
.features__description {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 18px;
|
font-size: 15px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: var(--ls-15);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
@@ -70,8 +72,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
gap: 24px;
|
||||||
padding: 32px;
|
padding: 36px;
|
||||||
background: rgba(255, 255, 255, 0.78);
|
background: rgba(255, 255, 255, 0.78);
|
||||||
border-radius: 30px;
|
border-radius: 30px;
|
||||||
}
|
}
|
||||||
@@ -105,9 +107,10 @@
|
|||||||
.feature-card__title {
|
.feature-card__title {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 24px;
|
font-size: 20px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
letter-spacing: var(--ls-20);
|
||||||
color: #2e2a28;
|
color: #2e2a28;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,34 +120,90 @@
|
|||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: var(--ls-15);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 440px) {
|
||||||
|
.features__header,
|
||||||
|
.features__grid {
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.features__title {
|
.features__title {
|
||||||
font-size: 40px;
|
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 {
|
.features__grid {
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.feature-card__title {
|
||||||
|
font-size: 24px;
|
||||||
|
letter-spacing: var(--ls-24);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
@media (min-width: 1024px) {
|
||||||
.features {
|
|
||||||
padding: 120px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.features__header {
|
.features__header {
|
||||||
padding: 0 180px;
|
padding: 0 clamp(36px, 14vw, 180px);
|
||||||
}
|
|
||||||
|
|
||||||
.features__title {
|
|
||||||
font-size: 48px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.features__grid {
|
.features__grid {
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
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;
|
padding: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1376px) {
|
||||||
|
.features {
|
||||||
|
padding-top: 120px;
|
||||||
|
padding-bottom: 120px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 64px 0;
|
padding: 60px 0;
|
||||||
background: #fef0eb;
|
background: #fef0eb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +30,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
flex-shrink: 0;
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
overflow: clip;
|
overflow: clip;
|
||||||
}
|
}
|
||||||
@@ -57,49 +58,10 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: var(--ls-14);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-footer__links {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-shrink: 0;
|
|
||||||
gap: 32px;
|
|
||||||
line-height: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.site-footer__link-column {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-start;
|
|
||||||
width: 160px;
|
|
||||||
gap: 24px;
|
|
||||||
overflow: clip;
|
|
||||||
}
|
|
||||||
|
|
||||||
.site-footer__link,
|
|
||||||
.site-footer__text {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: normal;
|
|
||||||
color: #4a4a4a;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.site-footer__link {
|
|
||||||
font-weight: 400;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: color 160ms ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.site-footer__link:hover {
|
|
||||||
color: #f28a4b;
|
|
||||||
}
|
|
||||||
|
|
||||||
.site-footer__text--heading {
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.site-footer__divider {
|
.site-footer__divider {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
@@ -119,6 +81,7 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
letter-spacing: var(--ls-14);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,10 +96,6 @@
|
|||||||
gap: 20px;
|
gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-footer__legal {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.site-footer__spacer {
|
.site-footer__spacer {
|
||||||
display: block;
|
display: block;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@@ -146,11 +105,11 @@
|
|||||||
|
|
||||||
@media (min-width: 1024px) {
|
@media (min-width: 1024px) {
|
||||||
.site-footer {
|
.site-footer {
|
||||||
padding: 120px 0;
|
padding: 60px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-footer__inner {
|
.site-footer__inner {
|
||||||
padding: 0;
|
padding: 0 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-footer__top {
|
.site-footer__top {
|
||||||
@@ -160,3 +119,13 @@
|
|||||||
gap: 0;
|
gap: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1280px) {
|
||||||
|
.site-footer__inner {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-footer__legal {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,3 +8,72 @@
|
|||||||
@import './features.css';
|
@import './features.css';
|
||||||
@import './trust.css';
|
@import './trust.css';
|
||||||
@import './preview.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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -86,6 +86,7 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
letter-spacing: var(--ls-14);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -118,7 +119,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.language-switcher__button:hover,
|
.language-switcher__button:hover,
|
||||||
.language-switcher__button[aria-expanded='true'] {
|
.language-switcher__button[aria-expanded="true"] {
|
||||||
border-color: #f28a4b;
|
border-color: #f28a4b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +134,7 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 14px;
|
line-height: 14px;
|
||||||
|
letter-spacing: var(--ls-14);
|
||||||
color: #2e2a28;
|
color: #2e2a28;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@@ -143,7 +145,8 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
z-index: 60;
|
z-index: 60;
|
||||||
width: 240px;
|
width: 240px;
|
||||||
overflow: hidden;
|
max-height: min(520px, calc(100vh - 96px));
|
||||||
|
overflow-y: auto;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border: 1px solid #e3d9d1;
|
border: 1px solid #e3d9d1;
|
||||||
border-radius: 18px;
|
border-radius: 18px;
|
||||||
@@ -156,13 +159,16 @@
|
|||||||
|
|
||||||
.language-switcher__option {
|
.language-switcher__option {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 18px 24px;
|
padding: 14px 24px;
|
||||||
font-size: 18px;
|
font-size: 14px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
letter-spacing: var(--ls-14);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: background-color 160ms ease, color 160ms ease;
|
transition:
|
||||||
|
background-color 160ms ease,
|
||||||
|
color 160ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-switcher__option:hover {
|
.language-switcher__option:hover {
|
||||||
@@ -195,6 +201,7 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
letter-spacing: var(--ls-14);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@@ -220,10 +227,14 @@
|
|||||||
background: #2e2a28;
|
background: #2e2a28;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
transform-origin: center;
|
transform-origin: center;
|
||||||
transition: transform 240ms ease, opacity 240ms ease;
|
transition:
|
||||||
|
transform 240ms ease,
|
||||||
|
opacity 240ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-nav {
|
.mobile-nav {
|
||||||
|
max-height: calc(100vh - 72px);
|
||||||
|
overflow-y: auto;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-top: 1px solid #e3d9d1;
|
border-top: 1px solid #e3d9d1;
|
||||||
}
|
}
|
||||||
@@ -245,9 +256,15 @@
|
|||||||
padding: 16px 0;
|
padding: 16px 0;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
letter-spacing: var(--ls-16);
|
||||||
color: #2e2a28;
|
color: #2e2a28;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-bottom: 1px solid #e3d9d1;
|
border-bottom: 1px solid #e3d9d1;
|
||||||
|
transition: color 160ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav__link.is-active {
|
||||||
|
color: #f28a4b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-nav__link--last {
|
.mobile-nav__link--last {
|
||||||
@@ -255,17 +272,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mobile-nav__languages {
|
.mobile-nav__languages {
|
||||||
display: flex;
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
gap: 12px 16px;
|
||||||
padding: 16px 0;
|
padding: 16px 0;
|
||||||
border-top: 1px solid #e3d9d1;
|
border-top: 1px solid #e3d9d1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-nav__language-link {
|
.mobile-nav__language-link {
|
||||||
font-size: 15px;
|
min-width: 0;
|
||||||
|
font-size: 14px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
line-height: 1.25;
|
||||||
|
letter-spacing: var(--ls-14);
|
||||||
color: #2e2a28;
|
color: #2e2a28;
|
||||||
|
text-align: center;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,15 +295,32 @@
|
|||||||
color: #f28a4b;
|
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 {
|
.mobile-nav__download-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
margin: 16px 0 8px;
|
margin: 16px 0 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-nav__download {
|
.mobile-nav__download {
|
||||||
display: block;
|
display: block;
|
||||||
|
width: 250px;
|
||||||
|
max-width: 100%;
|
||||||
padding: 14px 24px;
|
padding: 14px 24px;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
letter-spacing: var(--ls-15);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
.hero__inner {
|
.hero__inner {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column-reverse;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 1280px;
|
max-width: 1280px;
|
||||||
@@ -32,13 +32,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hero__phone-column {
|
.hero__phone-column {
|
||||||
display: none;
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 24px;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero__phone-frame {
|
.hero__phone-frame {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
z-index: 2;
|
||||||
aspect-ratio: 673 / 1108;
|
width: min(320px, 100%);
|
||||||
|
height: 527px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero__phone-crop {
|
.hero__phone-crop {
|
||||||
@@ -58,6 +66,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hero__content {
|
.hero__content {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
@@ -86,6 +96,7 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
letter-spacing: var(--ls-14);
|
||||||
color: #0d0d0d;
|
color: #0d0d0d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,9 +111,10 @@
|
|||||||
|
|
||||||
.hero__title {
|
.hero__title {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 40px;
|
font-size: 36px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
|
letter-spacing: var(--ls-36);
|
||||||
color: #2e2a28;
|
color: #2e2a28;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,9 +126,10 @@
|
|||||||
.hero__description {
|
.hero__description {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 18px;
|
font-size: 15px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: var(--ls-15);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,53 +137,23 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
width: 100%;
|
||||||
gap: 14px;
|
gap: 14px;
|
||||||
overflow: clip;
|
overflow: clip;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero__button {
|
.hero__store-badge {
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-shrink: 0;
|
|
||||||
padding: 14px 24px;
|
|
||||||
overflow: clip;
|
|
||||||
border-radius: 17px;
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: background-color 160ms ease;
|
transition:
|
||||||
|
transform 160ms ease,
|
||||||
|
filter 160ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero__button--primary {
|
.hero__store-badge:hover {
|
||||||
background: #f28a4b;
|
filter: brightness(0.96);
|
||||||
}
|
transform: translateY(-1px);
|
||||||
|
|
||||||
.hero__button--primary:hover {
|
|
||||||
background: #e07a3b;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero__button--secondary {
|
|
||||||
background: rgba(255, 255, 255, 0.55);
|
|
||||||
border: 1px solid #e3d9d1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero__button--secondary:hover {
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero__button-label {
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: normal;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero__button--primary .hero__button-label {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero__button--secondary .hero__button-label {
|
|
||||||
color: #2e2a28;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero__tags {
|
.hero__tags {
|
||||||
@@ -197,13 +180,93 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
letter-spacing: var(--ls-14);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
white-space: nowrap;
|
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) {
|
@media (min-width: 768px) {
|
||||||
.hero__title {
|
.hero__title {
|
||||||
font-size: 56px;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,24 +277,106 @@
|
|||||||
|
|
||||||
.hero__inner {
|
.hero__inner {
|
||||||
flex-direction: row;
|
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;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero__phone-column {
|
.hero__phone-column {
|
||||||
display: flex;
|
align-items: flex-start;
|
||||||
align-items: center;
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
height: 100%;
|
|
||||||
padding-top: 60px;
|
padding-top: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero__content {
|
.hero__phone-frame {
|
||||||
width: 660px;
|
position: static;
|
||||||
padding: 80px 0;
|
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 {
|
.hero__title {
|
||||||
font-size: 72px;
|
font-size: 72px;
|
||||||
|
letter-spacing: var(--ls-72);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,20 +33,24 @@
|
|||||||
.app-preview__description {
|
.app-preview__description {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 18px;
|
font-size: 15px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: var(--ls-15);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-preview__carousel {
|
.app-preview__carousel {
|
||||||
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
gap: 20px;
|
gap: 24px;
|
||||||
|
padding: 0 16px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-preview__side-phone {
|
.app-preview__side-phone {
|
||||||
@@ -72,7 +76,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.app-preview__control-wrap {
|
.app-preview__control-wrap {
|
||||||
display: none;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
@@ -96,7 +100,9 @@
|
|||||||
border: 0;
|
border: 0;
|
||||||
border-radius: 9999px;
|
border-radius: 9999px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color 160ms ease, transform 160ms ease;
|
transition:
|
||||||
|
background-color 160ms ease,
|
||||||
|
transform 160ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-preview__button:hover {
|
.app-preview__button:hover {
|
||||||
@@ -120,25 +126,67 @@
|
|||||||
.app-preview__center-phone {
|
.app-preview__center-phone {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 100%;
|
width: min(420px, calc(100vw - 168px));
|
||||||
aspect-ratio: 459 / 542;
|
aspect-ratio: 459 / 542;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
pointer-events: none;
|
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) {
|
@media (min-width: 768px) {
|
||||||
.app-preview__title {
|
.app-preview__title {
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
.app-preview__carousel {
|
||||||
.app-preview {
|
gap: clamp(10px, 1.4vw, 16px);
|
||||||
padding: 120px 130px 0;
|
padding: 0 clamp(16px, 3vw, 32px);
|
||||||
}
|
|
||||||
|
|
||||||
.app-preview__title {
|
|
||||||
font-size: 48px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-preview__side-phone,
|
.app-preview__side-phone,
|
||||||
@@ -148,11 +196,48 @@
|
|||||||
|
|
||||||
.app-preview__side-phone {
|
.app-preview__side-phone {
|
||||||
display: block;
|
display: block;
|
||||||
|
width: clamp(128px, 17vw, 190px);
|
||||||
|
height: auto;
|
||||||
|
aspect-ratio: 336 / 396;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-preview__center-phone {
|
.app-preview__center-phone {
|
||||||
width: 459px;
|
width: clamp(220px, 31vw, 320px);
|
||||||
height: 542px;
|
}
|
||||||
aspect-ratio: auto;
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 64px 16px;
|
padding: 60px 16px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,12 +18,21 @@
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.experience__heading {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
.experience__title {
|
.experience__title {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 32px;
|
font-size: 28px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
|
letter-spacing: var(--ls-28);
|
||||||
color: #1a1a1a;
|
color: #1a1a1a;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
@@ -37,7 +46,8 @@
|
|||||||
|
|
||||||
.experience__grid {
|
.experience__grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
|
grid-template-columns: minmax(0, 1fr);
|
||||||
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
}
|
}
|
||||||
@@ -47,7 +57,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
gap: 28px;
|
gap: 36px;
|
||||||
padding: 0 0 36px;
|
padding: 0 0 36px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: linear-gradient(to bottom, #fef0eb, #fff);
|
background: linear-gradient(to bottom, #fef0eb, #fff);
|
||||||
@@ -58,7 +68,7 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 232px;
|
aspect-ratio: 320 / 232;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,21 +92,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.experience-card__image--one {
|
.experience-card__image--one {
|
||||||
top: -58.58%;
|
top: -86.5%;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 298.5%;
|
height: 298.5%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.experience-card__image--two {
|
.experience-card__image--two {
|
||||||
top: -335.6%;
|
top: -137.86%;
|
||||||
left: -5.95%;
|
left: -3.13%;
|
||||||
width: 137.79%;
|
width: 130.62%;
|
||||||
height: 411.28%;
|
height: 389.91%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.experience-card__image--three {
|
.experience-card__image--three {
|
||||||
top: -99.23%;
|
top: -115.66%;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 298.5%;
|
height: 298.5%;
|
||||||
@@ -120,7 +130,7 @@
|
|||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
letter-spacing: -0.47px;
|
letter-spacing: var(--ls-24);
|
||||||
color: #0d0d0d;
|
color: #0d0d0d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,16 +140,17 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
letter-spacing: -0.18px;
|
letter-spacing: var(--ls-16);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.experience__caption {
|
.experience__caption {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 18px;
|
font-size: 15px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: var(--ls-15);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
@@ -149,7 +160,7 @@
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 64px 16px;
|
padding: 60px 16px;
|
||||||
background: #fef0eb;
|
background: #fef0eb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,6 +182,25 @@
|
|||||||
overflow: clip;
|
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 {
|
.section-eyebrow {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -186,6 +216,7 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
letter-spacing: var(--ls-14);
|
||||||
color: #f08458;
|
color: #f08458;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -194,26 +225,48 @@
|
|||||||
.use-cases__title {
|
.use-cases__title {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 32px;
|
font-size: 28px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
|
letter-spacing: var(--ls-28);
|
||||||
color: #1a1a1a;
|
color: #1a1a1a;
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.use-cases__description {
|
.use-cases__description {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 18px;
|
font-size: 15px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: var(--ls-15);
|
||||||
color: #7a726d;
|
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 {
|
.use-cases__rows {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 1128px;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
margin: 0 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 30px;
|
border-radius: 30px;
|
||||||
gap: 1px;
|
gap: 1px;
|
||||||
@@ -249,6 +302,7 @@
|
|||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
letter-spacing: var(--ls-18);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,13 +312,82 @@
|
|||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: var(--ls-15);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
@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 {
|
.use-case-row {
|
||||||
grid-template-columns: minmax(220px, 300px) minmax(280px, 1fr);
|
grid-template-columns: minmax(220px, 300px) minmax(280px, 1fr);
|
||||||
min-height: 120px;
|
height: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.use-case-row__title-cell,
|
.use-case-row__title-cell,
|
||||||
@@ -274,46 +397,66 @@
|
|||||||
|
|
||||||
.use-case-row__title {
|
.use-case-row__title {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
|
letter-spacing: var(--ls-20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
|
.experience,
|
||||||
|
.use-cases {
|
||||||
|
padding-left: 36px;
|
||||||
|
padding-right: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
.experience__title,
|
.experience__title,
|
||||||
.use-cases__title {
|
.use-cases__title {
|
||||||
font-size: 40px;
|
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) {
|
@media (min-width: 1024px) {
|
||||||
.experience {
|
.experience {
|
||||||
padding: 120px 16px;
|
padding-top: 60px;
|
||||||
}
|
padding-bottom: 60px;
|
||||||
|
padding-left: 36px;
|
||||||
.experience__grid {
|
padding-right: 36px;
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
||||||
}
|
|
||||||
|
|
||||||
.experience-card {
|
|
||||||
height: 477px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.experience-card__media {
|
|
||||||
height: 232px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.experience-card__title {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.experience__title,
|
|
||||||
.use-cases__title {
|
|
||||||
font-size: 48px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
@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 {
|
.use-cases {
|
||||||
padding: 120px 64px;
|
padding: 60px 64px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.use-cases__inner {
|
.use-cases__inner {
|
||||||
@@ -323,6 +466,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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) {
|
@media (min-width: 1440px) {
|
||||||
.use-cases {
|
.use-cases {
|
||||||
padding-right: 130px;
|
padding-right: 130px;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 64px 16px;
|
padding: 60px 16px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,18 +30,20 @@
|
|||||||
.trust__title {
|
.trust__title {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 32px;
|
font-size: 28px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
|
letter-spacing: var(--ls-28);
|
||||||
color: #1a1a1a;
|
color: #1a1a1a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.trust__description {
|
.trust__description {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 18px;
|
font-size: 15px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: var(--ls-15);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,6 +128,7 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
|
letter-spacing: var(--ls-16);
|
||||||
color: #0d0d0d;
|
color: #0d0d0d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,12 +138,13 @@
|
|||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: var(--ls-15);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.trust__divider {
|
.trust__divider {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: none;
|
display: none; /* shown only in desktop flex row via 1023px breakpoint */
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 118px;
|
height: 118px;
|
||||||
@@ -158,35 +162,167 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@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 {
|
.trust__title {
|
||||||
font-size: 40px;
|
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 {
|
.trust__grid {
|
||||||
|
position: relative;
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
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) {
|
@media (min-width: 1024px) {
|
||||||
.trust {
|
.trust {
|
||||||
padding: 120px;
|
padding-top: 60px;
|
||||||
}
|
padding-bottom: 60px;
|
||||||
|
padding-left: 28px;
|
||||||
.trust__title {
|
padding-right: 28px;
|
||||||
font-size: 48px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.trust__grid {
|
.trust__grid {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 24px;
|
gap: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.trust-card {
|
.trust-card {
|
||||||
flex: 1;
|
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 {
|
.trust__divider {
|
||||||
display: block;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 64px 16px;
|
padding: 60px 16px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
.why__copy {
|
.why__copy {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
order: 2;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
@@ -46,8 +47,9 @@
|
|||||||
|
|
||||||
.why__title {
|
.why__title {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 32px;
|
font-size: 28px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
letter-spacing: var(--ls-28);
|
||||||
color: #1a1a1a;
|
color: #1a1a1a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,23 +80,36 @@
|
|||||||
.why__description {
|
.why__description {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 18px;
|
font-size: 15px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: var(--ls-15);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
.why__description {
|
||||||
|
font-size: 18px;
|
||||||
|
letter-spacing: var(--ls-18);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.why__illustration {
|
.why__illustration {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: none;
|
display: block;
|
||||||
|
order: 1;
|
||||||
|
align-self: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 480px;
|
width: 480px;
|
||||||
|
max-width: calc(100vw - 32px);
|
||||||
height: 480px;
|
height: 480px;
|
||||||
|
max-height: calc(100vw - 32px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.why__illustration-image {
|
.why__illustration-image {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
@@ -111,8 +126,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
gap: 24px;
|
gap: 20px;
|
||||||
padding: 36px;
|
padding: 20px 16px;
|
||||||
overflow: clip;
|
overflow: clip;
|
||||||
background: #fef0eb;
|
background: #fef0eb;
|
||||||
border: 1px solid #e8e4de;
|
border: 1px solid #e8e4de;
|
||||||
@@ -124,8 +139,8 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 80px;
|
width: 60px;
|
||||||
height: 80px;
|
height: 60px;
|
||||||
overflow: clip;
|
overflow: clip;
|
||||||
background: #f08458;
|
background: #f08458;
|
||||||
border-radius: 9999px;
|
border-radius: 9999px;
|
||||||
@@ -135,19 +150,24 @@
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.why-card__icon--square {
|
.why-card__icon--simple {
|
||||||
width: 44px;
|
width: 33.001px;
|
||||||
height: 44px;
|
height: 32.973px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.why-card__icon--familiar {
|
.why-card__icon--familiar {
|
||||||
width: 38px;
|
width: 28.5px;
|
||||||
height: 40px;
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.why-card__icon--connected {
|
||||||
|
width: 33px;
|
||||||
|
height: 32.936px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.why-card__icon--modern {
|
.why-card__icon--modern {
|
||||||
width: 24px;
|
width: 18.125px;
|
||||||
height: 44px;
|
height: 33px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.why-card__copy {
|
.why-card__copy {
|
||||||
@@ -163,9 +183,10 @@
|
|||||||
.why-card__title {
|
.why-card__title {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 24px;
|
font-size: 20px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 20px;
|
line-height: 23px;
|
||||||
|
letter-spacing: var(--ls-20);
|
||||||
color: #0d0d0d;
|
color: #0d0d0d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,37 +196,122 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: var(--ls-16);
|
||||||
color: #7a726d;
|
color: #7a726d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@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 {
|
.why__title {
|
||||||
font-size: 40px;
|
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 {
|
.why__grid {
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
.why-card {
|
|
||||||
min-height: 152px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
|
||||||
.why {
|
|
||||||
padding: 120px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.why__intro {
|
.why__intro {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
|
||||||
.why__title {
|
.why__copy {
|
||||||
font-size: 48px;
|
order: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.why__illustration {
|
.why__illustration {
|
||||||
display: block;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||