VibeCoderzVibeCoderz
Telegram
All Prompts
Testimonial Slider with Tailwind and Chart.js preview
testimonialslidercarouseltailwindresponsiveinteractivechartjs

Testimonial Slider with Tailwind and Chart.js

Адаптивный слайдер отзывов с Tailwind CSS и Chart.js. Автоматическая ротация, аватары, навигация. Демонстрирует метрики.

Prompt

<section class="sm:px-8 sm:mt-32 [animation:fadeSlideIn_0.8s_ease-out_0.1s_both] animate-on-scroll max-w-7xl mt-32 mr-auto ml-auto pr-6 pl-6">
  <section class="overflow-hidden sm:mt-32 sm:pl-8 sm:pr-8 sm:pt-8 sm:pb-8 bg-gradient-to-br from-gray-500/10 via-gray-500/0 to-gray-500/10 max-w-7xl rounded-3xl ring-0 mt-24 pt-6 pr-6 pb-6 pl-6 relative" style="position: relative; --border-gradient: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0)); --border-radius-before: 24px">
  <!-- subtle frame glow -->
  <span aria-hidden="true" class="pointer-events-none absolute inset-0 rounded-3xl ring-1 ring-white/5"></span>

  <div class="grid grid-cols-1 md:grid-cols-2 md:gap-16 gap-8 gap-x-8 gap-y-8">
    <!-- Left: Intro -->
    <div class="">
      <span class="inline-flex items-center gap-1 uppercase text-xs font-medium text-emerald-400 tracking-tight bg-emerald-950 ring-emerald-400/20 ring-1 rounded-full pt-1 pr-3 pb-1 pl-3">Testimonials</span>

      <h2 class="sm:text-5xl lg:text-6xl text-4xl font-light text-white tracking-tight font-geist mt-6">
        Loved by teams who take budgets seriously
      </h2>

      <p class="mt-6 text-base sm:text-lg dark:text-neutral-400">
        See how Moneo helps people cut waste, automate savings, and stay on plan with AI-driven insights.
      </p>

      <!-- Controls -->
      <div class="flex gap-3 mt-8 gap-x-3 gap-y-3 items-center">
        <button aria-label="Previous testimonial" class="inline-flex border-neutral-700 hover:bg-neutral-800 transition bg-gradient-to-br w-11 h-11 rounded-full items-center justify-center from-white/10 to-white/0" style="position: relative; --border-gradient: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0)); --border-radius-before: 9999px" id="t-prev">
          <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="m12 19-7-7 7-7" class=""></path><path d="M19 12H5" class=""></path></svg>
        </button>
        <button aria-label="Next testimonial" class="inline-flex border-neutral-700 hover:bg-neutral-800 transition bg-gradient-to-br w-11 h-11 rounded-full items-center justify-center from-white/10 to-white/0" id="t-next" style="position: relative; --border-gradient: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0)); --border-radius-before: 9999px">
          <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14" class=""></path><path d="m12 5 7 7-7 7" class=""></path></svg>
        </button>
      </div>
    </div>

    <!-- Right: Testimonial Card -->
    <div class="md:pl-4">
      <figure class="sm:p-8 bg-gradient-to-br rounded-2xl ring-0 px-6 py-6 relative shadow-[inset_0_1px_0_rgba(255,255,255,0.06),0_20px_60px_rgba(0,0,0,0.35)] backdrop-blur from-white/10 to-white/0" style="position: relative; --border-gradient: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0)); --border-radius-before: 16px">
        <!-- quote icon -->
        <svg xmlns="http://www.w3.org/2000/svg" class="w-[34px] h-[34px] mb-4" viewBox="0 0 24 24" fill="currentColor" stroke-width="2" data-icon-replaced="true" style="width: 34px; height: 34px; color: rgb(52, 211, 153)">
          <path d="M7.17 6.18C5.2 7.62 4 9.76 4 12.1c0 3.4 2.38 5.9 5.6 5.9 2.1 0 3.4-1.05 3.4-2.63 0-1.36-1.02-2.36-2.44-2.36-1 0-1.76.45-2.18 1.24.06-2.06 1.36-3.76 3.4-4.54V6c-1.3.05-2.92.4-4.65 1.18Zm10 0C15.2 7.62 14 9.76 14 12.1c0 3.4 2.38 5.9 5.6 5.9 2.1 0 3.4-1.05 3.4-2.63 0-1.36-1.02-2.36-2.44-2.36-1 0-1.76.45-2.18 1.24.06-2.06 1.36-3.76 3.4-4.54V6c-1.3.05-2.92.4-4.65 1.18Z" class=""></path>
        </svg>

        <blockquote id="t-quote" class="text-2xl sm:text-3xl lg:text-4xl leading-tight font-light tracking-tight text-white" style="opacity: 1;">“The AI flagged duplicate subscriptions and saved our team over $600 in the first month.”</blockquote>

        <figcaption class="mt-6 flex items-center gap-3">
          <img alt="Avatar" class="w-10 h-10 object-cover rounded-full ring-1 ring-neutral-800" src="https://hoirqrkdgbmvpwutwuwj.supabase.co/storage/v1/object/public/assets/assets/4734259a-bad7-422f-981e-ce01e79184f2_1600w.jpg" style="opacity: 1" id="t-avatar">
          <div class="">
            <div id="t-name" class="text-base font-semibold tracking-tight text-white" style="opacity: 1;">Marcus Hill</div>
            <div id="t-role" class="text-sm text-neutral-400" style="opacity: 1;">Operations Lead, Toronto</div>
          </div>
        </figcaption>
      </figure>
    </div>
  </div>

  <!-- Slider Script -->
  <script>
    (() => {
      const items = [
        {
          quote: "Moneo made budgeting feel effortless. I went from guessing my savings to watching them grow automatically.",
          name: "Sophie Tran",
          role: "Freelance Designer, Montreal",
          avatar: "https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?q=80&w=128&auto=format&fit=crop&ixlib=rb-4.0.3"
        },
        {
          quote: "The AI flagged duplicate subscriptions and saved our team over $600 in the first month.",
          name: "Marcus Hill",
          role: "Operations Lead, Toronto",
          avatar: "https://images.unsplash.com/photo-1607746882042-944635dfe10e?q=80&w=128&auto=format&fit=crop&ixlib=rb-4.0.3"
        },
        {
          quote: "Clear cash-flow forecasts and weekly nudges keep me on track without thinking about it.",
          name: "Ana Morales",
          role: "Founder, Café Nube",
          avatar: "https://images.unsplash.com/photo-1552374196-c4e7ffc6e126?q=80&w=128&auto=format&fit=crop&ixlib=rb-4.0.3"
        }
      ];

      const q = document.getElementById('t-quote');
      const name = document.getElementById('t-name');
      const role = document.getElementById('t-role');
      const avatar = document.getElementById('t-avatar');
      const prev = document.getElementById('t-prev');
      const next = document.getElementById('t-next');
      const dotsWrap = document.getElementById('t-dots');

      let i = 0, timer;

      function render(index) {
        const it = items[index];
        // simple fade
        q.style.opacity = 0; name.style.opacity = 0; role.style.opacity = 0; avatar.style.opacity = 0.5;
        setTimeout(() => {
          q.textContent = `“${it.quote}”`;
          name.textContent = it.name;
          role.textContent = it.role;
          avatar.src = it.avatar;
          q.style.opacity = 1; name.style.opacity = 1; role.style.opacity = 1; avatar.style.opacity = 1;
        }, 150);
        [...dotsWrap.children].forEach((d, idx) => {
          d.classList.toggle('bg-emerald-400', idx === index);
          d.classList.toggle('bg-white/20', idx !== index);
        });
      }

      function start() {
        stop();
        timer = setInterval(() => { i = (i + 1) % items.length; render(i); }, 6000);
      }
      function stop() { if (timer) clearInterval(timer); }

      // dots
      items.forEach((_, idx) => {
        const dot = document.createElement('button');
        dot.className = "h-2.5 w-2.5 rounded-full bg-white/20 ring-1 ring-white/10 transition";
        dot.setAttribute('aria-label', `Go to testimonial ${idx + 1}`);
        dot.addEventListener('click', () => { i = idx; render(i); start(); });
        dotsWrap.appendChild(dot);
      });

      prev.addEventListener('click', () => { i = (i - 1 + items.length) % items.length; render(i); start(); });
      next.addEventListener('click', () => { i = (i + 1) % items.length; render(i); start(); });

      render(i);
      start();

      // pause on hover (optional)
      dotsWrap.closest('section').addEventListener('mouseenter', stop);
      dotsWrap.closest('section').addEventListener('mouseleave', start);
    })();
  </script>
</section>

  <!-- Charts -->
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js" class=""></script>
  <script class="">
    (function () {
      const el = document.getElementById('aura-growth-chart');
      if (!el) return;

      const ctx = el.getContext('2d');
      const gradient = ctx.createLinearGradient(0, 0, 0, el.height);
      gradient.addColorStop(0, 'rgba(139, 92, 246, 0.35)');
      gradient.addColorStop(1, 'rgba(139, 92, 246, 0.00)');

      const grid = 'rgba(148,163,184,0.15)';
      const label = 'rgba(226,232,240,0.8)';

      new Chart(el, {
        type: 'line',
        data: {
          labels: ['','10','20','30','40','50','60','Yesterday',''],
          datasets: [
            {
              label: 'Primary',
              data: [12,14,13,20,38,62,48,54,56],
              borderColor: '#7c3aed',
              backgroundColor: gradient,
              fill: true,
              borderWidth: 2.5,
              pointRadius: 0,
              tension: 0.35
            },
            {
              label: 'Secondary',
              data: [10,11,15,16,18,22,30,44,40],
              borderColor: 'rgba(255,255,255,0.85)',
              borderWidth: 2,
              pointRadius: 0,
              tension: 0.35
            }
          ]
        },
        options: {
          responsive: true,
          maintainAspectRatio: false,
          plugins: {
            legend: { display: false },
            tooltip: {
              enabled: true,
              backgroundColor: 'rgba(17,24,39,0.95)',
              titleColor: '#fff',
              bodyColor: '#e5e7eb',
              displayColors: false,
              padding: 10
            }
          },
          scales: {
            x: {
              grid: { color: grid, drawBorder: false },
              ticks: { color: label, maxTicksLimit: 8 }
            },
            y: {
              grid: { color: grid, drawBorder: false },
              ticks: { color: label, maxTicksLimit: 6 }
            }
          }
        }
      });
    })();
  </script>
</section>
All Prompts