Sproutline Pricing Pricing Block - Let's templates
Unlock every premium block and template with All-Access from $20 / 3 months, cancel anytime. Get All-Access
All blocks
Free Pricing

Sproutline Pricing

A pricing block extracted from the Sproutline template, available in Tailwind CSS and Bootstrap.

0 2
Sproutline Pricing preview
sproutline.html
<!DOCTYPE html>
<html lang="en">
<head>
  <script>
    window.FontAwesomeConfig = { autoReplaceSvg: 'nest' };
  </script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/js/all.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Sproutline Pricing | Tailwind CSS UI Block</title>
  <meta name="description" content="A pricing block extracted from the Sproutline template, available in Tailwind CSS and Bootstrap.">
  <meta name="keywords" content="Sproutline, Tailwind CSS template, HTML website template, agency template, web design agency, dark website template, subscription design studio, growth calculator, case study page, pricing page">
  <meta name="author" content="Let's templates">
  <link rel="canonical" href="">

  <meta property="og:type" content="product">
  <meta property="og:site_name" content="Let's templates">
  <meta property="og:locale" content="en_US">
  <meta property="og:url" content="">
  <meta property="og:title" content="Sproutline | Tailwind CSS Agency Template">
  <meta property="og:description" content="A dark, lime-accented Tailwind CSS agency template for web design studios, with a growth calculator, project hover list and case study pages.">
  <meta property="og:image" content="">
  <meta property="og:image:alt" content="Sproutline template preview">

  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:url" content="">
  <meta name="twitter:title" content="Sproutline | Tailwind CSS Agency Template">
  <meta name="twitter:description" content="A dark, lime-accented Tailwind CSS agency template for web design studios, with a growth calculator, project hover list and case study pages.">
  <meta name="twitter:image" content="">
  <meta name="twitter:image:alt" content="Sproutline template preview">
  <script src="https://cdn.tailwindcss.com/3.4.17"></script>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link href="https://fonts.googleapis.com/css2?family=DM+Serif+Display&family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: { night: '#060d1a', deep: '#0a1528', ocean: '#12306b', lime: { DEFAULT: '#a3e635', dark: '#84cc16' }, haze: '#c5d0e2' },
          fontFamily: { sans: ['"Plus Jakarta Sans"', 'sans-serif'], serif: ['"DM Serif Display"', 'serif'] }
        }
      }
    }
  </script>
  <style>
    @view-transition { navigation: auto; }
    ::view-transition-old(root) { animation: 180ms ease-out both page-fade-out; }
    ::view-transition-new(root) { animation: 220ms ease-in both page-fade-in; }
    @keyframes page-fade-out { to { opacity: 0; } }
    @keyframes page-fade-in { from { opacity: 0; } }
    html { scroll-behavior: smooth; }
    [hidden] { display: none !important; }
    body { background: radial-gradient(60rem 40rem at 0% 20%, rgba(29, 78, 216, .35), transparent 60%), radial-gradient(50rem 40rem at 100% 0%, rgba(29, 78, 216, .3), transparent 60%), #071226; }
    .frame-plain { background: #070f1e; }
    .frame-glow { background: radial-gradient(40rem 22rem at 50% 30%, rgba(37, 99, 235, .22), transparent 70%), #070f1e; }
    .marquee { animation: marquee 32s linear infinite; }
    .marquee:hover { animation-play-state: paused; }
    @keyframes marquee { to { transform: translateX(-50%); } }
    .fade-edges { mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); }
    .grow-bar { transition: width .6s ease; }
    .hover-image { transition: opacity .3s ease; }
    .reveal-ready [data-reveal] { opacity: 0; transform: translateY(24px); transition: opacity .6s ease, transform .6s ease; transition-delay: var(--reveal-delay, 0ms); }
    .reveal-ready [data-reveal].is-visible { opacity: 1; transform: none; }
    @media (prefers-reduced-motion: reduce) {
      html { scroll-behavior: auto; }
      .marquee { animation: none; }
      .grow-bar, .hover-image { transition: none; }
      ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
    }
  </style>
</head>
<body class="font-sans text-white antialiased">
<% active_page = "index" %>
<% nav = { "projects" => "Projects", "benefits" => "Benefits", "services" => "Services", "pricing" => "Pricing" } %>
<% nav.each do |slug, label| %>
<% active = active_page == slug %>
<% end %>
<% { "index" => "Home" }.merge(nav).merge("contact" => "Contact").each do |slug, label| %>
<% active = active_page == slug %>
<% end %>
<% 5.times do %>
<% end %>
<% logos = [["fa-circle-half-stroke", "Northwind"], ["fa-mountain", "Peakform"], ["fa-wave-square", "Signalry"], ["fa-cube", "Blockhaus"], ["fa-leaf", "Greenmark"], ["fa-star-of-life", "Asteria"], ["fa-infinity", "Loopwell"]] %>
<% (logos + logos).each_with_index do |(icon, name), index| %>
<% end %>
<% projects = [["lumen-coffee", "Lumen Coffee", "Ecommerce redesign", "+212% online orders", "1499951360447-b19be8fe80f5", "Clean desk with a laptop and monitor showing a website"], ["arcfield", "Arcfield Analytics", "SaaS marketing site", "3.1× demo requests", "1551288049-bebda4e38f71", "Analytics dashboard with charts on a dark screen"], ["paperkite", "Paperkite Studio", "Brand and portfolio", "Load time 4.8s → 0.9s", "1561070791-2526d30994b5", "Colour swatches and app screens on a tablet"], ["fieldnote", "Fieldnote Health", "Booking flow", "−38% drop-off at checkout", "1586717791821-3f44a563fa4c", "Hand sketching a wireframe on a tablet"]] %>
<% projects.each_with_index do |(slug, name, kind, result, photo, alt), index| %>
<% end %>
<% services = [["web", "Websites", "Marketing sites that load in under a second and are built to rank.", "1499951360447-b19be8fe80f5", "Desk with a laptop and monitor showing a website", ["Strategy & sitemap", "Design in Figma", "Build in your CMS"]], ["brand", "Brand", "Logos, type and colour systems that hold up from favicon to billboard.", "1561070791-2526d30994b5", "Colour swatches next to a tablet", ["Logo & mark", "Visual identity", "Brand guidelines"]], ["product", "Product UI", "Dashboards and app screens your users can figure out without a manual.", "1586717791821-3f44a563fa4c", "Wireframe sketched on a tablet", ["User flows", "Design system", "Prototype & tests"]], ["growth", "Growth", "Landing pages and A/B tests every sprint, tied to the metric you care about.", "1460925895917-afdab827c52f", "Laptop showing an analytics dashboard", ["Landing pages", "A/B testing", "Monthly report"]]] %>
<% services.each_with_index do |(id, title, text), index| %>
<% end %>
<% services.each_with_index do |(id, title, text, photo, alt, items), index| %>
<% items.each do |item| %>
<% end %>
<% end %>
<% steps = [["Kick-off call", "45 minutes on your goals, audience and the one number that matters.", "Day 1"], ["Strategy & wireframes", "Sitemap, messaging and grey-box layouts you can click through.", "Week 1"], ["Design", "Full designs in Figma with two rounds of feedback built in.", "Week 2–3"], ["Build & launch", "Coded, tested on every device and shipped on your domain.", "Week 4"], ["Grow", "Monthly tests and new pages while your plan is active.", "Ongoing"]] %>
<% steps.each_with_index do |(title, text, time), index| %>
<% end %>
<% steps.each_with_index do |(title, text, time), index| %>
<% end %>
<% [["240+", "sites launched"], ["48h", "average turnaround per request"], ["2.6×", "median conversion lift"], ["96%", "clients renewing after 3 months"]].each do |value, label| %>
<% end %>
<% results = [["+212%", "online orders in 90 days", "We'd outgrown our template. Sproutline rebuilt the shop in a month and orders tripled by spring.", "Ana Ribeiro", "Founder, Lumen Coffee", "1438761681033-6461ffad8d80"], ["3.1×", "demo requests", "The new site finally explains what we do. Sales calls start warmer and close faster.", "Marcus Hale", "CMO, Arcfield Analytics", "1519085360753-af0119f7cbe7"], ["−38%", "checkout drop-off", "They tested three booking flows and kept the one patients actually finished.", "Priya Nair", "Head of Product, Fieldnote", "1573496359142-b8d87734a5a2"]] %>
<% results.each_with_index do |(value, label, quote, name, role, photo), index| %>
<% end %>
<% included = ["Unlimited design requests", "One request at a time, 48h average", "Webflow or WordPress build", "Brand, web and product UI", "Weekly async updates", "Pause or cancel any time"] %>
<!-- block:start pricing -->
  <section class="px-5 md:px-10" data-billing>
    <div class="mx-auto grid max-w-7xl gap-6 lg:grid-cols-[1.4fr_1fr]">
      <div class="relative overflow-hidden rounded-[2.5rem] border-2 border-lime/60 bg-deep p-8 shadow-[0_0_60px_rgba(163,230,53,.12)] md:p-12">
        <div class="flex flex-wrap items-center justify-between gap-4">
          <p class="rounded-full bg-lime px-4 py-1.5 text-sm font-semibold text-night">One simple plan</p>
          <div class="flex rounded-full border border-white/15 p-1 text-sm font-semibold" role="group" aria-label="Billing period">
            <button type="button" data-billing-option="monthly" aria-pressed="true" class="rounded-full px-4 py-2 aria-pressed:bg-white aria-pressed:text-night">Monthly</button>
            <button type="button" data-billing-option="quarterly" aria-pressed="false" class="rounded-full px-4 py-2 aria-pressed:bg-white aria-pressed:text-night">Quarterly −10%</button>
          </div>
        </div>
        <p class="mt-8 flex items-end gap-2"><span class="text-6xl font-semibold tracking-tight md:text-7xl" data-price data-monthly="$4,950" data-quarterly="$4,450">$4,950</span><span class="pb-2 text-haze">/ month</span></p>
        <ul class="mt-8 grid gap-3 sm:grid-cols-2">
          <% included.each do |item| %><li class="flex items-center gap-3"><i class="fa-solid fa-circle-check text-lime" aria-hidden="true"></i><%= item %></li><% end %>
        </ul>
        <div class="mt-10 flex flex-wrap gap-4">
          <a href="contact.html" class="rounded-xl bg-lime px-7 py-4 font-semibold text-night transition hover:bg-lime-dark">Start this month</a>
          <a href="pricing.html" class="rounded-xl border-2 border-white/20 px-7 py-4 font-semibold transition hover:border-white/50">Compare options</a>
        </div>
      </div>
      <div class="flex flex-col rounded-[2.5rem] border border-white/10 bg-deep/60 p-8 md:p-10">
        <p class="font-semibold text-haze">Just need one thing?</p>
        <h3 class="mt-2 font-serif text-3xl">Single landing page</h3>
        <p class="mt-4 text-4xl font-semibold">$3,200 <span class="text-base font-normal text-haze">one-off</span></p>
        <p class="mt-4 text-haze">Strategy, design and build of one high-converting page, live in ten days.</p>
        <a href="contact.html" class="mt-auto inline-flex items-center gap-2 pt-8 font-semibold text-lime hover:underline">Ask about a sprint <i class="fa-solid fa-arrow-right" aria-hidden="true"></i></a>
      </div>
    </div>
  </section>
  <!-- block:end pricing -->
<script>
    const reducedMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;
    const watchMotion = !reducedMotion && !navigator.webdriver && 'IntersectionObserver' in window;

    document.querySelectorAll('[data-menu-toggle]').forEach((button) => {
      const menu = document.getElementById(button.getAttribute('aria-controls'));
      button.addEventListener('click', () => {
        const open = button.getAttribute('aria-expanded') === 'true';
        button.setAttribute('aria-expanded', String(!open));
        menu.classList.toggle('hidden', open);
      });
    });

    document.querySelectorAll('[data-hover-list]').forEach((root) => {
      const image = root.querySelector('[data-hover-image]');
      root.querySelectorAll('[data-hover-row]').forEach((row) => {
        row.addEventListener('mouseenter', () => { image.src = row.dataset.image; image.alt = row.dataset.alt; image.style.opacity = '1'; });
        row.addEventListener('mousemove', (event) => { image.style.transform = `translate(${event.clientX + 24}px, ${event.clientY - 110}px) rotate(-3deg)`; });
        row.addEventListener('mouseleave', () => { image.style.opacity = '0'; });
      });
    });

    document.querySelectorAll('[data-growth]').forEach((root) => {
      const oldRate = Number(root.dataset.oldRate) / 100;
      const newRate = Number(root.dataset.newRate) / 100;
      const money = (value) => `$${Math.round(value).toLocaleString('en-US')}`;
      const paint = () => {
        const visitors = Number(root.querySelector('[data-visitors]').value);
        const value = Number(root.querySelector('[data-value]').value);
        const before = visitors * oldRate * value;
        const after = visitors * newRate * value;
        root.querySelector('[data-visitors-label]').textContent = visitors.toLocaleString('en-US');
        root.querySelector('[data-value-label]').textContent = money(value);
        root.querySelector('[data-old-revenue]').textContent = money(before);
        root.querySelector('[data-new-revenue]').textContent = money(after);
        root.querySelector('[data-old-bar]').style.width = `${(before / after) * 100}%`;
        root.querySelector('[data-extra]').textContent = `+${money(after - before)}`;
        const days = Math.max(1, Math.ceil(4950 / ((after - before) / 30)));
        root.querySelector('[data-payback]').textContent = days > 90 ? 'about 3 months' : `${days} day${days === 1 ? '' : 's'}`;
      };
      root.addEventListener('input', paint);
      paint();
    });

    document.querySelectorAll('[data-tabs], [data-stepper]').forEach((root) => {
      const tabs = [...root.querySelectorAll('[role="tab"]')];
      const fill = root.querySelector('[data-step-fill]');
      const select = (tab) => {
        tabs.forEach((other) => { const on = other === tab; other.setAttribute('aria-selected', String(on)); other.tabIndex = on ? 0 : -1; document.getElementById(other.getAttribute('aria-controls')).hidden = !on; });
        if (fill) fill.style.width = `${((tabs.indexOf(tab) + 1) / tabs.length) * 100}%`;
      };
      tabs.forEach((tab, index) => {
        tab.addEventListener('click', () => select(tab));
        tab.addEventListener('keydown', (event) => {
          const move = { ArrowRight: 1, ArrowDown: 1, ArrowLeft: -1, ArrowUp: -1 }[event.key];
          if (!move) return;
          event.preventDefault();
          const next = tabs[(index + move + tabs.length) % tabs.length];
          select(next); next.focus();
        });
      });
    });

    document.querySelectorAll('[data-billing]').forEach((root) => {
      const price = root.querySelector('[data-price]');
      root.querySelectorAll('[data-billing-option]').forEach((option) => option.addEventListener('click', () => {
        root.querySelectorAll('[data-billing-option]').forEach((other) => other.setAttribute('aria-pressed', String(other === option)));
        price.textContent = price.dataset[option.dataset.billingOption];
      }));
    });

    document.querySelectorAll('[data-project-browser]').forEach((root) => {
      const list = root.querySelector('[data-project-list]');
      const items = [...list.children];
      const search = root.querySelector('[data-project-search]');
      const sort = root.querySelector('[data-project-sort]');
      const count = root.querySelector('[data-project-count]');
      const apply = () => {
        const query = String(search.value || '').trim().toLowerCase();
        const sorted = [...items].sort((a, b) => sort.value === 'lift' ? b.dataset.lift - a.dataset.lift : sort.value === 'az' ? a.dataset.name.localeCompare(b.dataset.name) : b.dataset.year - a.dataset.year);
        let shown = 0;
        sorted.forEach((item) => { const match = !query || item.textContent.toLowerCase().includes(query); item.hidden = !match; if (match) shown += 1; list.append(item); });
        count.textContent = shown;
        root.querySelector('[data-project-empty]').hidden = shown > 0;
      };
      search.addEventListener('input', apply);
      sort.addEventListener('change', apply);
      apply();
    });

    document.querySelectorAll('[data-faq-search]').forEach((root) => {
      const input = root.querySelector('[data-faq-query]');
      const items = [...root.querySelectorAll('[data-faq-item]')];
      input.addEventListener('input', () => {
        const query = String(input.value || '').trim().toLowerCase();
        let shown = 0;
        items.forEach((item) => { const match = !query || item.textContent.toLowerCase().includes(query); item.hidden = !match; if (match) shown += 1; });
        root.querySelector('[data-faq-empty]').hidden = shown > 0;
      });
    });

    document.querySelectorAll('[data-chip-form]').forEach((form) => {
      form.querySelectorAll('[data-chip]').forEach((chip) => chip.addEventListener('click', () => {
        const single = chip.closest('[data-single]');
        if (single) single.querySelectorAll('[data-chip]').forEach((other) => other.setAttribute('aria-pressed', String(other === chip)));
        else chip.setAttribute('aria-pressed', String(chip.getAttribute('aria-pressed') !== 'true'));
        form.querySelector('[data-chip-summary]').textContent = [...form.querySelectorAll('[data-chip][aria-pressed="true"]')].map((c) => c.dataset.chip).join(' · ') || 'Nothing picked yet';
      }));
      form.addEventListener('submit', (event) => {
        event.preventDefault();
        const status = form.querySelector('[data-form-status]');
        const picked = form.querySelectorAll('[data-chip][aria-pressed="true"]').length;
        if (!picked || !form.checkValidity()) { status.textContent = form.dataset.error; return; }
        status.textContent = form.dataset.success;
      });
    });

    document.querySelectorAll('[data-contact-form]').forEach((form) => {
      form.addEventListener('submit', (event) => {
        event.preventDefault();
        const status = form.querySelector('[data-form-status]');
        if (!form.checkValidity()) {
          status.textContent = form.dataset.error;
          form.querySelector(':invalid')?.focus();
          return;
        }
        status.textContent = form.dataset.success;
        form.reset();
      });
    });

    document.querySelectorAll('[data-current-year]').forEach((el) => { el.textContent = new Date().getFullYear(); });

    (() => {
      const items = document.querySelectorAll('[data-reveal]');
      if (!items.length || !watchMotion) return;
      document.documentElement.classList.add('reveal-ready');
      const observer = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
          if (!entry.isIntersecting) return;
          entry.target.classList.add('is-visible');
          observer.unobserve(entry.target);
        });
      }, { rootMargin: '0px 0px -10% 0px' });
      items.forEach((item) => observer.observe(item));
    })();
  </script>
</body>
</html>

From this template

Sproutline screenshot

Agency

Sproutline

Unlimited access to all products

Unlock the entire library of premium templates and blocks. Renews automatically, cancel anytime.

$20 / 3 months or $60 / year
Get Unlimited Access