CTA App Download
Секция загрузки мобильного приложения с мокапом смартфона и кнопками магазинов приложений.
ctamobileapp-storedownloadmockup
Живое превью
Mobile Experience
Manage Your Astro Deployments On the Go
Download our native companion mobile application. Monitor real-time builds, latency metrics, and team notifications directly from your pocket.
⚡ Instant Push Alerts
📊 Real-Time Analytics
🔒 Biometric Security
Production Edge 100% UP
✓ Build #402 deployed in 12s
⚡ TTFB latency: 14ms
Использование
Скопируйте и вставьте этот код на вашу страницу Astro:
astro
---
import { CtaAppDownload } from 'astro-component-kit';
---
<CtaAppDownload /> ---
import { CtaAppDownload } from 'astro-component-kit';
---
<CtaAppDownload /> Ручная установка
Если вы не используете пакет npm, создайте файл и вставьте следующий код: src/components/sections/CTAAppDownload.astro:
astro
---
/**
* CtaAppDownload — Full-page mobile app showcase and download CTA section with device mockup and store buttons.
*
* @param {string} badge - Eyebrow badge text.
* @param {string} title - Main headline.
* @param {string} subtitle - Description text.
*/
interface Props {
badge?: string;
title?: string;
subtitle?: string;
className?: string;
}
const {
badge = "Mobile Experience",
title = "Manage Your Astro Deployments On the Go",
subtitle = "Download our native companion mobile application. Monitor real-time builds, latency metrics, and team notifications directly from your pocket.",
className = ""
} = Astro.props;
---
<div class="cq-cta-app-download-cq">
<section class={`app-download-section ${className}`} aria-labelledby="app-title">
<div class="container">
<div class="app-card">
<div class="app-info">
{badge && <span class="app-badge">{badge}</span>}
<h2 id="app-title" class="app-title">{title}</h2>
<p class="app-subtitle">{subtitle}</p>
<div class="app-features-mini">
<div class="feat-pill">⚡ Instant Push Alerts</div>
<div class="feat-pill">📊 Real-Time Analytics</div>
<div class="feat-pill">🔒 Biometric Security</div>
</div>
<div class="store-buttons">
<a href="#app-store" class="store-btn">
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M15.97 6.85c.66-.8 1.11-1.92.99-3.04-.96.04-2.13.64-2.82 1.44-.6.7-.99 1.83-1.02 2.98.08.01.16.02.24.02.88 0 1.95-.58 2.61-1.4z"/></svg>
<div class="store-btn__text">
<span class="store-btn__sub">Download on the</span>
<span class="store-btn__name">App Store</span>
</div>
</a>
<a href="#google-play" class="store-btn">
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M3.609 1.814L13.792 12 3.61 22.186a2.227 2.227 0 0 1-.22-.968V2.782c0-.361.08-.696.22-.968zm11.24 11.24l2.128 2.129-12.03 6.946 9.902-9.075zm2.933-2.05l2.673 1.543c.876.505.876 1.332 0 1.837l-2.673 1.544-2.338-2.338 2.338-2.586zM4.947 1.87l12.031 6.947-2.128 2.128-9.903-9.075z"/></svg>
<div class="store-btn__text">
<span class="store-btn__sub">GET IT ON</span>
<span class="store-btn__name">Google Play</span>
</div>
</a>
</div>
</div>
<div class="app-visual">
<div class="phone-frame">
<div class="phone-notch"></div>
<div class="phone-screen">
<div class="phone-header">
<div class="phone-avatar"></div>
<span>Production Edge</span>
<span class="phone-live">100% UP</span>
</div>
<div class="phone-chart"></div>
<div class="phone-card-mini">✓ Build #402 deployed in 12s</div>
<div class="phone-card-mini">⚡ TTFB latency: 14ms</div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
<style>
.cq-cta-app-download-cq { container-type: inline-size; }
.app-download-section {
padding: var(--sp-20, 5rem) var(--sp-6, 1.5rem);
background: var(--c-bg-primary, #030712);
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.app-card {
background: linear-gradient(135deg, rgba(15, 23, 42, 0.8) 0%, rgba(10, 15, 30, 0.9) 100%);
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.1);
border-radius: var(--r-2xl, 24px);
padding: clamp(2rem, 5vw, 4rem);
display: grid;
grid-template-columns: 1.2fr 0.8fr;
gap: 3rem;
align-items: center;
}
.app-badge {
display: inline-flex;
padding: 0.35rem 0.9rem;
border-radius: 9999px;
font-size: 0.78rem;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
background: color-mix(in srgb, var(--c-primary, #b8860b) 12%, transparent);
color: #eab308;
border: 1px solid rgba(234, 179, 8, 0.25);
margin-bottom: var(--sp-4, 1rem);
}
.app-title {
font-size: clamp(2rem, 4vw, 2.8rem);
font-weight: 900;
color: #fff;
line-height: 1.2;
letter-spacing: -0.02em;
margin: 0 0 1rem;
}
.app-subtitle {
font-size: 1.05rem;
color: #94a3b8;
line-height: 1.6;
margin: 0 0 1.75rem;
}
.app-features-mini {
display: flex;
flex-wrap: wrap;
gap: 0.6rem;
margin-bottom: 2rem;
}
.feat-pill {
padding: 0.4rem 0.85rem;
background: rgb(var(--ink-rgb, 255 255 255) / 0.05);
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.08);
border-radius: 9999px;
font-size: 0.82rem;
color: #cbd5e1;
}
.store-buttons {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.store-btn {
display: inline-flex;
align-items: center;
gap: 0.75rem;
padding: 0.65rem 1.25rem;
background: rgba(0, 0, 0, 0.6);
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.15);
border-radius: 12px;
color: #fff;
text-decoration: none;
transition: all 0.2s ease;
}
.store-btn:hover {
background: rgb(var(--ink-rgb, 255 255 255) / 0.1);
border-color: rgb(var(--ink-rgb, 255 255 255) / 0.3);
}
.store-btn__text {
display: flex;
flex-direction: column;
text-align: left;
}
.store-btn__sub {
font-size: 0.65rem;
color: #94a3b8;
text-transform: uppercase;
}
.store-btn__name {
font-size: 1rem;
font-weight: 700;
}
/* Phone visual mockup */
.app-visual {
display: flex;
justify-content: center;
}
.phone-frame {
width: 250px;
height: 400px;
background: #020617;
border: 3px solid rgb(var(--ink-rgb, 255 255 255) / 0.2);
border-radius: 36px;
padding: 12px;
box-shadow: 0 20px 50px -10px rgba(0, 0, 0, 0.8);
display: flex;
flex-direction: column;
}
.phone-notch {
width: 70px;
height: 12px;
background: #0f172a;
border-radius: 999px;
margin: 0 auto 12px;
}
.phone-screen {
flex: 1;
background: rgba(15, 23, 42, 0.8);
border-radius: 24px;
padding: 1rem;
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.phone-header {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 0.75rem;
color: #fff;
font-weight: 700;
}
.phone-live {
font-size: 0.65rem;
color: #10b981;
background: rgba(16, 185, 129, 0.15);
padding: 0.15rem 0.4rem;
border-radius: 999px;
}
.phone-chart {
height: 80px;
background: linear-gradient(180deg, rgba(99, 102, 241, 0.3) 0%, transparent 100%);
border-bottom: 2px solid #6366f1;
border-radius: 8px;
}
.phone-card-mini {
padding: 0.5rem;
background: rgb(var(--ink-rgb, 255 255 255) / 0.05);
border-radius: 8px;
font-size: 0.72rem;
color: #cbd5e1;
}
@container (max-width: 960px) {
.app-card {
grid-template-columns: 1fr;
}
}
</style> ---
/**
* CtaAppDownload — Full-page mobile app showcase and download CTA section with device mockup and store buttons.
*
* @param {string} badge - Eyebrow badge text.
* @param {string} title - Main headline.
* @param {string} subtitle - Description text.
*/
interface Props {
badge?: string;
title?: string;
subtitle?: string;
className?: string;
}
const {
badge = "Mobile Experience",
title = "Manage Your Astro Deployments On the Go",
subtitle = "Download our native companion mobile application. Monitor real-time builds, latency metrics, and team notifications directly from your pocket.",
className = ""
} = Astro.props;
---
<div class="cq-cta-app-download-cq">
<section class={`app-download-section ${className}`} aria-labelledby="app-title">
<div class="container">
<div class="app-card">
<div class="app-info">
{badge && <span class="app-badge">{badge}</span>}
<h2 id="app-title" class="app-title">{title}</h2>
<p class="app-subtitle">{subtitle}</p>
<div class="app-features-mini">
<div class="feat-pill">⚡ Instant Push Alerts</div>
<div class="feat-pill">📊 Real-Time Analytics</div>
<div class="feat-pill">🔒 Biometric Security</div>
</div>
<div class="store-buttons">
<a href="#app-store" class="store-btn">
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M15.97 6.85c.66-.8 1.11-1.92.99-3.04-.96.04-2.13.64-2.82 1.44-.6.7-.99 1.83-1.02 2.98.08.01.16.02.24.02.88 0 1.95-.58 2.61-1.4z"/></svg>
<div class="store-btn__text">
<span class="store-btn__sub">Download on the</span>
<span class="store-btn__name">App Store</span>
</div>
</a>
<a href="#google-play" class="store-btn">
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M3.609 1.814L13.792 12 3.61 22.186a2.227 2.227 0 0 1-.22-.968V2.782c0-.361.08-.696.22-.968zm11.24 11.24l2.128 2.129-12.03 6.946 9.902-9.075zm2.933-2.05l2.673 1.543c.876.505.876 1.332 0 1.837l-2.673 1.544-2.338-2.338 2.338-2.586zM4.947 1.87l12.031 6.947-2.128 2.128-9.903-9.075z"/></svg>
<div class="store-btn__text">
<span class="store-btn__sub">GET IT ON</span>
<span class="store-btn__name">Google Play</span>
</div>
</a>
</div>
</div>
<div class="app-visual">
<div class="phone-frame">
<div class="phone-notch"></div>
<div class="phone-screen">
<div class="phone-header">
<div class="phone-avatar"></div>
<span>Production Edge</span>
<span class="phone-live">100% UP</span>
</div>
<div class="phone-chart"></div>
<div class="phone-card-mini">✓ Build #402 deployed in 12s</div>
<div class="phone-card-mini">⚡ TTFB latency: 14ms</div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
<style>
.cq-cta-app-download-cq { container-type: inline-size; }
.app-download-section {
padding: var(--sp-20, 5rem) var(--sp-6, 1.5rem);
background: var(--c-bg-primary, #030712);
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.app-card {
background: linear-gradient(135deg, rgba(15, 23, 42, 0.8) 0%, rgba(10, 15, 30, 0.9) 100%);
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.1);
border-radius: var(--r-2xl, 24px);
padding: clamp(2rem, 5vw, 4rem);
display: grid;
grid-template-columns: 1.2fr 0.8fr;
gap: 3rem;
align-items: center;
}
.app-badge {
display: inline-flex;
padding: 0.35rem 0.9rem;
border-radius: 9999px;
font-size: 0.78rem;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
background: color-mix(in srgb, var(--c-primary, #b8860b) 12%, transparent);
color: #eab308;
border: 1px solid rgba(234, 179, 8, 0.25);
margin-bottom: var(--sp-4, 1rem);
}
.app-title {
font-size: clamp(2rem, 4vw, 2.8rem);
font-weight: 900;
color: #fff;
line-height: 1.2;
letter-spacing: -0.02em;
margin: 0 0 1rem;
}
.app-subtitle {
font-size: 1.05rem;
color: #94a3b8;
line-height: 1.6;
margin: 0 0 1.75rem;
}
.app-features-mini {
display: flex;
flex-wrap: wrap;
gap: 0.6rem;
margin-bottom: 2rem;
}
.feat-pill {
padding: 0.4rem 0.85rem;
background: rgb(var(--ink-rgb, 255 255 255) / 0.05);
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.08);
border-radius: 9999px;
font-size: 0.82rem;
color: #cbd5e1;
}
.store-buttons {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.store-btn {
display: inline-flex;
align-items: center;
gap: 0.75rem;
padding: 0.65rem 1.25rem;
background: rgba(0, 0, 0, 0.6);
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.15);
border-radius: 12px;
color: #fff;
text-decoration: none;
transition: all 0.2s ease;
}
.store-btn:hover {
background: rgb(var(--ink-rgb, 255 255 255) / 0.1);
border-color: rgb(var(--ink-rgb, 255 255 255) / 0.3);
}
.store-btn__text {
display: flex;
flex-direction: column;
text-align: left;
}
.store-btn__sub {
font-size: 0.65rem;
color: #94a3b8;
text-transform: uppercase;
}
.store-btn__name {
font-size: 1rem;
font-weight: 700;
}
/* Phone visual mockup */
.app-visual {
display: flex;
justify-content: center;
}
.phone-frame {
width: 250px;
height: 400px;
background: #020617;
border: 3px solid rgb(var(--ink-rgb, 255 255 255) / 0.2);
border-radius: 36px;
padding: 12px;
box-shadow: 0 20px 50px -10px rgba(0, 0, 0, 0.8);
display: flex;
flex-direction: column;
}
.phone-notch {
width: 70px;
height: 12px;
background: #0f172a;
border-radius: 999px;
margin: 0 auto 12px;
}
.phone-screen {
flex: 1;
background: rgba(15, 23, 42, 0.8);
border-radius: 24px;
padding: 1rem;
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.phone-header {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 0.75rem;
color: #fff;
font-weight: 700;
}
.phone-live {
font-size: 0.65rem;
color: #10b981;
background: rgba(16, 185, 129, 0.15);
padding: 0.15rem 0.4rem;
border-radius: 999px;
}
.phone-chart {
height: 80px;
background: linear-gradient(180deg, rgba(99, 102, 241, 0.3) 0%, transparent 100%);
border-bottom: 2px solid #6366f1;
border-radius: 8px;
}
.phone-card-mini {
padding: 0.5rem;
background: rgb(var(--ink-rgb, 255 255 255) / 0.05);
border-radius: 8px;
font-size: 0.72rem;
color: #cbd5e1;
}
@container (max-width: 960px) {
.app-card {
grid-template-columns: 1fr;
}
}
</style>