Menu

Change language

GitHub repo

Coming Soon

blockmarketing

Interactive launch and maintenance workbench with high-impact countdown, VIP early access waitlist queue allocator, live launch roadmap progress tracker, and feature sneak-peek previews.

Installation

$npx shadcn-svelte@latest add https://uipkge.dev/r/svelte/coming-soon.json
Manifest:https://uipkge.dev/r/svelte/coming-soon.jsonInstalls to:src/lib/components/blocks/coming-soon/

Variants

Loading interactive previews…

Files installed (1)

  • src/lib/components/blocks/coming-soon/ComingSoon.svelte21.2 kB
    <script lang="ts" module>
      import type { Component } from 'svelte'
    
      export interface ComingSoonMilestone {
        id: string
        title: string
        category: string
        status: 'completed' | 'in_progress' | 'scheduled'
        completionPercent: number
        date: string
      }
    
      export interface ComingSoonTeaser {
        id: string
        badge: string
        title: string
        description: string
        icon: Component
        statLabel: string
        statValue: string
        codeSnippet: string
      }
    
      export type WaitlistRole = 'frontend' | 'architect' | 'founder'
    
      export interface ComingSoonProps {
        targetIso?: string
        statusUrl?: string
        productVersion?: string
        class?: string
      }
    </script>
    
    <script lang="ts">
      import { onDestroy, onMount } from 'svelte'
      import {
        Activity,
        ArrowRight,
        ArrowUpRight,
        Bot,
        Check,
        CheckCircle2,
        Copy,
        Palette,
        Rocket,
        ShieldCheck,
        Terminal,
        Zap,
      } from '@lucide/svelte'
      import { Badge } from '$lib/components/ui/badge'
      import { Button } from '$lib/components/ui/button'
      import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '$lib/components/ui/card'
      import { Input } from '$lib/components/ui/input'
      import { Progress } from '$lib/components/ui/progress'
      import { Separator } from '$lib/components/ui/separator'
    
      let {
        targetIso = '',
        statusUrl = 'https://status.uipkge.dev',
        productVersion = 'v2.0 Beta',
        class: className,
      }: ComingSoonProps = $props()
    
      function pad(value: number) {
        return String(value).padStart(2, '0')
      }
    
      const initialMilestones: ComingSoonMilestone[] = [
        {
          id: 'm1',
          title: 'Multi-Framework Compiler & Monorepo Architecture',
          category: 'Core Infra',
          status: 'completed',
          completionPercent: 100,
          date: 'Aug 15, 2026',
        },
        {
          id: 'm2',
          title: 'Tailwind CSS v4 OKLCH Dynamic Theming Engine',
          category: 'Design System',
          status: 'completed',
          completionPercent: 100,
          date: 'Aug 18, 2026',
        },
        {
          id: 'm3',
          title: 'Zero-Lockin Code Distribution Registry & CLI',
          category: 'DX & Tooling',
          status: 'completed',
          completionPercent: 100,
          date: 'Aug 21, 2026',
        },
        {
          id: 'm4',
          title: 'Multi-Region Edge Registry Cache & Global SLA Testing',
          category: 'Infrastructure',
          status: 'in_progress',
          completionPercent: 88,
          date: 'Target: 3 Days',
        },
        {
          id: 'm5',
          title: 'Public V2.0 Global General Availability Rollout',
          category: 'Release',
          status: 'scheduled',
          completionPercent: 0,
          date: 'Target: 7 Days',
        },
      ]
    
      const teasers: ComingSoonTeaser[] = [
        {
          id: 'agentic',
          badge: 'Flagship AI',
          title: 'Autonomous Multi-Agent Orchestrator',
          description: 'Decompose complex workflow DAGs into parallel subagent execution with real-time vector memory.',
          icon: Bot,
          statLabel: 'DAG Execution Speed',
          statValue: '120ms P99',
          codeSnippet: 'npx shadcn-svelte@latest add https://uipkge.dev/r/svelte/ai-agent-orchestrator.json',
        },
        {
          id: 'design',
          badge: 'Design Engineering',
          title: 'Tailwind v4 OKLCH Fluid Theme Tokens',
          description:
            'Perceptually uniform color spaces with automatic high-contrast dark mode switching & zero CSS bloat.',
          icon: Palette,
          statLabel: 'Bundle Size Overhead',
          statValue: '0.00 kB',
          codeSnippet: 'npx shadcn-svelte@latest add https://uipkge.dev/r/svelte/theme-customize.json',
        },
        {
          id: 'edge',
          badge: 'Ultra Low Latency',
          title: 'Cloudflare Workers Multi-Region Cache',
          description: 'Global component manifest resolution with smart geo-routing and edge-cached JSON trees.',
          icon: Zap,
          statLabel: 'Global Median Latency',
          statValue: '8.4ms',
          codeSnippet: 'curl -s https://uipkge.dev/r/svelte/init.json',
        },
      ]
    
      const ROLES: { id: WaitlistRole; label: string }[] = [
        { id: 'frontend', label: 'Frontend / UI' },
        { id: 'architect', label: 'Tech Lead / Arch' },
        { id: 'founder', label: 'CTO / Founder' },
      ]
    
      const deadline = targetIso ? new Date(targetIso).getTime() : Date.now() + 7 * 24 * 60 * 60 * 1000
    
      let days = $state('00')
      let hours = $state('00')
      let minutes = $state('00')
      let seconds = $state('00')
      let activeTeaserIndex = $state(0)
    
      // Waitlist form state
      let email = $state('')
      let role: WaitlistRole = $state('frontend')
      let submitted = $state(false)
      let queuePosition: number | null = $state(null)
      let copiedReferral = $state(false)
      let copiedCli = $state(false)
    
      function tick() {
        const diff = Math.max(0, deadline - Date.now())
        days = pad(Math.floor(diff / 86_400_000))
        hours = pad(Math.floor((diff % 86_400_000) / 3_600_000))
        minutes = pad(Math.floor((diff % 3_600_000) / 60_000))
        seconds = pad(Math.floor((diff % 60_000) / 1000))
      }
    
      let timer: ReturnType<typeof setInterval> | undefined
    
      onMount(() => {
        tick()
        timer = setInterval(tick, 1000)
      })
    
      onDestroy(() => {
        if (timer) clearInterval(timer)
      })
    
      function handleWaitlistSubmit(e: SubmitEvent) {
        e.preventDefault()
        if (!email) return
        const randomPos = Math.floor(Math.random() * 80) + 120
        queuePosition = randomPos
        submitted = true
      }
    
      function copyReferral() {
        navigator.clipboard.writeText(`https://uipkge.dev/invite?ref=queue_${queuePosition}`)
        copiedReferral = true
        setTimeout(() => (copiedReferral = false), 2000)
      }
    
      function copyTeaserSnippet(snippet: string) {
        navigator.clipboard.writeText(snippet)
        copiedCli = true
        setTimeout(() => (copiedCli = false), 2000)
      }
    
      const units = $derived([
        { label: 'Days', value: days },
        { label: 'Hours', value: hours },
        { label: 'Minutes', value: minutes },
        { label: 'Seconds', value: seconds },
      ])
    
      const overallReadiness = $derived(
        Math.round(initialMilestones.reduce((acc, m) => acc + m.completionPercent, 0) / initialMilestones.length),
      )
    
      const activeTeaser = $derived(teasers[activeTeaserIndex])
      const ActiveTeaserIcon = $derived(activeTeaser.icon)
    </script>
    
    <section
      data-slot="coming-soon"
      class={[
        'bg-background relative flex min-h-screen flex-col justify-between overflow-hidden px-4 py-16 sm:px-6 lg:px-8',
        className,
      ]}
    >
      <!-- Top Telemetry & Status Bar -->
      <div
        class="border-border/70 mx-auto flex w-full max-w-6xl flex-col items-center justify-between gap-4 border-b pb-12 sm:flex-row"
      >
        <div class="flex items-center gap-3">
          <div
            class="bg-primary text-primary-foreground flex size-9 items-center justify-center rounded-xl font-bold shadow-xs"
          >
            <Rocket class="size-5" />
          </div>
          <div>
            <div class="flex items-center gap-2">
              <span class="text-foreground text-sm font-semibold tracking-tight">UIPKGE Engine</span>
              <Badge variant="outline" class="border-primary/30 text-primary px-1.5 py-0.5 font-mono text-xs">
                {productVersion}
              </Badge>
            </div>
            <p class="text-muted-foreground text-xs">Multi-framework registry & visual workbench suite</p>
          </div>
        </div>
    
        <!-- Global SLA Readiness Pill -->
        <div class="bg-muted/40 border-border flex items-center gap-3 rounded-full border px-3.5 py-1.5">
          <div class="bg-success flex size-2 animate-pulse rounded-full"></div>
          <span class="text-muted-foreground font-mono text-xs">
            Staging Infrastructure: <strong class="text-foreground font-semibold">99.99% Operational</strong>
          </span>
          <Separator orientation="vertical" class="h-3.5" />
          <a
            href={statusUrl}
            target="_blank"
            rel="noreferrer"
            class="text-primary inline-flex items-center gap-1 font-mono text-xs hover:underline"
          >
            Live Status <ArrowUpRight class="size-3" />
          </a>
        </div>
      </div>
    
      <!-- Main Hero & Countdown Body -->
      <div class="mx-auto my-auto w-full max-w-6xl space-y-16 py-10">
        <!-- Headline & Subtitle -->
        <div class="mx-auto max-w-3xl space-y-4 text-center">
          <Badge variant="secondary" class="gap-1.5 px-3 py-1 font-mono text-xs shadow-xs">
            <Rocket class="text-primary size-3.5" />
            V2.0 General Availability Launch Matrix
          </Badge>
          <h1 class="text-foreground text-4xl leading-[1.1] font-bold tracking-tight sm:text-5xl lg:text-6xl">
            Production-grade design engineering workbenches.
          </h1>
          <p class="text-muted-foreground mx-auto max-w-2xl text-base leading-relaxed sm:text-lg">
            We are deploying 281+ production-grade primitives and composed workbenches with zero package dependencies. Own
            your source code with complete architectural freedom.
          </p>
        </div>
    
        <!-- High-Impact Digital Countdown Grid -->
        <div class="mx-auto grid max-w-2xl grid-cols-2 gap-4 sm:grid-cols-4">
          {#each units as unit (unit.label)}
            <Card
              class="border-border bg-card/70 group hover:border-primary/40 relative overflow-hidden p-5 text-center shadow-xs backdrop-blur-xs transition-colors"
            >
              <div class="text-foreground font-mono text-4xl font-bold tracking-tight tabular-nums sm:text-5xl">
                {unit.value}
              </div>
              <div class="text-muted-foreground mt-2 font-mono text-xs font-medium tracking-widest uppercase">
                {unit.label}
              </div>
              <div class="bg-primary/20 group-hover:bg-primary absolute right-0 bottom-0 left-0 h-0.5 transition-colors"></div>
            </Card>
          {/each}
        </div>
    
        <!-- Early Access & Queue Tracker Section -->
        <div class="mx-auto w-full max-w-xl">
          <Card class="border-border bg-card overflow-hidden shadow-sm">
            <CardHeader class="pb-4">
              <div class="flex items-center justify-between">
                <CardTitle class="flex items-center gap-2 text-base font-semibold">
                  <ShieldCheck class="text-primary size-4" />
                  Early Access Allocation
                </CardTitle>
                <Badge variant="outline" class="border-success/20 bg-success/10 text-success font-mono text-xs">
                  Batch #2 Opening Soon
                </Badge>
              </div>
              <CardDescription class="text-xs">
                Request priority invite access. Get instant sandbox access to all 281+ blocks before general public launch.
              </CardDescription>
            </CardHeader>
    
            <CardContent>
              {#if !submitted}
                <form class="space-y-4" onsubmit={handleWaitlistSubmit}>
                  <!-- Role Selector Tabs -->
                  <div class="space-y-1.5">
                    <span class="text-foreground text-xs font-medium">Your Primary Engineering Focus</span>
                    <div class="grid grid-cols-3 gap-2">
                      {#each ROLES as r (r.id)}
                        <button
                          type="button"
                          class={[
                            'rounded-lg border px-2.5 py-1.5 text-center text-xs font-medium transition-colors',
                            role === r.id
                              ? 'border-primary bg-primary/10 text-primary font-semibold shadow-xs'
                              : 'border-border bg-background text-muted-foreground hover:text-foreground',
                          ]}
                          onclick={() => (role = r.id)}
                        >
                          {r.label}
                        </button>
                      {/each}
                    </div>
                  </div>
    
                  <!-- Email Input & Submit -->
                  <div class="flex flex-col gap-2 sm:flex-row">
                    <div class="relative flex-1">
                      <Input
                        bind:value={email}
                        type="email"
                        placeholder="[email protected]"
                        required
                        class="h-10 font-mono text-xs"
                      />
                    </div>
                    <Button type="submit" class="h-10 gap-1.5 px-5 text-xs font-semibold">
                      <span>Reserve Spot</span>
                      <ArrowRight class="size-3.5" />
                    </Button>
                  </div>
                  <p class="text-muted-foreground text-center text-xs">
                    No spam. You will only receive your single cryptographic invite token.
                  </p>
                </form>
              {:else}
                <div class="bg-muted/40 border-border space-y-4 rounded-xl border p-4 text-center">
                  <div class="bg-success/10 text-success mx-auto flex size-10 items-center justify-center rounded-full">
                    <Check class="size-5" />
                  </div>
                  <div class="space-y-1">
                    <p class="text-foreground text-sm font-semibold">You are #{queuePosition} in queue!</p>
                    <p class="text-muted-foreground text-xs">
                      Invitation tokens for Batch #2 will be delivered to
                      <strong class="text-foreground font-mono">{email}</strong>.
                    </p>
                  </div>
    
                  <div class="border-border flex flex-col items-center justify-between gap-3 border-t pt-2 sm:flex-row">
                    <span class="text-muted-foreground font-mono text-xs">Move up 5 spots per teammate invite:</span>
                    <Button variant="outline" size="sm" class="h-8 gap-1.5 font-mono text-xs" onclick={copyReferral}>
                      {#if copiedReferral}
                        <Check class="text-success size-3" />
                      {:else}
                        <Copy class="size-3" />
                      {/if}
                      <span>{copiedReferral ? 'Copied Link' : 'Copy Invite Link'}</span>
                    </Button>
                  </div>
                </div>
              {/if}
            </CardContent>
          </Card>
        </div>
    
        <!-- Interactive Feature Sneak-Peek Carousel & Terminal Preview -->
        <div class="space-y-6">
          <div class="flex flex-col justify-between gap-4 sm:flex-row sm:items-center">
            <div>
              <h2 class="text-foreground flex items-center gap-2 text-lg font-semibold tracking-tight">
                <Zap class="text-primary size-4" />
                Incoming Flagship Capabilities
              </h2>
              <p class="text-muted-foreground text-xs">Sneak peek preview of the upcoming architecture release</p>
            </div>
    
            <!-- Teaser Navigation Tabs -->
            <div class="bg-muted/40 border-border flex items-center gap-1.5 rounded-lg border p-1">
              {#each teasers as t, idx (t.id)}
                <button
                  type="button"
                  class={[
                    'rounded-md px-3 py-1 text-xs font-medium transition-colors',
                    activeTeaserIndex === idx
                      ? 'bg-background text-foreground font-semibold shadow-xs'
                      : 'text-muted-foreground hover:text-foreground',
                  ]}
                  onclick={() => (activeTeaserIndex = idx)}
                >
                  {t.badge}
                </button>
              {/each}
            </div>
          </div>
    
          <!-- Active Teaser Card -->
          <Card class="border-border bg-card overflow-hidden">
            <div class="divide-border grid grid-cols-1 divide-y lg:grid-cols-12 lg:divide-x lg:divide-y-0">
              <div class="space-y-4 p-6 sm:p-8 lg:col-span-7">
                <div class="flex items-center gap-2.5">
                  <div class="bg-primary/10 text-primary rounded-lg p-2">
                    <ActiveTeaserIcon class="size-5" />
                  </div>
                  <Badge variant="secondary" class="font-mono text-xs">
                    {activeTeaser.badge}
                  </Badge>
                </div>
    
                <h3 class="text-foreground text-xl font-bold tracking-tight">{activeTeaser.title}</h3>
                <p class="text-muted-foreground text-xs leading-relaxed sm:text-sm">
                  {activeTeaser.description}
                </p>
    
                <div class="flex items-center gap-6 pt-2">
                  <div>
                    <p class="text-muted-foreground font-mono text-xs">{activeTeaser.statLabel}</p>
                    <p class="text-foreground mt-0.5 font-mono text-xl font-bold">
                      {activeTeaser.statValue}
                    </p>
                  </div>
                  <Separator orientation="vertical" class="h-8" />
                  <div>
                    <p class="text-muted-foreground font-mono text-xs">Framework Support</p>
                    <p class="text-success mt-1 text-xs font-semibold">Svelte 5 · Vue 3.5 · React 19 Parity</p>
                  </div>
                </div>
              </div>
    
              <!-- Terminal Snippet Box -->
              <div class="bg-muted/20 flex flex-col justify-between space-y-4 p-6 lg:col-span-5">
                <div class="space-y-2">
                  <div class="flex items-center justify-between">
                    <span class="text-muted-foreground flex items-center gap-1.5 font-mono text-xs font-medium">
                      <Terminal class="size-3.5" /> Direct CLI Command
                    </span>
                    <Button
                      variant="ghost"
                      size="sm"
                      class="h-7 gap-1.5 px-2 font-mono text-xs"
                      onclick={() => copyTeaserSnippet(activeTeaser.codeSnippet)}
                    >
                      {#if copiedCli}
                        <Check class="text-success size-3" />
                      {:else}
                        <Copy class="size-3" />
                      {/if}
                      <span>{copiedCli ? 'Copied' : 'Copy'}</span>
                    </Button>
                  </div>
                  <div
                    class="bg-background border-border text-foreground selection:bg-primary/20 overflow-x-auto rounded-lg border p-3 font-mono text-xs"
                  >
                    <code>{activeTeaser.codeSnippet}</code>
                  </div>
                </div>
    
                <div
                  class="border-border/80 bg-background/50 text-muted-foreground flex items-center gap-2 rounded-lg border p-3 text-xs"
                >
                  <CheckCircle2 class="text-success size-3.5 shrink-0" />
                  <span>Transitive dependencies, OKLCH styles & TS types included.</span>
                </div>
              </div>
            </div>
          </Card>
        </div>
    
        <!-- Launch Readiness Milestones Tracker -->
        <div class="border-border/70 space-y-6 border-t pt-4">
          <div class="flex flex-col justify-between gap-4 sm:flex-row sm:items-center">
            <div>
              <h2 class="text-foreground flex items-center gap-2 text-lg font-semibold tracking-tight">
                <Activity class="text-primary size-4" />
                V2.0 Launch Milestones & Engineering Progress
              </h2>
              <p class="text-muted-foreground text-xs">Transparent real-time build and release status</p>
            </div>
            <div class="flex items-center gap-3">
              <span class="text-foreground font-mono text-xs font-semibold">Overall Readiness: {overallReadiness}%</span>
              <Progress value={overallReadiness} class="h-2 w-28" />
            </div>
          </div>
    
          <div class="grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3">
            {#each initialMilestones as m (m.id)}
              <div
                class="border-border bg-card hover:border-primary/30 flex flex-col justify-between space-y-3 rounded-xl border p-4 shadow-xs transition-colors"
              >
                <div class="flex items-start justify-between gap-2">
                  <Badge
                    variant="outline"
                    class={[
                      'px-2 py-0.5 font-mono text-xs',
                      m.status === 'completed' && 'border-success/20 bg-success/10 text-success',
                      m.status === 'in_progress' && 'border-warning/20 bg-warning/10 text-warning',
                      m.status === 'scheduled' && 'bg-muted text-muted-foreground border-border',
                    ]}
                  >
                    {m.status === 'completed' ? 'Completed' : m.status === 'in_progress' ? 'In Progress' : 'Scheduled'}
                  </Badge>
                  <span class="text-muted-foreground font-mono text-xs">{m.date}</span>
                </div>
    
                <div>
                  <p class="text-foreground text-xs leading-snug font-semibold">{m.title}</p>
                  <p class="text-muted-foreground mt-1 font-mono text-xs">{m.category}</p>
                </div>
    
                <div class="space-y-1 pt-1">
                  <div class="text-muted-foreground flex justify-between font-mono text-xs">
                    <span>Progress</span>
                    <span>{m.completionPercent}%</span>
                  </div>
                  <Progress value={m.completionPercent} class="h-1.5" />
                </div>
              </div>
            {/each}
          </div>
        </div>
      </div>
    
      <!-- Footer -->
      <footer
        class="border-border text-muted-foreground mx-auto flex w-full max-w-6xl flex-col items-center justify-between gap-4 border-t pt-8 text-xs sm:flex-row"
      >
        <div class="flex items-center gap-2">
          <span>&copy; {new Date().getFullYear()} UIPKGE. Open source under MIT License.</span>
        </div>
        <div class="flex items-center gap-4">
          <a
            href="https://github.com/uday-a/uipkge-registry"
            target="_blank"
            rel="noreferrer"
            class="hover:text-foreground transition-colors"
          >
            GitHub
          </a>
          <Separator orientation="vertical" class="h-3" />
          <a href="https://uipkge.dev" target="_blank" rel="noreferrer" class="hover:text-foreground transition-colors">
            Registry Docs
          </a>
          <Separator orientation="vertical" class="h-3" />
          <a href={statusUrl} target="_blank" rel="noreferrer" class="hover:text-foreground transition-colors">
            Status Page
          </a>
        </div>
      </footer>
    </section>
    

Raw manifest:https://uipkge.dev/r/svelte/coming-soon.json