Compare commits

..

10 Commits

Author SHA1 Message Date
TerryM
376755889d docs: add README and fix Vite 7 override
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 16:40:16 +08:00
TerryM
a071a85121 feat: add Footer component 2026-05-12 16:34:58 +08:00
TerryM
a573a1e571 feat: add Download CTA section 2026-05-12 16:34:26 +08:00
TerryM
bafa1ba6d4 feat: add Use Cases section 2026-05-12 16:33:59 +08:00
TerryM
1e81796aee feat: add Core System section 2026-05-12 16:32:14 +08:00
TerryM
14b528f02b feat: add Hero section 2026-05-12 16:30:36 +08:00
TerryM
316dbe3c78 feat: add Header component 2026-05-12 16:28:30 +08:00
TerryM
213d6c49bc feat: add Base layout with Inter font 2026-05-12 16:27:03 +08:00
TerryM
c06d6bc3c3 feat: replace Tailwind with UnoCSS
Faster dev HMR, native Astro 6 support, same utility class names.
Tokens migrated to uno.config.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 16:26:01 +08:00
TerryM
264f66bea5 feat: download Figma assets to public/assets
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 16:22:26 +08:00
29 changed files with 1711 additions and 1093 deletions

77
README.md Normal file
View File

@@ -0,0 +1,77 @@
# Talk Pro
Marketing landing page for Talk Pro — a modern messaging app designed for clear, simple, and reliable communication.
## Stack
- [Astro 6](https://astro.build) — static site generator, zero client-side JS
- [UnoCSS](https://unocss.dev) — atomic CSS engine (Tailwind-compatible, faster HMR)
- TypeScript (strict)
- Inter — Google Fonts
## Getting Started
```bash
npm install
npm run dev
```
Open [http://localhost:4321](http://localhost:4321)
## Commands
| Command | Description |
|---------|-------------|
| `npm run dev` | Start dev server at `localhost:4321` |
| `npm run build` | Build for production into `dist/` |
| `npm run preview` | Preview production build locally |
## Project Structure
```
talk-pro/
├── public/
│ └── assets/ # Images downloaded from Figma
├── src/
│ ├── layouts/
│ │ └── Base.astro # HTML shell, Inter font, meta
│ ├── components/
│ │ ├── Header.astro # Sticky frosted-glass nav
│ │ ├── Hero.astro # Hero with phone mockup
│ │ ├── CoreSystem.astro # 6-feature card grid
│ │ ├── UseCases.astro # 3 identity cards
│ │ ├── DownloadCTA.astro # Store badges
│ │ └── Footer.astro # Links + copyright
│ ├── pages/
│ │ └── index.astro # Composes all sections
│ └── styles/
│ └── global.css
├── uno.config.ts # Design tokens + UnoCSS config
└── astro.config.mjs
```
## Design Tokens
Defined in `uno.config.ts`:
| Token | Value |
|-------|-------|
| `brand` | `#f28a4b` |
| `text-primary` | `#2e2a28` |
| `text-secondary` | `#7a726d` |
| `surface` | `#f8f3ee` |
| `surface-alt` | `#f2eae3` |
| `surface-footer` | `#efe6de` |
| `border-light` | `#e3d9d1` |
## Assets
Figma assets are stored in `public/assets/`. To re-download them (valid for 7 days from Figma export):
```bash
bash scripts/download-assets.sh
```
## Design Source
Figma: [Talk Pro — Home Page Desktop](https://www.figma.com/design/Gb8WMJ2RLlcZ0bigoiOQx9/Talk-Pro?node-id=9333-31390)

View File

@@ -1,6 +1,6 @@
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
import UnoCSS from '@unocss/astro';
export default defineConfig({
integrations: [tailwind()],
integrations: [UnoCSS({ injectReset: true })],
});

2304
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,10 @@
"astro": "^6.3.1"
},
"devDependencies": {
"@astrojs/tailwind": "^6.0.2",
"tailwindcss": "^3.4.19"
"@unocss/astro": "^66.6.8",
"unocss": "^66.6.8"
},
"overrides": {
"vite": "^7"
}
}

View File

@@ -0,0 +1,6 @@
<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">
<g id="Icon">
<rect width="44" height="44" rx="12" fill="var(--fill-0, #D55F31)"/>
<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)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 559 B

View File

@@ -0,0 +1,6 @@
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 22.0004 26.9856" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Group">
<path id="Vector" d="M16.1918 0C16.2546 0 16.3174 0 16.3838 0C16.5378 1.90308 15.8115 3.32506 14.9286 4.35481C14.0624 5.37746 12.8762 6.36929 10.9578 6.21879C10.8298 4.34297 11.5574 3.02645 12.439 1.99907C13.2566 1.0416 14.7556 0.189597 16.1918 0Z" fill="var(--fill-0, white)"/>
<path id="Vector_2" d="M22.0004 19.8082C22.0004 19.8271 22.0004 19.8437 22.0004 19.8615C21.4612 21.4944 20.6922 22.8939 19.7537 24.1926C18.8969 25.3717 17.847 26.9584 15.9724 26.9584C14.3525 26.9584 13.2766 25.9168 11.6164 25.8883C9.86025 25.8599 8.89449 26.7593 7.28883 26.9856C7.10516 26.9856 6.92149 26.9856 6.74137 26.9856C5.56231 26.815 4.61077 25.8812 3.91756 25.0399C1.87346 22.5538 0.293876 19.3425 0 15.233C0 14.8301 0 14.4284 0 14.0255C0.124423 11.0843 1.55351 8.69304 3.45304 7.53413C4.45554 6.91794 5.83367 6.39299 7.36823 6.62762C8.02589 6.72953 8.69778 6.95467 9.28672 7.17745C9.84484 7.39193 10.5428 7.77231 11.204 7.75217C11.6519 7.73913 12.0975 7.50569 12.549 7.34098C13.8714 6.86343 15.1678 6.31597 16.8765 6.57311C18.9301 6.88357 20.3876 7.79601 21.2882 9.20377C19.551 10.3094 18.1776 11.9754 18.4123 14.8206C18.6208 17.405 20.1234 18.9171 22.0004 19.8082Z" fill="var(--fill-0, white)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,3 @@
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 1180 1" fill="none" xmlns="http://www.w3.org/2000/svg">
<line id="Line" y1="0.5" x2="1180" y2="0.5" stroke="var(--stroke-0, #E3D9D1)"/>
</svg>

After

Width:  |  Height:  |  Size: 258 B

BIN
public/assets/hero-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

BIN
public/assets/logo-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

View File

@@ -0,0 +1,14 @@
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 77.9999 27.3466" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Group 8">
<path id="Vector" d="M40.9405 20.8327C43.8201 20.792 46.7009 20.8546 49.5757 21.02C58.0611 21.5051 67.1544 23.0697 75.207 25.9203C75.7287 26.1051 76.704 26.4048 77.0609 26.8008C77.2687 28.0927 72.5969 26.7 72.1119 26.5908C63.0951 24.587 53.8933 23.5076 44.6529 23.3707C33.1497 23.0089 20.9234 24.7233 9.72826 27.2833C9.29807 27.3815 8.61557 27.3918 8.39051 26.9468C8.49032 26.3331 10.397 25.7556 10.9663 25.5599C20.5216 22.2771 30.8642 21.0698 40.9405 20.8327Z" fill="var(--fill-0, #F28A4B)"/>
<path id="Vector_2" d="M31.318 0.0224661C31.8649 0.0139438 32.8866 -0.104058 33.2606 0.300423C33.3065 0.889771 32.4703 4.77527 32.3052 5.60259C32.0856 6.70196 31.7116 9.06001 31.422 10.1043C32.5555 9.18653 33.6855 8.09699 34.7424 7.13332C36.0662 5.92709 36.4364 5.25449 38.3791 5.48983C38.8939 5.55211 39.7945 5.27874 40.0876 5.81696C40.07 5.99789 40.0826 6.0228 39.9339 6.16768C38.2986 7.76135 36.4564 9.19244 34.775 10.7363C35.619 12.4178 36.9093 14.4474 37.8796 16.1165C38.0982 16.4652 38.3254 16.7563 38.3624 17.1608C38.3115 17.324 38.2538 17.3896 38.1055 17.4787C37.5409 17.8183 35.5396 17.7435 34.913 17.5403C34.2374 17.322 32.3776 13.308 31.9903 12.5528C31.5792 12.9003 31.1699 13.2497 30.7626 13.6017C30.5008 14.6369 30.4536 15.7264 30.2 16.7504C29.9334 17.7652 29.0813 17.7055 28.3005 17.6603C27.1169 17.5915 26.5033 17.9455 26.7986 16.441C27.0193 15.3173 27.29 14.1039 27.5094 12.994L28.896 5.9284C29.2375 4.25738 29.5313 2.57456 29.8657 0.90223C30.0467 -0.00309788 30.5349 0.0375439 31.318 0.0224661Z" fill="var(--fill-0, #2E2A28)"/>
<path id="Vector_3" d="M0.941515 0.37534C3.25959 0.264915 5.62425 0.356276 7.94687 0.356276C9.60223 0.356276 11.5002 0.247168 13.1259 0.366795C13.2646 0.377311 13.366 0.393748 13.4863 0.469994C13.6176 0.552812 13.6619 0.717133 13.6716 0.862394C13.704 1.34682 13.2587 2.8691 12.9071 3.19709C12.4474 3.62564 9.05615 3.40611 8.28287 3.39953C7.47585 6.82599 6.89241 10.4187 6.11747 13.8899C5.92381 14.8114 5.75465 16.7208 5.20897 17.4136C4.89788 17.808 2.41612 17.8363 1.98082 17.3577C1.89186 16.7839 4.39226 4.90867 4.68484 3.41333C3.72145 3.39296 0.616716 3.61249 0.0536389 3.1353C-0.061151 2.88487 0.0320916 2.45895 0.11222 2.19932C0.347797 1.43621 0.126322 0.759855 0.941515 0.37534Z" fill="var(--fill-0, #2E2A28)"/>
<path id="Vector_4" d="M25.4674 0.0148448C25.9427 0.00694851 27.0579 -0.0542471 27.4724 0.147108C27.895 0.35307 27.4717 1.69149 27.391 2.14421C27.2885 2.71866 27.1388 3.37932 27.0188 3.98339L25.756 10.4031C25.3468 12.5107 25.0186 14.6447 24.5911 16.7504C24.4225 17.5808 24.2599 17.6907 23.4616 17.692C22.8596 17.6828 21.6356 17.8295 21.2147 17.4591C21.1268 17.3821 21.125 17.3492 21.136 17.209C21.2783 15.3817 21.8208 13.3984 22.1653 11.6119L23.56 4.36044C23.797 3.14967 24.0258 1.93562 24.2946 0.731434C24.459 -0.00489494 24.8585 0.0306374 25.4674 0.0148448Z" fill="var(--fill-0, #2E2A28)"/>
<g id="Vector_5">
<path fill-rule="evenodd" clip-rule="evenodd" d="M71.6495 5.11303C74.6824 4.86166 77.5554 6.28123 77.9503 9.53783C78.1755 11.4579 77.6281 13.3892 76.4288 14.906C75.0142 16.6748 73.1939 17.5443 70.9747 17.7839C67.818 18.0877 64.8171 16.6472 64.4884 13.2195C64.3149 11.2569 64.9282 9.30557 66.1935 7.79467C67.6121 6.10827 69.4964 5.30877 71.6495 5.11303ZM71.3595 7.84935C69.1568 8.28547 67.9375 10.1587 67.9572 12.3425C67.975 14.3657 69.1902 15.2459 71.1368 15.0896C72.2798 14.8336 73.2163 14.2735 73.795 13.2497C75.1541 10.8445 74.911 7.55083 71.3595 7.84935Z" fill="var(--fill-0, #F28A4B)"/>
<path d="M64.0954 4.9784C64.4103 4.94111 65.2562 5.06895 65.2588 5.37122C65.2661 6.07163 64.7563 7.87458 64.4288 8.43917C63.9897 8.46314 63.4642 8.42253 63.0303 8.47379C60.3232 8.79071 59.8827 10.8613 59.4615 13.0438C59.2766 14.0012 59.1082 14.9626 58.957 15.9266C58.7602 17.1524 58.8349 17.8707 57.3221 17.6837C56.7807 17.6164 55.7896 17.8554 55.3974 17.4839C55.2865 17.2476 55.3069 17.2409 55.3452 16.9886C55.7044 15.5025 57.3981 5.79532 57.7177 5.49439C57.8893 5.3326 58.2492 5.282 58.471 5.27135C58.9484 5.24871 60.3179 5.1788 60.6474 5.47707C60.8355 5.84792 60.5846 6.93582 60.5212 7.42784C61.4258 6.0683 62.4315 5.14485 64.0954 4.9784Z" fill="var(--fill-0, #F28A4B)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M48.9446 0.1562C50.955 0.158164 53.5275 0.122138 55.0666 1.63374C57.201 3.7307 56.339 7.94429 54.3235 9.84468C52.1625 11.8833 49.6855 11.9808 46.8987 11.9619L46.1184 11.957C45.9559 12.7548 45.3084 17.0471 44.9719 17.3691C44.6001 17.7241 43.1814 17.6145 42.6409 17.6191C42.2972 17.6217 41.9482 17.6038 41.6916 17.3525C41.5596 16.8275 43.0455 9.96145 43.2288 8.98823L44.2737 3.62983C44.4556 2.70432 44.6085 1.7591 44.8166 0.838817C44.905 0.448118 45.0992 0.373253 45.4329 0.183544C45.7078 0.175033 45.9841 0.168595 46.259 0.164012C47.1544 0.15616 48.0492 0.153582 48.9446 0.1562ZM47.8303 3.18061C47.6215 4.33916 47.4035 5.49572 47.175 6.65034C47.0402 7.34484 46.8186 8.33409 46.7727 9.01557C48.4072 9.0241 49.6081 9.14689 51.0706 8.34956C53.0184 7.11729 53.6271 3.65427 50.7307 3.25483C49.8037 3.12652 48.7737 3.17538 47.8303 3.18061Z" fill="var(--fill-0, #F28A4B)"/>
</g>
<path id="Subtract" fill-rule="evenodd" clip-rule="evenodd" d="M14.8502 5.24274C19.7083 4.68825 21.102 7.28866 19.9723 11.6041C19.8429 12.0983 19.3743 14.3233 19.3122 14.7652C18.9984 16.9987 20.4166 17.7218 17.1188 17.6675C16.048 17.64 15.8944 17.0865 15.943 16.1431C14.502 17.603 12.8943 18.2777 10.8043 17.7808C10.0268 17.5955 9.52384 17.1424 9.01625 16.5611C7.80468 14.6731 8.71157 12.0689 10.6413 11.064C12.5185 10.0867 14.8779 10.1417 16.9508 10.0972C17.405 7.84867 16.1659 7.37086 14.1364 7.89899C13.2123 8.13925 12.8419 8.64924 12.0778 9.13434L12.0084 9.17829C11.9265 9.13578 11.8462 9.09028 11.7672 9.04255C9.15458 7.48582 11.4606 6.12449 13.2497 5.55622C13.7891 5.38473 14.2902 5.31212 14.8502 5.24274ZM16.4821 12.2779C15.8553 12.2759 15.1975 12.2591 14.5758 12.314C14.1695 12.354 13.8972 12.3897 13.4528 12.4781C12.2772 12.7118 11.0575 14.261 12.2916 15.1998C12.6616 15.4819 13.2647 15.5124 13.7487 15.483C15.5022 15.0856 16.2509 13.9879 16.4821 12.2779Z" fill="var(--fill-0, #2E2A28)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

19
scripts/download-assets.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
set -e
mkdir -p public/assets
curl -sL "https://www.figma.com/api/mcp/asset/81b107f5-6e2b-4877-9cd6-d2af7b9fc4e4" -o public/assets/logo-icon.png
curl -sL "https://www.figma.com/api/mcp/asset/642480ed-2bdc-40f0-8b34-4d868443be3a" -o public/assets/logo-wordmark.png
curl -sL "https://www.figma.com/api/mcp/asset/92f03ea0-0710-41ca-a84c-eff4af034455" -o public/assets/hero-bg.png
curl -sL "https://www.figma.com/api/mcp/asset/9e59170a-ac6c-48fd-a869-34bcd7beec0c" -o public/assets/hero-phone.png
curl -sL "https://www.figma.com/api/mcp/asset/86a3a493-f756-4e82-a055-2857ad1bb127" -o public/assets/icon-messaging.png
curl -sL "https://www.figma.com/api/mcp/asset/d8131626-0de4-4be3-98a0-d01c310c7e2d" -o public/assets/icon-groups.png
curl -sL "https://www.figma.com/api/mcp/asset/e9d23aa1-7e10-4382-b1bd-b9ac755e2a5f" -o public/assets/icon-channels.png
curl -sL "https://www.figma.com/api/mcp/asset/ac45f93c-45ed-464a-8a9c-c389ba20555f" -o public/assets/icon-voice.png
curl -sL "https://www.figma.com/api/mcp/asset/67edb5de-858a-4a14-86bf-ac815f6681d1" -o public/assets/icon-video.png
curl -sL "https://www.figma.com/api/mcp/asset/c54dcf64-c5ff-4e2e-9573-c80e3946d1fc" -o public/assets/icon-media.png
curl -sL "https://www.figma.com/api/mcp/asset/295181b7-7046-42dc-a5f2-234957c85c27" -o public/assets/badge-android-icon.png
curl -sL "https://www.figma.com/api/mcp/asset/c1b2603d-7e44-4235-ba42-5ca5983bd926" -o public/assets/badge-ios-icon.png
curl -sL "https://www.figma.com/api/mcp/asset/62960bde-f21e-494f-8e9d-f2f0b7a55547" -o public/assets/footer-divider.png
echo "Done. $(ls public/assets | wc -l) assets downloaded."

View File

@@ -0,0 +1,44 @@
---
const cards = [
{ img: '/assets/icon-messaging.png', title: 'Private Messaging', desc: 'Stay connected through fast and familiar one-on-one conversations.' },
{ img: '/assets/icon-groups.png', title: 'Group Chats', desc: 'Create spaces for friends, teams, communities, and shared discussions.' },
{ img: '/assets/icon-channels.png', title: 'Channels', desc: 'Follow updates, announcements, and content from the people or communities you care about.' },
{ img: '/assets/icon-voice.png', title: 'Voice Calls', desc: 'Talk in real time whenever messages are not enough.' },
{ img: '/assets/icon-video.png', title: 'Video Calls', desc: 'Connect face-to-face with a simple and reliable video call experience.' },
{ img: '/assets/icon-media.png', title: 'Media Sharing', desc: 'Share photos, videos, files, and updates in your conversations.' },
]
const rows = [cards.slice(0, 3), cards.slice(3)]
---
<section class="flex flex-col items-center px-[130px] py-[110px] max-w-[1440px] mx-auto">
<div class="flex flex-col items-center pb-[60px] w-full">
<p class="font-bold text-brand text-[13px] tracking-[-0.04px]">CORE SYSTEM</p>
<div class="h-[15px]"></div>
<div class="font-bold text-text-primary text-[52px] text-center tracking-[-1.16px] leading-[0.96]">
<p>Built for how modern</p>
<p>communication actually works.</p>
</div>
<div class="h-5"></div>
<p class="text-text-secondary text-[18px] font-normal leading-[1.5] text-center tracking-[-0.26px] max-w-[900px]">
Different identities, different conversations, and different privacy levels should not be forced into one flat interface. Talk Pro lets them exist in order inside one platform.
</p>
</div>
<div class="flex flex-col gap-[22px] w-[1280px]">
{rows.map((row) => (
<div class="flex gap-[22px]">
{row.map((card) => (
<div class="flex-1 flex flex-col items-center bg-[rgba(255,255,255,0.78)] border border-white rounded-[30px] p-8">
<div class="size-[240px] shrink-0 overflow-hidden rounded-2xl">
<img src={card.img} alt={card.title} class="w-full h-full object-cover" />
</div>
<div class="h-[22px]"></div>
<p class="font-bold text-text-primary text-[25px] tracking-[-0.5px] w-full">{card.title}</p>
<div class="h-[14px]"></div>
<p class="text-text-secondary text-[15px] font-normal leading-[1.5] tracking-[-0.13px] w-full">{card.desc}</p>
</div>
))}
</div>
))}
</div>
</section>

View File

@@ -0,0 +1,40 @@
---
---
<section class="flex flex-col items-center bg-surface-alt px-[130px] py-[110px] w-full">
<div class="bg-[rgba(255,255,255,0.78)] rounded-[34px] p-[52px] flex flex-col items-center max-w-[1180px] w-full">
<p class="font-bold text-brand text-[13px] tracking-[2.86px]">DOWNLOAD</p>
<div class="h-[15px]"></div>
<div class="font-bold text-text-primary text-[44px] text-center tracking-[-2.2px] leading-[1.04] max-w-[1076px]">
<p>Start with one conversation.</p>
<p>Build your own communication space.</p>
</div>
<div class="h-5"></div>
<p class="text-text-secondary text-[18px] font-normal leading-[1.75] text-center max-w-[800px]">
Talk Pro supports iOS and Android. Official store links, QR codes, version information, and compatibility notes are reserved on the download page.
</p>
<div class="h-8"></div>
<div class="flex gap-2 items-center">
<!-- Android badge -->
<div class="bg-brand border border-border-light rounded-[20px] flex items-center gap-2 h-[70px] px-4 py-3">
<img src="/assets/badge-android-icon.png" alt="Android" class="size-[44px]" />
<div class="flex flex-col gap-[3px]">
<p class="font-bold text-[#ffd6bc] text-[11px] tracking-[0.66px]">ANDROID</p>
<p class="font-bold text-white text-[15px]">Download APK</p>
</div>
</div>
<!-- iOS badge -->
<div class="bg-[rgba(18,18,18,0.94)] border border-border-light rounded-[20px] flex items-center gap-2 h-[70px] px-4 py-3">
<div class="bg-[#323232] rounded-[12px] size-[44px] flex items-center justify-center">
<img src="/assets/badge-ios-icon.png" alt="Apple" class="w-[22px] h-[27px]" />
</div>
<div class="flex flex-col gap-[3px]">
<p class="font-bold text-[#ccc] text-[11px] tracking-[0.66px]">IOS</p>
<p class="font-bold text-white text-[15px]">Coming on App Store</p>
</div>
</div>
</div>
</div>
</section>

View File

@@ -0,0 +1,42 @@
---
const columns: Record<string, string[]> = {
Product: ['Features', 'Product', 'Download'],
Privacy: ['Privacy Policy', 'Protected Space', 'Security'],
Company: ['About', 'Support', 'Contact'],
}
---
<footer class="bg-surface-footer px-[130px] pt-[58px] pb-[30px] w-full">
<div class="flex gap-[42px] items-start max-w-[1180px]">
<!-- Brand -->
<div class="flex flex-col gap-[14px] w-[280px]">
<div class="bg-brand rounded-[12px] size-9"></div>
<p class="font-bold text-text-primary text-[18px] tracking-[-0.54px]">Talk Pro</p>
<div class="text-text-secondary text-[14px] font-normal leading-[1.7]">
<p>Designed for modern communication,</p>
<p>privacy, and intelligent connection.</p>
</div>
</div>
<div class="flex-1"></div>
{Object.entries(columns).map(([heading, items]) => (
<div class="flex flex-col gap-3">
<p class="font-bold text-text-primary text-[15px]">{heading}</p>
{items.map((item) => (
<a href="#" class="text-text-secondary text-[14px] font-normal hover:text-text-primary transition-colors whitespace-nowrap">{item}</a>
))}
</div>
))}
</div>
<div class="h-11"></div>
<div class="max-w-[1180px] border-t border-border-light"></div>
<div class="h-6"></div>
<div class="flex items-center gap-5 max-w-[1180px]">
<p class="text-text-secondary text-[14px] font-normal">© 2026 Talk Pro. All rights reserved.</p>
<div class="flex-1"></div>
<p class="text-text-secondary text-[14px] font-normal">Terms of Use · Privacy Policy · Support</p>
</div>
</footer>

View File

@@ -0,0 +1,28 @@
---
---
<header class="fixed top-0 left-0 w-full h-[78px] bg-[rgba(248,243,238,0.84)] border-b border-border-light backdrop-blur-sm z-50 flex items-center justify-center">
<div class="w-[1280px] flex items-center">
<div class="flex-1">
<a href="/" class="flex items-center gap-2 w-fit">
<img src="/assets/logo-icon.png" alt="Talk Pro icon" class="h-[42px] w-[53px] object-cover" />
<img src="/assets/logo-wordmark.png" alt="Talk Pro" class="h-6" />
</a>
</div>
<nav class="flex items-center gap-7 font-bold text-[14px] text-text-secondary tracking-[-0.09px]">
<a href="#" class="hover:text-text-primary transition-colors">Home</a>
<a href="#" class="hover:text-text-primary transition-colors">Features</a>
<a href="#" class="hover:text-text-primary transition-colors">Product</a>
<a href="#" class="hover:text-text-primary transition-colors">Privacy</a>
<a href="#" class="hover:text-text-primary transition-colors">About</a>
</nav>
<div class="flex-1 flex justify-end">
<button class="bg-brand text-white font-bold text-[14px] px-[22px] py-[13px] rounded-[17px] hover:opacity-90 transition-opacity">
Download
</button>
</div>
</div>
</header>
<div class="h-[78px]"></div>

82
src/components/Hero.astro Normal file
View File

@@ -0,0 +1,82 @@
---
const floatCards = [
{
icon: '☷',
title: 'Work / Private / Protected',
desc: 'One account, multiple communication worlds.',
pos: 'left-[-40px] top-[75.5px]',
},
{
icon: '✦',
title: 'AI Summary Ready',
desc: 'Long conversations and group highlights organized automatically.',
pos: 'left-[180px] top-[270px]',
},
{
icon: '◌',
title: 'Protected Hidden Space',
desc: 'When privacy needs more, enter a protected space.',
pos: 'left-[20px] top-[540px]',
},
]
---
<section class="relative w-full overflow-hidden">
<img src="/assets/hero-bg.png" alt="" class="absolute inset-0 w-full h-full object-cover pointer-events-none" aria-hidden="true" />
<div class="relative flex items-center gap-[70px] h-[683px] px-[130px] py-[80px] max-w-[1440px] mx-auto">
<!-- Left column -->
<div class="flex flex-col gap-[30px] items-start w-[600px] shrink-0">
<div class="flex flex-col gap-6">
<div class="bg-[rgba(255,255,255,0.62)] border border-white px-[14px] py-[9px] rounded-full w-fit">
<p class="font-bold text-text-secondary text-[14px] tracking-[-0.09px] whitespace-pre">✦ Available on iOS and Android</p>
</div>
<div class="font-bold text-text-primary text-[72px] tracking-[-1.61px] leading-[0.96] w-[560px]">
<p>One User.</p>
<p>Multiple Worlds.</p>
</div>
<p class="text-text-secondary text-[20px] font-normal leading-[1.5] tracking-[-0.33px]">
Talk Pro is a modern messaging app designed for clear, simple, and reliable communication. From private chats to group conversations, channels, voice calls, and video calls, Talk Pro helps people stay connected in one familiar experience.
</p>
</div>
<div class="flex items-center gap-[14px]">
<button class="bg-brand text-white font-bold text-[15px] px-6 py-[14px] rounded-[17px] tracking-[-0.13px] hover:opacity-90 transition-opacity whitespace-pre">
Download Talk Pro ↓
</button>
<button class="bg-[rgba(255,255,255,0.55)] border border-border-light text-text-primary font-bold text-[15px] px-6 py-[14px] rounded-[17px] tracking-[-0.13px] hover:bg-white transition-colors whitespace-pre">
Explore Features →
</button>
</div>
<div class="flex items-center gap-[10px]">
{['Identity Layer', 'AI Native Messaging', 'Adaptive Privacy'].map((tag) => (
<div class="bg-[rgba(255,255,255,0.68)] border border-white px-[14px] py-[9px] rounded-full">
<p class="font-bold text-text-secondary text-[14px] tracking-[-0.09px] whitespace-nowrap">{tag}</p>
</div>
))}
</div>
</div>
<!-- Phone mockup -->
<div class="relative h-[690px] w-[430px] shrink-0">
<div class="absolute bg-text-primary h-[620px] left-[63px] rounded-[44px] top-[35px] w-[304px] overflow-hidden">
<img src="/assets/hero-phone.png" alt="Talk Pro app" class="absolute left-3 top-3 w-[280px] h-[596px] rounded-[34px] object-cover" />
</div>
{floatCards.map((card) => (
<div class={`absolute ${card.pos} flex items-start gap-3 bg-[rgba(255,255,255,0.86)] border border-white backdrop-blur-[3.7px] rounded-[24px] pl-4 pr-[18px] py-4`}>
<div class="bg-[#fff0e5] rounded-[14px] size-[38px] flex items-center justify-center shrink-0">
<span class="text-brand font-bold text-[18px]">{card.icon}</span>
</div>
<div class="flex flex-col gap-1">
<p class="font-bold text-text-primary text-[14px] tracking-[-0.09px] whitespace-nowrap">{card.title}</p>
<p class="text-text-secondary text-[12px] font-normal leading-[1.45] tracking-[0.01px] w-[185px]">{card.desc}</p>
</div>
</div>
))}
</div>
</div>
</section>

View File

@@ -0,0 +1,31 @@
---
const cases = [
{ title: 'Work Identity', desc: 'Keep work communication clear, organized, and easier to review.' },
{ title: 'Private Identity', desc: 'Keep personal conversations natural, focused, and separate from work noise.' },
{ title: 'Protected Space', desc: 'Some conversations are not only private. They require stronger boundaries and another layer of protection.' },
]
---
<section class="flex flex-col items-center bg-surface px-[130px] py-[110px] w-full">
<div class="flex flex-col items-center pb-[60px] max-w-[1180px] w-full">
<p class="font-bold text-brand text-[13px] tracking-[2.86px]">USE CASES</p>
<div class="h-[15px]"></div>
<p class="font-bold text-text-primary text-[52px] text-center tracking-[-2.6px] leading-[1.04]">
Designed for the worlds you already live in.
</p>
<div class="h-5"></div>
<p class="text-text-secondary text-[18px] font-normal leading-[1.75] text-center max-w-[900px]">
Work, private life, and protected conversations should not interfere with each other inside one identity.
</p>
</div>
<div class="flex gap-[22px]">
{cases.map((c) => (
<div class="bg-[rgba(255,255,255,0.78)] border border-white rounded-[30px] p-8 h-[245px] w-[378px] flex flex-col">
<p class="font-bold text-text-primary text-[25px] tracking-[-0.75px]">{c.title}</p>
<div class="h-4"></div>
<p class="text-text-secondary text-[15px] font-normal leading-[1.72]">{c.desc}</p>
</div>
))}
</div>
</section>

24
src/layouts/Base.astro Normal file
View File

@@ -0,0 +1,24 @@
---
import '../styles/global.css'
export interface Props {
title?: string
}
const { title = 'Talk Pro — One User. Multiple Worlds.' } = Astro.props
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Talk Pro is a modern messaging app for private chats, group conversations, channels, voice and video calls." />
<title>{title}</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet" />
</head>
<body class="bg-surface font-sans overflow-x-hidden">
<slot />
</body>
</html>

View File

@@ -1,17 +1,18 @@
---
import '../styles/global.css';
import Base from '../layouts/Base.astro'
import Header from '../components/Header.astro'
import Hero from '../components/Hero.astro'
import CoreSystem from '../components/CoreSystem.astro'
import UseCases from '../components/UseCases.astro'
import DownloadCTA from '../components/DownloadCTA.astro'
import Footer from '../components/Footer.astro'
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>Talk Pro</title>
</head>
<body class="bg-white text-gray-900">
<h1 class="text-4xl font-bold p-8">Talk Pro</h1>
</body>
</html>
<Base>
<Header />
<Hero />
<CoreSystem />
<UseCases />
<DownloadCTA />
<Footer />
</Base>

View File

@@ -1,3 +1 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
/* UnoCSS handles reset and utilities via astro.config.mjs injectReset */

View File

@@ -1,21 +0,0 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,ts,tsx}'],
theme: {
extend: {
colors: {
brand: '#f28a4b',
'text-primary': '#2e2a28',
'text-secondary': '#7a726d',
surface: '#f8f3ee',
'surface-alt': '#f2eae3',
'surface-footer': '#efe6de',
'border-light': '#e3d9d1',
},
fontFamily: {
sans: ['Inter', 'sans-serif'],
},
},
},
plugins: [],
}

19
uno.config.ts Normal file
View File

@@ -0,0 +1,19 @@
import { defineConfig, presetWind } from 'unocss'
export default defineConfig({
presets: [presetWind()],
theme: {
colors: {
brand: '#f28a4b',
'text-primary': '#2e2a28',
'text-secondary': '#7a726d',
surface: '#f8f3ee',
'surface-alt': '#f2eae3',
'surface-footer': '#efe6de',
'border-light': '#e3d9d1',
},
fontFamily: {
sans: ['Inter', 'sans-serif'],
},
},
})