diff --git a/website/assets/app-icon.png b/website/assets/app-icon.png new file mode 100644 index 0000000..94d30c7 Binary files /dev/null and b/website/assets/app-icon.png differ diff --git a/website/assets/badges/badge_github.png b/website/assets/badges/badge_github.png new file mode 100644 index 0000000..326d254 Binary files /dev/null and b/website/assets/badges/badge_github.png differ diff --git a/website/assets/badges/download_on_apple.svg b/website/assets/badges/download_on_apple.svg new file mode 100755 index 0000000..072b425 --- /dev/null +++ b/website/assets/badges/download_on_apple.svg @@ -0,0 +1,46 @@ + + Download_on_the_App_Store_Badge_US-UK_RGB_blk_4SVG_092917 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/assets/badges/download_on_obtainium.png b/website/assets/badges/download_on_obtainium.png new file mode 100644 index 0000000..4f36053 Binary files /dev/null and b/website/assets/badges/download_on_obtainium.png differ diff --git a/website/assets/badges/get-it-on-zapstore.svg b/website/assets/badges/get-it-on-zapstore.svg new file mode 100644 index 0000000..4a18a96 --- /dev/null +++ b/website/assets/badges/get-it-on-zapstore.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/website/assets/logo.png b/website/assets/logo.png new file mode 100644 index 0000000..91829db Binary files /dev/null and b/website/assets/logo.png differ diff --git a/website/assets/screenshots/android/android-1.png b/website/assets/screenshots/android/android-1.png new file mode 100644 index 0000000..f0734d7 Binary files /dev/null and b/website/assets/screenshots/android/android-1.png differ diff --git a/website/assets/screenshots/android/android-2.png b/website/assets/screenshots/android/android-2.png new file mode 100644 index 0000000..fe9941e Binary files /dev/null and b/website/assets/screenshots/android/android-2.png differ diff --git a/website/assets/screenshots/android/android-3.png b/website/assets/screenshots/android/android-3.png new file mode 100644 index 0000000..02a53d5 Binary files /dev/null and b/website/assets/screenshots/android/android-3.png differ diff --git a/website/assets/screenshots/android/android-4.png b/website/assets/screenshots/android/android-4.png new file mode 100644 index 0000000..e6faddb Binary files /dev/null and b/website/assets/screenshots/android/android-4.png differ diff --git a/website/assets/screenshots/android/android-5.png b/website/assets/screenshots/android/android-5.png new file mode 100644 index 0000000..7d02a2b Binary files /dev/null and b/website/assets/screenshots/android/android-5.png differ diff --git a/website/assets/screenshots/android/android-6.png b/website/assets/screenshots/android/android-6.png new file mode 100644 index 0000000..5f5b2f2 Binary files /dev/null and b/website/assets/screenshots/android/android-6.png differ diff --git a/website/assets/screenshots/android/android-7.png b/website/assets/screenshots/android/android-7.png new file mode 100644 index 0000000..0cfe674 Binary files /dev/null and b/website/assets/screenshots/android/android-7.png differ diff --git a/website/assets/screenshots/android/android-8.png b/website/assets/screenshots/android/android-8.png new file mode 100644 index 0000000..f987aef Binary files /dev/null and b/website/assets/screenshots/android/android-8.png differ diff --git a/website/assets/screenshots/ipad/ipad-1.png b/website/assets/screenshots/ipad/ipad-1.png new file mode 100644 index 0000000..afee9cc Binary files /dev/null and b/website/assets/screenshots/ipad/ipad-1.png differ diff --git a/website/assets/screenshots/ipad/ipad-2.png b/website/assets/screenshots/ipad/ipad-2.png new file mode 100644 index 0000000..f5a123a Binary files /dev/null and b/website/assets/screenshots/ipad/ipad-2.png differ diff --git a/website/assets/screenshots/ipad/ipad-3.png b/website/assets/screenshots/ipad/ipad-3.png new file mode 100644 index 0000000..96094c9 Binary files /dev/null and b/website/assets/screenshots/ipad/ipad-3.png differ diff --git a/website/assets/screenshots/ipad/ipad-4.png b/website/assets/screenshots/ipad/ipad-4.png new file mode 100644 index 0000000..a8e6197 Binary files /dev/null and b/website/assets/screenshots/ipad/ipad-4.png differ diff --git a/website/assets/screenshots/ipad/ipad-5.png b/website/assets/screenshots/ipad/ipad-5.png new file mode 100644 index 0000000..4e61329 Binary files /dev/null and b/website/assets/screenshots/ipad/ipad-5.png differ diff --git a/website/assets/screenshots/ipad/ipad-6.png b/website/assets/screenshots/ipad/ipad-6.png new file mode 100644 index 0000000..094d6d6 Binary files /dev/null and b/website/assets/screenshots/ipad/ipad-6.png differ diff --git a/website/assets/screenshots/ipad/ipad-7.png b/website/assets/screenshots/ipad/ipad-7.png new file mode 100644 index 0000000..ebda343 Binary files /dev/null and b/website/assets/screenshots/ipad/ipad-7.png differ diff --git a/website/assets/screenshots/ipad/ipad-8.png b/website/assets/screenshots/ipad/ipad-8.png new file mode 100644 index 0000000..c8bf030 Binary files /dev/null and b/website/assets/screenshots/ipad/ipad-8.png differ diff --git a/website/assets/screenshots/iphone/iphone-1.png b/website/assets/screenshots/iphone/iphone-1.png new file mode 100644 index 0000000..19ab01d Binary files /dev/null and b/website/assets/screenshots/iphone/iphone-1.png differ diff --git a/website/assets/screenshots/iphone/iphone-2.png b/website/assets/screenshots/iphone/iphone-2.png new file mode 100644 index 0000000..2e0754a Binary files /dev/null and b/website/assets/screenshots/iphone/iphone-2.png differ diff --git a/website/assets/screenshots/iphone/iphone-3.png b/website/assets/screenshots/iphone/iphone-3.png new file mode 100644 index 0000000..dbe3642 Binary files /dev/null and b/website/assets/screenshots/iphone/iphone-3.png differ diff --git a/website/assets/screenshots/iphone/iphone-4.png b/website/assets/screenshots/iphone/iphone-4.png new file mode 100644 index 0000000..159bbe2 Binary files /dev/null and b/website/assets/screenshots/iphone/iphone-4.png differ diff --git a/website/assets/screenshots/iphone/iphone-5.png b/website/assets/screenshots/iphone/iphone-5.png new file mode 100644 index 0000000..1dbc281 Binary files /dev/null and b/website/assets/screenshots/iphone/iphone-5.png differ diff --git a/website/assets/screenshots/iphone/iphone-6.png b/website/assets/screenshots/iphone/iphone-6.png new file mode 100644 index 0000000..eb602fd Binary files /dev/null and b/website/assets/screenshots/iphone/iphone-6.png differ diff --git a/website/assets/screenshots/iphone/iphone-7.png b/website/assets/screenshots/iphone/iphone-7.png new file mode 100644 index 0000000..627ec25 Binary files /dev/null and b/website/assets/screenshots/iphone/iphone-7.png differ diff --git a/website/assets/screenshots/iphone/iphone-8.png b/website/assets/screenshots/iphone/iphone-8.png new file mode 100644 index 0000000..a403d4b Binary files /dev/null and b/website/assets/screenshots/iphone/iphone-8.png differ diff --git a/website/assets/screenshots/macos/macos-1.png b/website/assets/screenshots/macos/macos-1.png new file mode 100644 index 0000000..57c15ba Binary files /dev/null and b/website/assets/screenshots/macos/macos-1.png differ diff --git a/website/assets/screenshots/macos/macos-2.png b/website/assets/screenshots/macos/macos-2.png new file mode 100644 index 0000000..b623eb7 Binary files /dev/null and b/website/assets/screenshots/macos/macos-2.png differ diff --git a/website/assets/screenshots/macos/macos-3.png b/website/assets/screenshots/macos/macos-3.png new file mode 100644 index 0000000..a852e14 Binary files /dev/null and b/website/assets/screenshots/macos/macos-3.png differ diff --git a/website/assets/screenshots/macos/macos-4.png b/website/assets/screenshots/macos/macos-4.png new file mode 100644 index 0000000..6d7f5d6 Binary files /dev/null and b/website/assets/screenshots/macos/macos-4.png differ diff --git a/website/assets/screenshots/macos/macos-5.png b/website/assets/screenshots/macos/macos-5.png new file mode 100644 index 0000000..1a6fbc9 Binary files /dev/null and b/website/assets/screenshots/macos/macos-5.png differ diff --git a/website/assets/screenshots/macos/macos-6.png b/website/assets/screenshots/macos/macos-6.png new file mode 100644 index 0000000..3f1f3fe Binary files /dev/null and b/website/assets/screenshots/macos/macos-6.png differ diff --git a/website/index.html b/website/index.html new file mode 100644 index 0000000..196c22d --- /dev/null +++ b/website/index.html @@ -0,0 +1,323 @@ + + + + + +SatsPrice — Bitcoin Price & Sats Converter + + + + + +
+ + + +
+ + +
+
+
+

Bitcoin price calculator

+

Know your sats,
wherever you carry Bitcoin.

+

+ SatsPrice converts Bitcoin, satoshis, and fiat currency in real time — sourced live + from Coinbase and CoinGecko, or set your own exchange rate. No account, no ads, + no tracking. +

+ + + +
+ + + iOS + + + + macOS + + + + Android + +
+ +
+ Free forever + Open source (GPL‑3.0) + No account required +
+
+ +
+
+
+ SatsPrice app showing BTC to USD price, sats conversion, and a list of currencies +
+ +
+
Live‑style price
+
$77,300
+
1 USD ≈ 1,294 sats
+
+ +
+
+
Coinbase & CoinGeckoor set your own rate
+
+
+
+
+ + +
+
+ 🔄 Multi‑source pricing + 🌍 150+ currencies + 🥇 Precious metals + 🔓 No ads, no accounts + 💻 Native on every platform +
+
+ + +
+
+
+

Capabilities

+

Everything you need to think in sats

+

A focused calculator that does one job — Bitcoin, satoshis, and fiat conversion — and does it well on every device you own.

+
+ +
+
+
🔄
+

Multi‑source pricing

+

Live BTC/fiat rates from Coinbase and CoinGecko, refreshed with a tap — or enter your own exchange rate manually.

+
+ +
+
🧮
+

Instant conversion

+

Type into any field — Sats, BTC, or fiat — and watch every other value update immediately.

+
+ +
+
🌍
+

150+ currencies

+

Every major fiat currency with country flags, smart search, and a Priced / Unpriced split so you know what's live.

+
+ +
+
🥇
+

Precious metals

+

Track gold, silver, platinum, and palladium right alongside your fiat currencies.

+
+ +
+
📌
+

Personalized watchlist

+

Reorder currencies, pin favorites to the top, and reset with confirmation — it all persists between launches.

+
+ +
+
🔢
+

Locale‑aware formatting

+

Digit grouping and "updated" timestamps that read naturally, no matter where you are.

+
+ +
+
💻
+

Native on every platform

+

SwiftUI on iOS and macOS, Compose Multiplatform on Android — built with Kotlin Multiplatform to feel right at home on each device, not like a port.

+
+ +
+
🔓
+

Free & open source

+

GPL‑3.0 licensed, no ads, no accounts, no tracking. Inspect every line on GitHub.

+
+
+
+
+ + +
+
+
+

See it in action

+

One app, at home on every screen

+

Real screenshots from Android, iPhone, iPad, and Mac — the same fast, focused experience everywhere.

+
+ +
+ + + + +
+ +
+
+
SatsPrice on Android — price source and conversion
+
SatsPrice on Android — currency list
+
SatsPrice on Android — reorder currency menu
+
SatsPrice on Android
+
SatsPrice on Android
+
SatsPrice on Android — searching currencies by name
+
SatsPrice on Android — reset confirmation dialog
+
SatsPrice on Android
+
+
+ +
+
+
SatsPrice on iPhone — price source and conversion
+
SatsPrice on iPhone
+
SatsPrice on iPhone — editing currency list
+
SatsPrice on iPhone
+
SatsPrice on iPhone
+
SatsPrice on iPhone
+
SatsPrice on iPhone
+
SatsPrice on iPhone
+
+
+ +
+
+
SatsPrice on iPad
+
SatsPrice on iPad
+
SatsPrice on iPad
+
SatsPrice on iPad
+
SatsPrice on iPad
+
SatsPrice on iPad
+
SatsPrice on iPad
+
SatsPrice on iPad
+
+
+ +
+
+
SatsPrice on macOS — main window
+
SatsPrice on macOS
+
SatsPrice on macOS
+
SatsPrice on macOS
+
SatsPrice on macOS
+
SatsPrice on macOS
+
+
+ +

Scroll or swipe to see more →

+
+
+ + +
+
+
+

Get the app

+

Download SatsPrice

+

Pick the option that fits your platform. Every build is free, with no in‑app purchases.

+ + + +
+ 🍎 iOS 16.0+ + 🖥️ macOS 13.0+ + 🤖 Android 7.0+ +
+ +

+ 100% open source under GPL‑3.0 — + view the code. +

+
+
+
+ +
+ + + + + + diff --git a/website/script.js b/website/script.js new file mode 100644 index 0000000..f9e3afd --- /dev/null +++ b/website/script.js @@ -0,0 +1,56 @@ +// Mobile nav toggle +const navToggle = document.querySelector(".nav-toggle"); +const mobileNav = document.querySelector(".mobile-nav"); + +if (navToggle && mobileNav) { + navToggle.addEventListener("click", () => { + mobileNav.classList.toggle("open"); + }); + + mobileNav.querySelectorAll("a").forEach((link) => { + link.addEventListener("click", () => mobileNav.classList.remove("open")); + }); +} + +// Platform showcase tabs +const tabButtons = document.querySelectorAll(".tab-btn"); +const tabPanels = document.querySelectorAll(".tab-panel"); + +tabButtons.forEach((btn) => { + btn.addEventListener("click", () => { + const target = btn.getAttribute("data-tab"); + + tabButtons.forEach((b) => b.classList.remove("active")); + tabPanels.forEach((p) => p.classList.remove("active")); + + btn.classList.add("active"); + document.getElementById(target).classList.add("active"); + }); +}); + +// Simulated live BTC price ticker (cosmetic only, not a real feed) +(function priceTicker() { + const valueEl = document.querySelector(".ticker .tk-value"); + const subEl = document.querySelector(".ticker .tk-sub"); + if (!valueEl) return; + + let price = 77300; + + function format(n) { + return n.toLocaleString("en-US", { maximumFractionDigits: 0 }); + } + + function tick() { + price += (Math.random() - 0.5) * 60; + valueEl.textContent = "$" + format(price); + const sats = Math.round(100000000 / price); + subEl.textContent = "1 USD ≈ " + sats.toLocaleString("en-US") + " sats"; + } + + tick(); + setInterval(tick, 2200); +})(); + +// Footer year +const yearEl = document.getElementById("year"); +if (yearEl) yearEl.textContent = new Date().getFullYear(); diff --git a/website/styles.css b/website/styles.css new file mode 100644 index 0000000..de458c0 --- /dev/null +++ b/website/styles.css @@ -0,0 +1,747 @@ +/* ============ Tokens ============ */ +:root { + --bg: #0a0d16; + --bg-soft: #0e1220; + --surface: #141a2c; + --surface-2: #1b2338; + --border: #262f4a; + --border-soft: #1e2740; + --text: #f2f4fb; + --text-dim: #a7afc9; + --text-faint: #6d7593; + --gold: #f7b955; + --gold-soft: #ffd98e; + --blue: #5ec8f2; + --coral: #ff6b6b; + --green: #4ade80; + + --gradient-gold: linear-gradient(135deg, #ffd98e 0%, #f7b955 50%, #e8963f 100%); + --shadow-lg: 0 30px 60px -20px rgba(0, 0, 0, 0.6); + --shadow-md: 0 16px 32px -12px rgba(0, 0, 0, 0.5); + --shadow-glow: 0 0 0 1px rgba(247, 185, 85, 0.15), 0 20px 50px -15px rgba(247, 185, 85, 0.25); + + --radius-sm: 10px; + --radius-md: 16px; + --radius-lg: 24px; + --radius-xl: 32px; + + --container: 1200px; +} + +* { box-sizing: border-box; } + +html { + scroll-behavior: smooth; +} + +body { + margin: 0; + background: var(--bg); + color: var(--text); + font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + line-height: 1.5; + -webkit-font-smoothing: antialiased; + overflow-x: hidden; +} + +img { max-width: 100%; display: block; } + +a { color: inherit; text-decoration: none; } + +.container { + width: 100%; + max-width: var(--container); + margin: 0 auto; + padding-inline: 24px; +} + +section { position: relative; } + +.eyebrow { + display: inline-flex; + align-items: center; + gap: 8px; + font-size: 13px; + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--gold-soft); + margin: 0 0 14px; +} + +.eyebrow::before { + content: ""; + width: 18px; + height: 2px; + background: var(--gradient-gold); + border-radius: 2px; +} + +h1, h2, h3, h4 { + font-family: inherit; + margin: 0; + letter-spacing: -0.02em; +} + +.section-head { + max-width: 640px; + margin: 0 auto 56px; + text-align: center; +} + +.section-head h2 { + font-size: clamp(28px, 4vw, 42px); + font-weight: 700; + color: var(--text); +} + +.section-head p { + margin-top: 14px; + color: var(--text-dim); + font-size: 17px; +} + +/* ============ Background texture ============ */ +.bg-glow { + position: fixed; + inset: 0; + z-index: -1; + background: + radial-gradient(700px 500px at 12% -5%, rgba(247, 185, 85, 0.16), transparent 60%), + radial-gradient(800px 600px at 100% 10%, rgba(94, 200, 242, 0.12), transparent 55%), + radial-gradient(900px 700px at 50% 120%, rgba(247, 185, 85, 0.08), transparent 60%), + var(--bg); +} + +/* ============ Buttons ============ */ +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 10px; + padding: 14px 24px; + border-radius: 999px; + font-weight: 600; + font-size: 15px; + border: 1px solid transparent; + cursor: pointer; + transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease, border-color 0.18s ease; + white-space: nowrap; +} + +.btn-primary { + background: var(--gradient-gold); + color: #1a1305; + box-shadow: 0 12px 30px -10px rgba(247, 185, 85, 0.55); +} + +.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 18px 36px -10px rgba(247, 185, 85, 0.65); } + +.btn-ghost { + background: rgba(255, 255, 255, 0.03); + color: var(--text); + border-color: var(--border); + backdrop-filter: blur(6px); +} + +.btn-ghost:hover { border-color: rgba(247, 185, 85, 0.5); transform: translateY(-2px); } + +.btn-sm { padding: 10px 18px; font-size: 13px; } + +/* ============ Header ============ */ +.site-header { + position: sticky; + top: 0; + z-index: 100; + background: rgba(10, 13, 22, 0.72); + backdrop-filter: blur(14px); + border-bottom: 1px solid var(--border-soft); +} + +.site-header .container { + display: flex; + align-items: center; + justify-content: space-between; + height: 72px; +} + +.brand { + display: flex; + align-items: center; + gap: 10px; + font-weight: 700; + font-size: 17px; + letter-spacing: -0.01em; +} + +.brand img { + width: 34px; + height: 34px; + border-radius: 9px; +} + +.main-nav { + display: flex; + align-items: center; + gap: 36px; +} + +.main-nav a { + font-size: 14.5px; + font-weight: 500; + color: var(--text-dim); + transition: color 0.15s ease; +} + +.main-nav a:hover { color: var(--text); } + +.header-cta { display: flex; align-items: center; gap: 14px; } + +.nav-toggle { + display: none; + width: 40px; + height: 40px; + border-radius: 10px; + border: 1px solid var(--border); + background: var(--surface); + color: var(--text); + align-items: center; + justify-content: center; + cursor: pointer; +} + +.mobile-nav { + display: none; + flex-direction: column; + gap: 2px; + padding: 10px 24px 20px; + border-bottom: 1px solid var(--border-soft); + background: var(--bg-soft); +} + +.mobile-nav a { + padding: 12px 4px; + font-size: 15px; + font-weight: 500; + color: var(--text-dim); + border-bottom: 1px solid var(--border-soft); +} + +.mobile-nav.open { display: flex; } + +/* ============ Hero ============ */ +.hero { + padding: 84px 0 60px; +} + +.hero .container { + display: grid; + grid-template-columns: 1.05fr 0.95fr; + align-items: center; + gap: 48px; +} + +.hero-copy h1 { + font-size: clamp(36px, 5.2vw, 58px); + font-weight: 800; + line-height: 1.06; +} + +.hero-copy h1 .accent { + background: var(--gradient-gold); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +.hero-copy p.lead { + margin: 22px 0 0; + font-size: 18px; + color: var(--text-dim); + max-width: 520px; +} + +.hero-actions { + display: flex; + flex-wrap: wrap; + gap: 14px; + margin-top: 32px; +} + +.platform-pills { + display: flex; + flex-wrap: wrap; + gap: 10px; + margin-top: 28px; +} + +.pill { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 8px 14px; + border-radius: 999px; + background: var(--surface); + border: 1px solid var(--border); + font-size: 13px; + font-weight: 600; + color: var(--text-dim); +} + +.pill svg { width: 15px; height: 15px; flex-shrink: 0; } + +.trust-row { + display: flex; + flex-wrap: wrap; + gap: 18px; + margin-top: 26px; + font-size: 13px; + color: var(--text-faint); +} + +.trust-row span { display: inline-flex; align-items: center; gap: 6px; } +.trust-row span::before { content: "✓"; color: var(--green); font-weight: 700; } + +/* Hero visual */ +.hero-visual { + position: relative; + display: flex; + justify-content: center; + align-items: flex-start; + padding-top: 10px; +} + +.phone-frame { + position: relative; + width: min(300px, 78vw); + border-radius: 46px; + padding: 14px; + background: linear-gradient(160deg, #232c46, #11162650); + border: 1px solid var(--border); + box-shadow: var(--shadow-lg); + z-index: 2; +} + +.phone-frame::before { + content: ""; + position: absolute; + top: 26px; + left: 50%; + transform: translateX(-50%); + width: 90px; + height: 22px; + background: #05070c; + border-radius: 20px; + z-index: 3; +} + +.phone-frame img { + border-radius: 32px; + border: 1px solid rgba(255, 255, 255, 0.06); + display: block; + width: 100%; +} + +.float-card { + position: absolute; + background: rgba(20, 26, 44, 0.85); + border: 1px solid var(--border); + backdrop-filter: blur(16px); + border-radius: var(--radius-md); + box-shadow: var(--shadow-md); + padding: 14px 16px; + z-index: 4; + animation: float 5s ease-in-out infinite; +} + +.float-card.ticker { + top: -6px; + right: -18px; + min-width: 190px; +} + +.float-card.sources { + bottom: 60px; + left: -34px; + animation-delay: 1.2s; +} + +.ticker .tk-label { + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--text-faint); + display: flex; + align-items: center; + gap: 6px; +} + +.ticker .tk-label .dot { + width: 7px; + height: 7px; + border-radius: 50%; + background: var(--green); + box-shadow: 0 0 0 3px rgba(74, 222, 128, 0.18); + animation: pulse 1.8s ease-in-out infinite; +} + +.ticker .tk-value { + font-size: 21px; + font-weight: 700; + margin-top: 4px; + font-variant-numeric: tabular-nums; +} + +.ticker .tk-sub { + font-size: 12px; + color: var(--text-faint); + margin-top: 3px; + font-variant-numeric: tabular-nums; +} + +.float-card.sources { display: flex; align-items: center; gap: 10px; padding: 12px 16px; } +.float-card.sources .ic { + width: 34px; height: 34px; border-radius: 10px; + background: var(--gradient-gold); + display: flex; align-items: center; justify-content: center; + font-size: 16px; +} +.float-card.sources .tx { font-size: 12.5px; font-weight: 600; color: var(--text); line-height: 1.3; } +.float-card.sources .tx small { display: block; font-weight: 400; color: var(--text-faint); } + +@keyframes float { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-10px); } +} + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.35; } +} + +.hero-blob { + position: absolute; + width: 460px; + height: 460px; + border-radius: 50%; + background: radial-gradient(circle, rgba(247, 185, 85, 0.22), transparent 70%); + filter: blur(10px); + top: -60px; + right: -60px; + z-index: 0; + pointer-events: none; +} + +/* ============ Logo strip ============ */ +.logo-strip { + padding: 30px 0 10px; + border-top: 1px solid var(--border-soft); + border-bottom: 1px solid var(--border-soft); +} + +.logo-strip .container { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 14px 40px; +} + +.logo-strip .item { + display: flex; + align-items: center; + gap: 8px; + font-size: 13px; + color: var(--text-faint); + font-weight: 600; + letter-spacing: 0.02em; +} + +.logo-strip svg { width: 16px; height: 16px; } + +/* ============ Features ============ */ +.features { padding: 110px 0; } + +.feature-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 20px; +} + +.feature-card { + background: var(--surface); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + padding: 26px 24px; + transition: transform 0.2s ease, border-color 0.2s ease, background 0.2s ease; +} + +.feature-card:hover { + transform: translateY(-4px); + border-color: rgba(247, 185, 85, 0.35); + background: var(--surface-2); +} + +.feature-card .icon { + width: 46px; + height: 46px; + border-radius: 13px; + display: flex; + align-items: center; + justify-content: center; + font-size: 22px; + background: linear-gradient(150deg, rgba(247, 185, 85, 0.18), rgba(94, 200, 242, 0.12)); + border: 1px solid var(--border); + margin-bottom: 18px; +} + +.feature-card h3 { + font-size: 16.5px; + font-weight: 700; + margin-bottom: 8px; +} + +.feature-card p { + font-size: 14.5px; + color: var(--text-dim); + margin: 0; +} + +.feature-card.wide { grid-column: span 2; } + +/* ============ Platform showcase ============ */ +.showcase { padding: 40px 0 110px; } + +.tabs { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 10px; + margin-bottom: 44px; +} + +.tab-btn { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 11px 20px; + border-radius: 999px; + border: 1px solid var(--border); + background: var(--surface); + color: var(--text-dim); + font-weight: 600; + font-size: 14px; + cursor: pointer; + transition: all 0.18s ease; +} + +.tab-btn svg { width: 16px; height: 16px; } + +.tab-btn.active { + background: var(--gradient-gold); + color: #1a1305; + border-color: transparent; + box-shadow: 0 10px 24px -10px rgba(247, 185, 85, 0.6); +} + +.tab-panel { display: none; } +.tab-panel.active { display: block; animation: fadein 0.35s ease; } + +@keyframes fadein { + from { opacity: 0; transform: translateY(8px); } + to { opacity: 1; transform: translateY(0); } +} + +.shot-scroll { + display: flex; + gap: 20px; + overflow-x: auto; + padding: 10px 4px 26px; + scroll-snap-type: x proximity; + -webkit-overflow-scrolling: touch; +} + +.shot-scroll::-webkit-scrollbar { height: 8px; } +.shot-scroll::-webkit-scrollbar-track { background: transparent; } +.shot-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 8px; } + +.shot-scroll .shot { + flex: 0 0 auto; + scroll-snap-align: start; + border-radius: var(--radius-md); + overflow: hidden; + box-shadow: var(--shadow-md); + border: 1px solid var(--border); + background: var(--surface); +} + +.shot-scroll.h-phone .shot { height: 480px; } +.shot-scroll.h-phone .shot img { height: 100%; width: auto; } + +.shot-scroll.h-tablet .shot { height: 340px; } +.shot-scroll.h-tablet .shot img { height: 100%; width: auto; } + +.shot-scroll.h-desktop .shot { height: 300px; } +.shot-scroll.h-desktop .shot img { height: 100%; width: auto; } + +.shot.framed-phone { border-radius: 30px; border: 6px solid #1c2340; } +.shot.framed-tablet { border-radius: 18px; border: 6px solid #1c2340; } + +.showcase-caption { + text-align: center; + color: var(--text-faint); + font-size: 13.5px; + margin-top: -10px; +} + +/* ============ Download ============ */ +.download { + padding: 100px 0 110px; +} + +.download-card { + background: linear-gradient(155deg, var(--surface) 0%, var(--surface-2) 100%); + border: 1px solid var(--border); + border-radius: var(--radius-xl); + padding: 64px 48px; + text-align: center; + position: relative; + overflow: hidden; +} + +.download-card::before { + content: ""; + position: absolute; + inset: 0; + background: radial-gradient(500px 260px at 50% -10%, rgba(247, 185, 85, 0.18), transparent 70%); + pointer-events: none; +} + +.download-card h2 { + font-size: clamp(26px, 4vw, 38px); + font-weight: 800; +} + +.download-card > p { + color: var(--text-dim); + margin: 14px auto 0; + max-width: 480px; + font-size: 16px; +} + +.badge-row { + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: center; + gap: 18px; + margin-top: 40px; + position: relative; +} + +.badge-link { + display: inline-flex; + align-items: center; + transition: transform 0.18s ease, filter 0.18s ease; + border-radius: 12px; +} + +.badge-link:hover { transform: translateY(-3px); } + +.badge-link img { height: 56px; width: auto; border-radius: 12px; } + +.badge-link.obtainium img, +.badge-link.github img { height: 56px; } + +.version-row { + margin-top: 38px; + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 12px; + position: relative; +} + +.version-row .pill { background: rgba(255, 255, 255, 0.03); } + +.oss-note { + margin-top: 26px; + font-size: 13.5px; + color: var(--text-faint); + position: relative; +} + +.oss-note a { color: var(--gold-soft); font-weight: 600; } +.oss-note a:hover { text-decoration: underline; } + +/* ============ Footer ============ */ +.site-footer { + border-top: 1px solid var(--border-soft); + padding: 48px 0 36px; +} + +.footer-grid { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 20px; +} + +.footer-brand { + display: flex; + align-items: center; + gap: 10px; + font-weight: 700; + color: var(--text-dim); +} + +.footer-brand img { width: 26px; height: 26px; border-radius: 7px; } + +.footer-links { + display: flex; + gap: 26px; + flex-wrap: wrap; + font-size: 14px; + color: var(--text-dim); +} + +.footer-links a:hover { color: var(--text); } + +.footer-meta { + margin-top: 28px; + padding-top: 24px; + border-top: 1px solid var(--border-soft); + display: flex; + justify-content: space-between; + flex-wrap: wrap; + gap: 10px; + font-size: 12.5px; + color: var(--text-faint); +} + +/* ============ Responsive ============ */ +@media (max-width: 980px) { + .main-nav { display: none; } + .nav-toggle { display: inline-flex; } + .hero .container { grid-template-columns: 1fr; } + .hero-visual { margin-top: 20px; } + .feature-grid { grid-template-columns: repeat(2, 1fr); } + .feature-card.wide { grid-column: span 2; } +} + +@media (max-width: 640px) { + .hero { padding: 48px 0 40px; } + .hero-copy p.lead { font-size: 16px; } + .feature-grid { grid-template-columns: 1fr; } + .feature-card.wide { grid-column: span 1; } + .download-card { padding: 44px 22px; } + .badge-link img { height: 48px; } + .float-card.sources { left: -10px; } + .float-card.ticker { right: -8px; } + .footer-grid { flex-direction: column; align-items: flex-start; } + .footer-meta { flex-direction: column; } +} + +@media (max-width: 400px) { + .header-cta .btn { display: none; } +}