Section

Agent Workflow — Sharp Glassmorphism

Frosted-glass agent execution stepper floating over a living gradient mesh, visualizing Plan, Search, Reason, Act, Reflect, Respond. Translucent layered nodes glow cyan when done and fuchsia when running, with a gradient filling progress bar. A Run button drives steps through pending → running → done on a timer with a live log line. Respects prefers-reduced-motion.

  • Section
  • Tailwind
  • HTML
  • MIT

Preview

Live section

Interactive preview
Open preview
9:41 100%
devsnips.dev/library/tailwind/sections/ai-product/agent-workflow/sharp-glassmorphism/
fluid · no fixed width 100%
Dependencies: Tailwind CSS (CDN) · Google Fonts: Sora, JetBrains Mono Responsive · Keyboard-ready · Reduced-motion

Install

Add to your project

terminal
npx devsnips add Tailwind/Sections/AI-Product/agent-workflow/sharp-glassmorphism
registry path: Tailwind/Sections/AI-Product/agent-workflow/sharp-glassmorphism

Source

Implementation

code.html
<!--
Snippet Name: Agent Workflow — Sharp Glassmorphism
Description: Frosted-glass agent execution stepper over a vibrant animated gradient mesh that animates Plan → Search → Reason → Act → Reflect → Respond through pending/running/done states with a gradient filling connector and a Run button.
Author: DevSnips Contributors
Usage Example: Drop into a vivid app shell as an agent run visualization. The Run button drives the steps through statuses on a timer. Requires a colored backdrop behind the panel for the glass to read.
-->
<div class="relative w-full max-w-2xl" data-workflow="sg">

  <!-- Glass panel -->
  <div class="relative overflow-hidden rounded-2xl border border-white/20 bg-white/10 shadow-[0_8px_40px_-12px_rgba(99,102,241,0.45)] backdrop-blur-2xl">
    <!-- Top highlight -->
    <div class="pointer-events-none absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white/50 to-transparent" aria-hidden="true"></div>

    <!-- Header -->
    <div class="flex flex-wrap items-center justify-between gap-3 border-b border-white/15 px-5 py-4">
      <div class="flex items-center gap-3">
        <div class="sg-glow flex h-10 w-10 items-center justify-center rounded-xl border border-white/30 bg-white/20 text-white backdrop-blur">
          <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
            <circle cx="6" cy="6" r="2.4" /><circle cx="18" cy="6" r="2.4" /><circle cx="12" cy="18" r="2.4" />
            <path d="M7.6 7.6 10.6 16M16.4 7.6 13.4 16" />
          </svg>
        </div>
        <div class="leading-tight">
          <p class="font-sora text-[15px] font-semibold text-white">Agent Run · #4827</p>
          <p class="sg-mono mt-1 flex items-center gap-1.5 text-[11px] text-white/70">
            <span class="wf-status-dot sg-dot"></span> <span data-wf-status-label>Idle · 6 steps</span>
          </p>
        </div>
      </div>
      <button type="button" data-wf-run class="sg-glow flex items-center gap-2 rounded-xl border border-white/30 bg-gradient-to-r from-fuchsia-500 to-indigo-500 px-4 py-2 font-sora text-[13px] font-semibold text-white transition-opacity hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-white/60">
        <svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M6 4l14 8-14 8V4z" /></svg>
        <span data-wf-run-label>Run</span>
      </button>
    </div>

    <!-- Progress bar -->
    <div class="border-b border-white/15 px-5 py-4">
      <div class="flex items-center justify-between">
        <p class="sg-mono text-[11px] text-white/60">Progress</p>
        <p class="sg-mono text-[11px] text-white/80" data-wf-count>0 / 6</p>
      </div>
      <div class="mt-2 h-1.5 w-full overflow-hidden rounded-full bg-white/10">
        <div class="wf-progress h-full w-0 rounded-full bg-gradient-to-r from-fuchsia-500 to-cyan-400 transition-[width] duration-300 ease-out" style="box-shadow:0 0 12px rgba(168,85,247,0.6)" data-wf-progress></div>
      </div>
    </div>

    <!-- Steps -->
    <ol class="wf-steps divide-y divide-white/10" data-wf-steps>
      <!-- steps injected by JS -->
    </ol>

    <!-- Footer / log -->
    <div class="border-t border-white/15 px-5 py-3">
      <p class="sg-mono text-[11px] text-white/60">
        <span class="text-cyan-200">//</span> <span data-wf-log>Awaiting start.</span>
      </p>
    </div>
  </div>

  <style>
    [data-workflow="sg"] .sg-mono { font-family: 'JetBrains Mono', ui-monospace, monospace; }
    [data-workflow="sg"] .font-sora { font-family: 'Sora', sans-serif; }
    [data-workflow="sg"] .sg-dot { display: inline-block; height: 6px; width: 6px; border-radius: 9999px; background: #6ee7ff; box-shadow: 0 0 8px #6ee7ff; }
    [data-workflow="sg"] .sg-glow { box-shadow: 0 0 0 1px rgba(255,255,255,0.08), 0 4px 20px -4px rgba(168,85,247,0.5); }
    [data-workflow="sg"] .wf-step { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 14px; padding: 14px 20px; }
    [data-workflow="sg"] .wf-node { display: flex; align-items: center; justify-content: center; height: 40px; width: 40px; border-radius: 12px; border: 1px solid rgba(255,255,255,0.2); background: rgba(255,255,255,0.1); color: rgba(255,255,255,0.7); backdrop-blur; transition: all .25s ease; }
    [data-workflow="sg"] .wf-step[data-status="done"] .wf-node { background: rgba(110,231,255,0.25); color: #6ee7ff; border-color: rgba(110,231,255,0.6); box-shadow: 0 0 0 1px rgba(255,255,255,0.08), 0 4px 20px -4px rgba(110,231,255,0.5); }
    [data-workflow="sg"] .wf-step[data-status="running"] .wf-node { background: rgba(236,72,153,0.25); color: #fff; border-color: rgba(236,72,153,0.6); animation: sg-pulse 1.4s infinite ease-in-out; }
    @keyframes sg-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(236,72,153,0); } 50% { box-shadow: 0 0 0 5px rgba(236,72,153,0.18); } }
    [data-workflow="sg"] .wf-step[data-status="done"] .wf-title { color: rgba(255,255,255,0.95); }
    [data-workflow="sg"] .wf-step[data-status="running"] .wf-title { color: #fff; }
    [data-workflow="sg"] .wf-step[data-status="pending"] .wf-title { color: rgba(255,255,255,0.5); }
    [data-workflow="sg"] .wf-pill { font-family: 'JetBrains Mono', monospace; font-size: 10px; text-transform: uppercase; letter-spacing: .08em; padding: 2px 8px; border-radius: 9999px; border: 1px solid rgba(255,255,255,0.2); color: rgba(255,255,255,0.6); background: rgba(255,255,255,0.06); backdrop-blur; }
    [data-workflow="sg"] .wf-step[data-status="done"] .wf-pill { color: #6ee7ff; border-color: rgba(110,231,255,0.5); background: rgba(110,231,255,0.12); }
    [data-workflow="sg"] .wf-step[data-status="running"] .wf-pill { color: #fff; border-color: rgba(236,72,153,0.6); background: rgba(236,72,153,0.2); }
  </style>

  <script>
    (function () {
      var root = document.currentScript.closest('[data-workflow="sg"]');
      if (!root) return;

      var STEPS = [
        { id: 'plan', label: 'Plan', detail: 'Decompose goal into subtasks', icon: '<path d="M9 4h6a2 2 0 0 1 2 2v3M9 20h6a2 2 0 0 0 2-2v-3"/><rect x="4" y="8" width="6" height="5"/><path d="M10 10.5h4"/>' },
        { id: 'search', label: 'Search', detail: 'Retrieve context from tools', icon: '<circle cx="11" cy="11" r="6"/><path d="M20 20l-4-4"/>' },
        { id: 'reason', label: 'Reason', detail: 'Chain logic over evidence', icon: '<path d="M12 3v3M12 18v3M3 12h3M18 12h3"/><circle cx="12" cy="12" r="3.4"/>' },
        { id: 'act', label: 'Act', detail: 'Call tool: write_file()', icon: '<path d="M4 12h11M11 8l4 4-4 4"/><rect x="16" y="6" width="4" height="12"/>' },
        { id: 'reflect', label: 'Reflect', detail: 'Verify output vs goal', icon: '<path d="M4 6h16M4 12h10M4 18h7"/>' },
        { id: 'respond', label: 'Respond', detail: 'Stream final answer', icon: '<path d="M4 5h16v10H7l-3 3V5z"/>' }
      ];

      var ol = root.querySelector('[data-wf-steps]');
      var progress = root.querySelector('[data-wf-progress]');
      var countEl = root.querySelector('[data-wf-count]');
      var runBtn = root.querySelector('[data-wf-run]');
      var runLabel = root.querySelector('[data-wf-run-label]');
      var statusLabel = root.querySelector('[data-wf-status-label]');
      var logEl = root.querySelector('[data-wf-log]');

      var reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
      var tickMs = reduceMotion ? 0 : 1100;

      STEPS.forEach(function (s, idx) {
        var li = document.createElement('li');
        li.className = 'wf-step';
        li.setAttribute('data-step', s.id);
        li.setAttribute('data-status', 'pending');
        li.setAttribute('aria-label', 'Step ' + (idx + 1) + ' of ' + STEPS.length + ': ' + s.label + ', pending');
        li.innerHTML =
          '<div class="wf-node">' +
            '<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">' + s.icon + '</svg>' +
          '</div>' +
          '<div>' +
            '<p class="wf-title font-sora text-[14px] font-semibold leading-tight">' + s.label + '</p>' +
            '<p class="sg-mono mt-0.5 text-[11px] text-white/55">' + s.detail + '</p>' +
          '</div>' +
          '<span class="wf-pill">Pending</span>';
        ol.appendChild(li);
      });

      var stepEls = Array.prototype.slice.call(ol.querySelectorAll('.wf-step'));
      var running = false;
      var timer = null;

      function setStatus(el, status) {
        el.setAttribute('data-status', status);
        var idx = stepEls.indexOf(el);
        el.setAttribute('aria-label', 'Step ' + (idx + 1) + ' of ' + STEPS.length + ': ' + STEPS[idx].label + ', ' + status);
        var pill = el.querySelector('.wf-pill');
        var label = status.charAt(0).toUpperCase() + status.slice(1);
        pill.textContent = label;
      }

      function renderProgress(done) {
        var pct = (done / STEPS.length) * 100;
        progress.style.width = pct + '%';
        countEl.textContent = done + ' / ' + STEPS.length;
      }

      function setHeaderState(state) {
        var map = {
          idle: 'Idle · 6 steps',
          running: 'Running…',
          done: 'Completed'
        };
        if (statusLabel) statusLabel.textContent = map[state] || map.idle;
      }

      function reset() {
        stepEls.forEach(function (el) { setStatus(el, 'pending'); });
        renderProgress(0);
        setHeaderState('idle');
        if (logEl) logEl.textContent = 'Awaiting start.';
      }

      function finish() {
        running = false;
        setHeaderState('done');
        if (runBtn) { runBtn.disabled = false; if (runLabel) runLabel.textContent = 'Run again'; }
        if (logEl) logEl.textContent = 'Run complete. 6/6 steps succeeded.';
      }

      function run() {
        if (running) return;
        running = true;
        if (runBtn) runBtn.disabled = true;
        if (runLabel) runLabel.textContent = 'Running';
        reset();
        setHeaderState('running');
        if (logEl) logEl.textContent = 'Starting agent run…';

        var i = 0;
        function next() {
          if (i > 0) {
            setStatus(stepEls[i - 1], 'done');
            if (logEl) logEl.textContent = 'Completed: ' + STEPS[i - 1].label;
            renderProgress(i);
          }
          if (i >= STEPS.length) { finish(); return; }
          setStatus(stepEls[i], 'running');
          if (logEl) logEl.textContent = 'Executing: ' + STEPS[i].label;
          i++;
          if (tickMs === 0) { next(); }
          else { timer = setTimeout(next, tickMs); }
        }
        next();
      }

      if (runBtn) runBtn.addEventListener('click', function () { if (timer) clearTimeout(timer); run(); });
      reset();
    })();
  </script>
</div>
193 lines UTF-8 · LF · Spaces: 2

AI-ready

Available to your agent.

This section is reachable through the DevSnips CLI, MCP server and Skills integrations — one registry, one resource path.

Resource path

devsnips://sections/ai-product/agent-workflow/sharp-glassmorphism

Continue browsing

View all