Tenace 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

Tenace Pricing

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

0 3
Tenace Pricing preview
tenace.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>Tenace Pricing | Tailwind CSS UI Block</title>
  <meta name="description" content="A pricing block extracted from the Tenace template, available in Tailwind CSS and Bootstrap.">
  <meta name="keywords" content="Tenace, Tailwind CSS template, HTML website template, education template, online course template, bridge school, card game lessons, e-learning platform, online academy">
  <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="Tenace | Tailwind CSS Education Template">
  <meta property="og:description" content="A bold, geometric Tailwind CSS education template for online bridge schools, with an interactive bidding quiz, a course spotlight and a weekly lesson calendar.">
  <meta property="og:image" content="">
  <meta property="og:image:alt" content="Tenace template preview">

  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:url" content="">
  <meta name="twitter:title" content="Tenace | Tailwind CSS Education Template">
  <meta name="twitter:description" content="A bold, geometric Tailwind CSS education template for online bridge schools, with an interactive bidding quiz, a course spotlight and a weekly lesson calendar.">
  <meta name="twitter:image" content="">
  <meta name="twitter:image:alt" content="Tenace 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=Inter:wght@300;400;500;600&family=Unbounded:wght@600;800&display=swap" rel="stylesheet">
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: { indigo: { DEFAULT: '#2f2fa2', deep: '#23238a', soft: '#6b5bd2' }, sun: '#fbbf3c', petal: '#f9b4c0', blush: '#f6e9e8', ink: '#141414', heart: '#d6324f' },
          fontFamily: { sans: ['Inter', 'sans-serif'], display: ['Unbounded', 'sans-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; }
    .marquee { display: flex; overflow: hidden; gap: 3rem; }
    .marquee-track { display: flex; flex-shrink: 0; align-items: center; gap: 3rem; animation: marquee 30s linear infinite; }
    .marquee:hover .marquee-track { animation-play-state: paused; }
    @keyframes marquee { to { transform: translateX(calc(-100% - 3rem)); } }
    .ring-progress { transition: stroke-dashoffset 1.2s cubic-bezier(.2,.8,.2,1); }
    .reveal-ready [data-ring] .ring-progress { stroke-dashoffset: 100; }
    .reveal-ready [data-ring].is-visible .ring-progress { stroke-dashoffset: var(--ring-offset); }
    .reveal-ready [data-reveal], .reveal-ready [data-tile] { opacity: 0; transform: translateY(24px); transition: opacity .6s ease, transform .6s ease; transition-delay: var(--reveal-delay, 0ms); }
    .reveal-ready [data-tile] { transform: scale(.85); }
    .reveal-ready [data-reveal].is-visible, .reveal-ready [data-tile].is-visible { opacity: 1; transform: none; }
    @media (prefers-reduced-motion: reduce) {
      html { scroll-behavior: auto; }
      .marquee-track { animation: none; }
      .marquee { overflow-x: auto; }
      ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
    }
  </style>
</head>
<body class="bg-blush font-sans text-ink antialiased">
<% active_page = "index" %>
<% { "contacts" => "Contacts", "pricing" => "Choose a plan", "about" => "About us", "courses" => "Courses" }.each do |slug, label| %>
<% active = active_page == slug %>
<% end %>
<% { "index" => "Home", "courses" => "Courses", "pricing" => "Choose a plan", "about" => "About us", "contacts" => "Contacts", "login" => "Log in" }.each do |slug, label| %>
<% active = active_page == slug %>
<% end %>
<% tiles = [
    [:photo, "bg-sun", "rounded-full", "1438761681033-6461ffad8d80", "Young woman with auburn hair by a lake"],
    [:shape, "bg-indigo-soft", "rounded-tl-full rounded-br-full"],
    [:suit, "bg-indigo", "♥", "text-sun"],
    [:photo, "bg-petal", "rounded-t-full", "1507003211169-0a1dd7228f2d", "Smiling man with a beard"],
    [:shape, "bg-indigo-soft", "rounded-br-full"],
    [:shape, "bg-sun", "rounded-tr-full rounded-bl-full"],
    [:shape, "bg-indigo-soft", "rounded-full"],
    [:shape, "bg-indigo-soft", "rounded-tl-full"],
    [:shape, "bg-[#4b3fc4]", "rounded-b-full"],
    [:brand, "bg-petal", "rounded-t-full"],
    [:shape, "bg-indigo-soft", "rounded-tr-full"],
    [:suit, "bg-indigo", "♦", "text-petal"],
    [:photo, "bg-petal", "rounded-full", "1500648767791-00dcc994a43e", "Man in a grey sweater smiling"],
    [:shape, "bg-indigo-soft", "rounded-bl-full"],
    [:photo, "bg-sun", "rounded-t-full", "1573496359142-b8d87734a5a2", "Woman in a grey blazer smiling"],
    [:shape, "bg-petal", "rounded-tl-full"],
    [:shape, "bg-indigo-soft", "rounded-t-full"],
    [:suit, "bg-indigo", "♣", "text-indigo-soft"],
    [:shape, "bg-indigo-soft", "rounded-t-full"],
    [:shape, "bg-petal", "rounded-t-full"]
  ] %>
<% [["fa-whatsapp", "WhatsApp", "https://www.whatsapp.com"], ["fa-facebook-f", "Facebook", "https://www.facebook.com"], ["fa-twitter", "Twitter", "https://twitter.com"]].each do |icon, label, url| %>
<% end %>
<% tiles.each_with_index do |(kind, bg, *rest), index| %>
<% case kind %>
<% when :photo %>
<% when :suit %>
<% when :brand %>
<% else %>
<% end %>
<% end %>
<% hands = [
    { cards: [["K", "♠"], ["Q", "♠"], ["5", "♠"], ["A", "♥"], ["J", "♥"], ["9", "♥"], ["8", "♥"], ["4", "♥"], ["K", "♦"], ["6", "♦"], ["7", "♣"], ["3", "♣"], ["2", "♣"]], answer: "1♥", points: 13, why: "13 points and five hearts: open your longest suit. Five-card majors come first." },
    { cards: [["A", "♠"], ["Q", "♠"], ["4", "♠"], ["K", "♥"], ["10", "♥"], ["3", "♥"], ["Q", "♦"], ["J", "♦"], ["8", "♦"], ["2", "♦"], ["K", "♣"], ["9", "♣"], ["5", "♣"]], answer: "1NT", points: 15, why: "15 points and a balanced shape with no five-card major: that's a textbook 1NT." },
    { cards: [["J", "♠"], ["8", "♠"], ["6", "♠"], ["3", "♠"], ["Q", "♥"], ["7", "♥"], ["2", "♥"], ["K", "♦"], ["9", "♦"], ["4", "♦"], ["J", "♣"], ["10", "♣"], ["5", "♣"]], answer: "Pass", points: 7, why: "Only 7 points. Opening needs about 12, so pass and let partner speak." }
  ] %>
<% hands.each_with_index do |hand, index| %>
<% hand[:cards].each_with_index do |(rank, suit), card_index| %>
<% end %>
<% ["1♥", "1NT", "Pass"].each do |bid| %>
<% end %>
<% end %>
<% [["learn", "♠", "Learn", "Bite-size video lessons with a teacher who explains the why, not just the rule.", "bg-sun"], ["practise", "♥", "Practise", "Thousands of real deals with hints when you're stuck and replays when you're done.", "bg-petal"], ["play", "♦", "Play live", "Weekly small-group sessions and friendly online club nights.", "bg-indigo-soft text-white"], ["track", "♣", "Track progress", "Skill maps show what you've mastered and what to practise next.", "bg-sun"]].each_with_index do |(id, suit, title, text, tone), index| %>
<% end %>
<% [["learn", "1543269664-56d93c1b41a6", "Smiling woman following a lesson on her tablet"], ["practise", "1541278107931-e006523892df", "Playing cards spread across a table"], ["play", "1511193311914-0346f16efe90", "Hand laying down cards on a green table"], ["track", "1522202176988-66273c2fd55f", "Students reviewing progress together on laptops"]].each_with_index do |(id, photo, alt), index| %>
<% end %>
<% courses = [
    ["Bidding Basics", "Beginner", "12 lessons · 4 weeks", "Count your points, open the bidding and find the right contract with your partner.", "1541278107931-e006523892df", "Playing cards spread across a table", "bg-sun", "bidding-basics.html"],
    ["Defence That Wins", "Intermediate", "10 lessons · 4 weeks", "Opening leads, signals and counting: the skills that turn good players into partners people want.", "1511193311914-0346f16efe90", "Hand laying down cards on a green table", "bg-petal", "courses.html"],
    ["Slam Bidding", "Intermediate", "9 lessons · 3 weeks", "Cue bids, key cards and the confidence to bid the big ones.", "1517245386807-bb43f82c33c4", "Two players discussing a hand at a laptop", "bg-indigo-soft text-white", "courses.html"],
    ["Squeezes & Endplays", "Advanced", "14 lessons · 6 weeks", "Make the defenders do your work for you in the final tricks.", "1576267423048-15c0040fec78", "Team celebrating a win around a table", "bg-sun", "courses.html"]
  ] %>
<% courses.each_with_index do |(title, level, meta, text, photo, alt, tone, href), index| %>
<% end %>
<% courses.each_with_index do |(title, level, meta, text, photo, alt), index| %>
<% end %>
<% week = [["Mon", 14], ["Tue", 15], ["Wed", 16], ["Thu", 17], ["Fri", 18], ["Sat", 19], ["Sun", 20]] %>
<% sessions = { "Mon" => [["18:00", "Opening leads that set traps", "bg-sun"]], "Wed" => [["12:30", "Lunch-break practice", "bg-petal"], ["19:30", "Counting the hand", "bg-indigo-soft text-white"]], "Thu" => [["18:00", "Ask the teacher", "bg-petal"]], "Fri" => [["18:00", "Defending no-trump", "bg-indigo-soft text-white"]], "Sun" => [["11:00", "Club night: duplicate", "bg-sun"], ["17:00", "Slam clinic", "bg-petal"]] } %>
<% week.each do |day, date| %>
<% (sessions[day] || []).each do |time, title, tone| %>
<% end %>
<% if sessions[day].nil? %>
<% end %>
<% end %>
<% [[92, "92%", "pass their first level test", "#fbbf3c"], [78, "78%", "play at least weekly", "#f9b4c0"], [98, "4.9", "average lesson rating", "#ffffff"]].each_with_index do |(percent, label, text, color), index| %>
<% end %>
<% reviews = [["I'd watched my parents play for years. Three months in, I'm the one explaining squeezes at family dinners.", "Clara Jensen", "Player plan · learning since 2025", 1, "bg-sun"], ["The instant feedback is the magic. I finally understand why I lose tricks, not just that I lose them.", "Omar Haddad", "Player plan · intermediate", 3, "bg-petal"], ["Our club moved its beginner nights online with Tenace and membership doubled in a year.", "Helen Price", "Club organiser, Bath", 5, "bg-indigo-soft"], ["Live lessons are small enough that the teacher knows your name, and your bad habits.", "Ravi Mehta", "Club plan · advanced", 8, "bg-sun"]] %>
<% reviews.each_with_index do |(quote, name, role), index| %>
<% end %>
<% reviews.each_with_index do |(quote, name, role, avatar, tone), index| %>
<% end %>
<!-- block:start pricing -->
  <section id="plans" class="bg-white">
    <div class="mx-auto grid max-w-7xl gap-6 px-5 py-20 md:px-12 md:py-28 lg:grid-cols-[1fr_1.6fr]">
      <div class="flex flex-col rounded-[2rem] bg-blush p-8">
        <h2 class="font-display text-xl font-extrabold uppercase">Free</h2>
        <p class="mt-2 font-light text-ink/70">Learn the rules and play your first hands.</p>
        <p class="mt-8 font-display text-5xl font-extrabold">$0</p>
        <ul class="mt-8 grid flex-1 content-start gap-3 text-sm">
          <% ["3 beginner courses", "50 practice deals", "Community forum"].each do |feature| %><li class="flex items-center gap-3"><i class="fa-solid fa-check text-indigo" aria-hidden="true"></i><%= feature %></li><% end %>
        </ul>
        <a href="login.html" class="mt-10 rounded-md border-2 border-indigo px-6 py-3.5 text-center text-sm font-semibold uppercase text-indigo transition hover:bg-indigo hover:text-white">Start free</a>
      </div>
      <div class="relative overflow-hidden rounded-[2rem] bg-indigo p-8 text-white md:p-12">
        <div class="absolute -right-10 -top-10 grid grid-cols-2" aria-hidden="true"><span class="h-24 w-24 rounded-tl-full bg-sun"></span><span class="h-24 w-24 rounded-full bg-petal"></span><span class="h-24 w-24 rounded-br-full bg-indigo-soft"></span><span class="h-24 w-24 rounded-t-full bg-sun"></span></div>
        <div class="relative max-w-md">
          <span class="rounded-md bg-sun px-3 py-1 text-xs font-semibold uppercase text-ink">Most players choose this</span>
          <h2 class="mt-6 font-display text-3xl font-extrabold uppercase">Player</h2>
          <p class="mt-2 font-light text-white/80">Everything you need to improve every single week.</p>
          <p class="mt-8 flex items-baseline gap-2"><span class="font-display text-6xl font-extrabold">$12</span><span class="text-white/70">/ month · or $120 a year</span></p>
          <ul class="mt-8 grid gap-3 sm:grid-cols-2">
            <% ["All courses", "Unlimited practice deals", "Weekly live lesson", "Progress reports", "Teacher Q&A", "Offline hands"].each do |feature| %><li class="flex items-center gap-3"><i class="fa-solid fa-check text-sun" aria-hidden="true"></i><%= feature %></li><% end %>
          </ul>
          <a href="login.html" class="mt-10 inline-flex items-center rounded-md bg-sun px-10 py-4 text-sm font-semibold uppercase text-ink transition hover:bg-white">Choose Player</a>
          <p class="mt-4 text-sm text-white/70">Running a club? <a href="pricing.html" class="font-semibold text-white underline underline-offset-4">Compare all plans</a></p>
        </div>
      </div>
    </div>
  </section>
  <!-- block:end pricing -->
<script>
    document.querySelectorAll('[data-menu-toggle]').forEach((button) => {
      const menu = document.getElementById(button.getAttribute('aria-controls'));
      if (!menu) return;
      button.addEventListener('click', () => {
        const open = button.getAttribute('aria-expanded') === 'true';
        button.setAttribute('aria-expanded', String(!open));
        menu.classList.toggle('hidden', open);
      });
    });

    document.querySelectorAll('[data-quiz]').forEach((quiz) => {
      const hands = [...quiz.querySelectorAll('[data-quiz-hand]')];
      let current = 0;
      let score = 0;
      hands.forEach((hand) => {
        const feedback = hand.querySelector('[data-quiz-feedback]');
        const verdict = hand.querySelector('[data-quiz-verdict]');
        const answer = verdict.textContent;
        feedback.hidden = true;
        hand.querySelectorAll('[data-quiz-option]').forEach((option) => {
          option.addEventListener('click', () => {
            if (!feedback.hidden) return;
            const right = option.dataset.correct === 'true';
            option.setAttribute('aria-pressed', 'true');
            if (right) score += 1;
            verdict.textContent = right ? `Spot on: ${option.textContent.trim()} is right.` : `Not quite. ${answer}`;
            feedback.hidden = false;
            quiz.querySelector('[data-quiz-score]').textContent = score;
          });
        });
        hand.querySelector('[data-quiz-next]')?.addEventListener('click', () => {
          hand.hidden = true;
          current = (current + 1) % hands.length;
          if (current === 0) { score = 0; quiz.querySelector('[data-quiz-score]').textContent = 0; }
          const next = hands[current];
          next.hidden = false;
          next.querySelector('[data-quiz-feedback]').hidden = true;
          next.querySelectorAll('[data-quiz-option]').forEach((option) => option.removeAttribute('aria-pressed'));
          quiz.querySelector('[data-quiz-index]').textContent = current + 1;
          next.querySelector('[data-quiz-option]')?.focus();
        });
      });
    });

    document.querySelectorAll('[data-tabs]').forEach((tablist) => {
      const tabs = [...tablist.querySelectorAll('[role="tab"]')];
      const select = (tab) => tabs.forEach((other) => {
        const active = other === tab;
        other.setAttribute('aria-selected', String(active));
        other.tabIndex = active ? 0 : -1;
        document.getElementById(other.getAttribute('aria-controls')).hidden = !active;
      });
      tabs.forEach((tab, index) => {
        tab.addEventListener('click', () => select(tab));
        tab.addEventListener('keydown', (event) => {
          const step = { ArrowRight: 1, ArrowDown: 1, ArrowLeft: -1, ArrowUp: -1 }[event.key];
          if (!step) return;
          event.preventDefault();
          const next = tabs[(index + step + tabs.length) % tabs.length];
          next.focus();
          select(next);
        });
      });
    });

    document.querySelectorAll('[data-switcher]').forEach((root) => {
      root.addEventListener('click', (event) => {
        const button = event.target.closest('[data-switch]');
        if (!button) return;
        root.querySelectorAll('[data-switch]').forEach((other) => other.setAttribute('aria-selected', String(other === button)));
        root.querySelectorAll('[data-switch-panel]').forEach((panel) => { panel.hidden = panel.dataset.switchPanel !== button.dataset.switch; });
      });
    });

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

    document.querySelectorAll('[data-course-tools]').forEach((tools) => {
      const grid = document.querySelector(tools.dataset.courseTools);
      const search = tools.querySelector('[data-course-search]');
      const sort = tools.querySelector('[data-course-sort]');
      const count = tools.querySelector('[data-course-count]');
      const apply = () => {
        const query = search.value.trim().toLowerCase();
        const items = [...grid.querySelectorAll('[data-course]')];
        items.sort((a, b) => Number(a.dataset[sort.value]) - Number(b.dataset[sort.value])).forEach((item) => grid.append(item));
        let shown = 0;
        items.forEach((item) => {
          const match = !query || item.textContent.toLowerCase().includes(query);
          item.hidden = !match;
          if (match) shown += 1;
        });
        count.textContent = shown;
      };
      search.addEventListener('input', apply);
      sort.addEventListener('change', apply);
    });

    document.querySelectorAll('[data-booking]').forEach((form) => {
      const summary = form.querySelector('[data-booking-summary]');
      const update = () => {
        const day = [...form.querySelectorAll('[name="day"]')].find((input) => input.checked);
        const time = [...form.querySelectorAll('[name="time"]')].find((input) => input.checked);
        summary.textContent = day && time ? `${day.value} at ${time.value}` : 'Pick a day and a time';
      };
      form.addEventListener('change', update);
      update();
    });

    document.querySelectorAll('[data-contact-form], [data-booking]').forEach((form) => {
      form.addEventListener('submit', (event) => {
        event.preventDefault();
        const status = form.querySelector('[data-form-status]');
        const groups = [...form.querySelectorAll('[data-required-group]')].every((group) => [...group.querySelectorAll('[name]')].some((choice) => choice.checked));
        if (!groups || !form.checkValidity()) {
          status.textContent = form.dataset.error;
          return;
        }
        status.textContent = form.dataset.success;
        form.reset();
        form.dispatchEvent(new Event('change'));
      });
    });

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

    (() => {
      const items = document.querySelectorAll('[data-reveal], [data-tile]');
      const skip = navigator.webdriver || !('IntersectionObserver' in window) || matchMedia('(prefers-reduced-motion: reduce)').matches;
      if (!items.length || skip) 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

Tenace screenshot

Education

Tenace

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