1 звезда на GitHub = 1 новый компонент.

Поставить звезду
Призывы к действию (CTA)

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>