Vireon UI Template - Let's templates
Vireon preview 1
Free
0 2

Vireon

Vireon is a moody, monochrome agency template for creative studios and digital consultancies with a services accordion, case studies, and a full-bleed contact form.

Live Demo
vireon-tailwind.html
<%# letstemplates: access=premium category=agency %>
<!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>Vireon | Tailwind CSS Agency Template</title>
  <meta name="description" content="Vireon is a moody, monochrome Tailwind CSS agency template for creative studios and digital consultancies with a services accordion, case studies, and a full-bleed contact form.">
  <meta name="keywords" content="Vireon, Tailwind CSS template, HTML website template, agency template, creative studio, digital consultancy, case studies, services accordion, responsive agency design">
  <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="Vireon | Tailwind CSS Agency Template">
  <meta property="og:description" content="A moody, monochrome Tailwind CSS agency template for creative studios and digital consultancies with a services accordion, case studies, and a full-bleed contact form.">
  <meta property="og:image" content="">
  <meta property="og:image:alt" content="Vireon template preview">

  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:url" content="">
  <meta name="twitter:title" content="Vireon | Tailwind CSS Agency Template">
  <meta name="twitter:description" content="A moody, monochrome Tailwind CSS agency template for creative studios and digital consultancies with a services accordion, case studies, and a full-bleed contact form.">
  <meta name="twitter:image" content="">
  <meta name="twitter:image:alt" content="Vireon template preview">
  <script src="https://cdn.tailwindcss.com"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            ink: '#0d0d0d',
            paper: '#ffffff',
            mist: '#8f8f8f'
          },
          fontFamily: {
            sans: ['"Space Grotesk"', 'ui-sans-serif', 'system-ui', 'sans-serif'],
            mono: ['"JetBrains Mono"', 'ui-monospace', 'monospace']
          }
        }
      }
    };
  </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; }
    [data-accordion-panel] { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .45s ease; }
    [data-accordion-panel] > div { overflow: hidden; }
    [data-accordion-item][aria-expanded="true"] [data-accordion-panel] { grid-template-rows: 1fr; }
    [data-accordion-item][aria-expanded="true"] [data-accordion-icon] { transform: rotate(45deg); }
    [data-accordion-icon] { transition: transform .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; }
      [data-accordion-panel], [data-accordion-icon] { transition: none; }
      ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
    }
  </style>
</head>
<body class="bg-paper font-sans text-ink antialiased">

  <!-- block:start navbar -->
  <header class="fixed inset-x-0 top-0 z-40 border-b border-black/10 bg-paper/90 backdrop-blur">
    <nav class="mx-auto flex max-w-7xl items-center justify-between px-6 py-5 lg:px-10">
      <a href="index.html" class="font-mono text-lg font-semibold tracking-tight text-ink">Vireon<span class="text-mist">.</span></a>
      <div class="hidden items-center gap-10 md:flex">
        <% { "index" => "Home", "about" => "About", "work" => "Work", "services" => "Services" }.each do |slug, label| %>
          <a href="<%= slug == "index" ? "index.html" : "#{slug}.html" %>" <%= 'aria-current="page"'.html_safe if slug == "index" %> class="text-sm font-medium <%= slug == "index" ? "text-ink" : "text-mist transition hover:text-ink" %>"><%= label %></a>
        <% end %>
      </div>
      <a href="contact.html" class="hidden rounded-full border border-ink px-5 py-2 text-sm font-medium text-ink transition hover:bg-ink hover:text-paper md:inline-flex">Start a project</a>
      <button type="button" id="menu-toggle" aria-expanded="false" aria-controls="mobile-menu" class="inline-flex h-10 w-10 items-center justify-center rounded-full border border-black/10 md:hidden">
        <i class="fa-solid fa-bars text-sm" aria-hidden="true"></i>
        <span class="sr-only">Toggle menu</span>
      </button>
    </nav>
    <div id="mobile-menu" hidden class="border-t border-black/10 bg-paper px-6 pb-6 md:hidden">
      <% { "index" => "Home", "about" => "About", "work" => "Work", "services" => "Services" }.each do |slug, label| %>
        <a href="<%= slug == "index" ? "index.html" : "#{slug}.html" %>" class="block py-3 text-sm font-medium <%= slug == "index" ? "text-ink" : "text-mist" %>"><%= label %></a>
      <% end %>
      <a href="contact.html" class="mt-2 block rounded-full border border-ink px-5 py-2 text-center text-sm font-medium text-ink">Start a project</a>
    </div>
  </header>
  <!-- block:end navbar -->

  <!-- block:start hero -->
  <section id="hero" class="px-6 pb-16 pt-36 lg:px-10 lg:pt-48">
    <div class="mx-auto grid max-w-7xl items-center gap-12 lg:grid-cols-2">
      <div data-reveal>
        <span class="inline-flex items-center gap-2 rounded-full border border-black/10 px-3 py-1 font-mono text-xs uppercase tracking-widest text-mist"><i class="fa-solid fa-asterisk text-[10px]" aria-hidden="true"></i>Independent studio</span>
        <h1 class="mt-6 text-5xl font-semibold leading-[1.05] tracking-tight md:text-6xl lg:text-7xl">Brand and product design, built with restraint.</h1>
        <p class="mt-6 max-w-md text-base text-mist md:text-lg">We're a small studio shaping identity, interface and motion for teams who'd rather do one thing well than ten things loudly.</p>
        <div class="mt-8 flex flex-wrap items-center gap-4">
          <a href="work.html" class="inline-flex items-center gap-2 rounded-full bg-ink px-6 py-3 text-sm font-medium text-paper transition hover:bg-black/80">See selected work<i class="fa-solid fa-arrow-up rotate-45 text-xs" aria-hidden="true"></i></a>
          <a href="contact.html" class="inline-flex items-center gap-2 rounded-full border border-ink px-6 py-3 text-sm font-medium text-ink transition hover:bg-ink hover:text-paper">Start a project</a>
        </div>
        <dl class="mt-12 grid max-w-sm grid-cols-3 gap-4 border-t border-black/10 pt-6">
          <% [["11", "Years"], ["64", "Projects"], ["18", "Clients"]].each do |value, label| %>
            <div>
              <dt class="font-mono text-2xl font-semibold" data-count-to="<%= value %>"><%= value %></dt>
              <dd class="mt-1 text-xs uppercase tracking-widest text-mist"><%= label %></dd>
            </div>
          <% end %>
        </dl>
      </div>
      <div data-reveal style="--reveal-delay:120ms" class="relative aspect-[4/5] overflow-hidden rounded-2xl bg-black">
        <img src="https://images.unsplash.com/photo-1697899001862-59699946ea29?auto=format&fit=crop&w=1200&q=80" alt="Grainy monochrome abstract sculptural render" class="h-full w-full object-cover">
      </div>
    </div>
  </section>
  <!-- block:end hero -->

  <!-- block:start about -->
  <section id="about" class="border-t border-black/10 px-6 py-24 lg:px-10">
    <div class="mx-auto grid max-w-7xl gap-12 lg:grid-cols-2">
      <div data-reveal>
        <span class="font-mono text-xs uppercase tracking-widest text-mist">01 / Approach</span>
        <h2 class="mt-4 text-3xl font-semibold tracking-tight md:text-4xl">We design in the space between clarity and character.</h2>
      </div>
      <div class="grid gap-8 sm:grid-cols-2">
        <% [
          ["Listen first", "We start with your constraints, not a template. Every engagement begins with a short discovery sprint."],
          ["Design in the open", "Weekly reviews, shared files, no black-box reveals. You see the work as it forms."],
          ["Build for use", "Every system ships with the documentation and components your team needs to run it without us."],
          ["Stay small", "A capped roster of active clients means senior attention on every project, always."]
        ].each_with_index do |(title, copy), index| %>
          <div data-reveal style="--reveal-delay:<%= index * 80 %>ms">
            <span class="font-mono text-sm text-mist"><%= format("%02d", index + 1) %></span>
            <h3 class="mt-2 text-lg font-semibold"><%= title %></h3>
            <p class="mt-2 text-sm text-mist"><%= copy %></p>
          </div>
        <% end %>
      </div>
    </div>
  </section>
  <!-- block:end about -->

  <!-- block:start gallery -->
  <section id="work" class="border-t border-black/10 px-6 py-24 lg:px-10">
    <div class="mx-auto max-w-7xl">
      <div data-reveal class="flex flex-wrap items-end justify-between gap-4">
        <div>
          <span class="font-mono text-xs uppercase tracking-widest text-mist">02 / Selected work</span>
          <h2 class="mt-4 text-3xl font-semibold tracking-tight md:text-4xl">A few recent engagements</h2>
        </div>
        <a href="work.html" class="inline-flex items-center gap-2 text-sm font-medium text-ink hover:text-mist">View all work<i class="fa-solid fa-arrow-up rotate-45 text-xs" aria-hidden="true"></i></a>
      </div>
      <div class="mt-12 grid gap-8 lg:grid-cols-5">
        <a href="solyra.html" data-reveal class="group relative aspect-[16/10] overflow-hidden rounded-2xl bg-black lg:col-span-3">
          <img src="https://images.unsplash.com/photo-1651833826115-7530e72ce504?auto=format&fit=crop&w=1200&q=80" alt="Dark curved ribbon abstract render for a rebrand project" class="h-full w-full object-cover transition duration-500 group-hover:scale-105">
          <span class="absolute inset-x-0 bottom-0 flex items-center justify-between bg-gradient-to-t from-black/70 to-transparent p-6">
            <span class="font-medium text-paper">Solyra &mdash; Full identity system</span>
            <i class="fa-solid fa-arrow-up rotate-45 text-paper" aria-hidden="true"></i>
          </span>
        </a>
        <a href="kindlewave.html" data-reveal style="--reveal-delay:100ms" class="group relative aspect-[16/10] overflow-hidden rounded-2xl bg-black lg:col-span-2">
          <img src="https://images.unsplash.com/photo-1638376776402-9a4b75fe21bb?auto=format&fit=crop&w=900&q=80" alt="Black and white abstract wavy render for a product launch" class="h-full w-full object-cover transition duration-500 group-hover:scale-105">
          <span class="absolute inset-x-0 bottom-0 flex items-center justify-between bg-gradient-to-t from-black/70 to-transparent p-6">
            <span class="font-medium text-paper">Kindlewave &mdash; Launch site</span>
            <i class="fa-solid fa-arrow-up rotate-45 text-paper" aria-hidden="true"></i>
          </span>
        </a>
      </div>
    </div>
  </section>
  <!-- block:end gallery -->

  <!-- block:start features -->
  <section id="services" class="border-t border-black/10 px-6 py-24 lg:px-10">
    <div class="mx-auto grid max-w-7xl gap-12 lg:grid-cols-2">
      <div data-reveal>
        <span class="font-mono text-xs uppercase tracking-widest text-mist">03 / Services</span>
        <h2 class="mt-4 text-3xl font-semibold tracking-tight md:text-4xl">What we take on</h2>
        <p class="mt-4 max-w-sm text-sm text-mist">Every project is scoped around outcomes, not deliverables. Open a row to see how each service runs.</p>
      </div>
      <div data-reveal style="--reveal-delay:100ms" class="divide-y divide-black/10 border-y border-black/10">
        <% [
          ["Brand identity", "Naming, mark, type and voice: a system built to hold up across every surface you ship."],
          ["Product design", "Interface design and prototyping for web and native product, from flow to final pixel."],
          ["Motion & art direction", "Launch films, motion systems and photography direction for campaigns and product reveals."],
          ["Design systems", "Component libraries and documentation your team can extend long after we're gone."]
        ].each_with_index do |(title, copy), index| %>
          <div data-accordion-item aria-expanded="<%= index.zero? %>" class="py-2">
            <button type="button" data-accordion-trigger aria-expanded="<%= index.zero? %>" aria-controls="service-<%= index %>" class="flex w-full items-center justify-between py-4 text-left">
              <span class="text-lg font-medium"><%= title %></span>
              <i data-accordion-icon class="fa-solid fa-plus text-xs" aria-hidden="true"></i>
            </button>
            <div id="service-<%= index %>" data-accordion-panel>
              <div><p class="pb-5 pr-8 text-sm text-mist"><%= copy %></p></div>
            </div>
          </div>
        <% end %>
      </div>
    </div>
  </section>
  <!-- block:end features -->

  <!-- block:start cta -->
  <section class="border-t border-black/10 px-6 py-20 lg:px-10">
    <a href="solyra.html" data-reveal class="group relative mx-auto flex max-w-7xl flex-col items-center gap-8 overflow-hidden rounded-2xl bg-black px-8 py-14 text-center text-paper md:flex-row md:justify-between md:text-left">
      <img src="https://images.unsplash.com/photo-1517241034903-9a4c3ab12f00?auto=format&fit=crop&w=1600&q=60" alt="Monochrome wavy abstract shapes" class="absolute inset-0 h-full w-full object-cover opacity-30 transition duration-500 group-hover:opacity-40">
      <div class="relative">
        <span class="font-mono text-xs uppercase tracking-widest text-white/50">Next project</span>
        <h2 class="mt-3 text-3xl font-semibold tracking-tight md:text-4xl">Solyra &mdash; a quiet identity for a loud category</h2>
      </div>
      <span class="relative inline-flex shrink-0 items-center gap-2 rounded-full border border-white/30 px-6 py-3 text-sm font-medium transition group-hover:bg-white group-hover:text-ink">View case study<i class="fa-solid fa-arrow-up rotate-45 text-xs" aria-hidden="true"></i></span>
    </a>
  </section>
  <!-- block:end cta -->

  <!-- block:start contact -->
  <section id="contact-teaser" class="border-t border-black/10 px-6 py-24 lg:px-10">
    <div data-reveal class="mx-auto max-w-3xl text-center">
      <h2 class="text-3xl font-semibold tracking-tight md:text-4xl">Have a brief worth talking through?</h2>
      <p class="mt-4 text-mist">We take on a small number of new projects each quarter. Tell us where you're headed.</p>
      <a href="contact.html" class="mt-8 inline-flex items-center gap-2 rounded-full bg-ink px-7 py-3 text-sm font-medium text-paper transition hover:bg-black/80">Get in touch<i class="fa-solid fa-arrow-up rotate-45 text-xs" aria-hidden="true"></i></a>
    </div>
  </section>
  <!-- block:end contact -->

  <!-- block:start footer -->
  <footer class="border-t border-black/10 px-6 py-14 lg:px-10">
    <div class="mx-auto flex max-w-7xl flex-col gap-8 md:flex-row md:items-end md:justify-between">
      <div>
        <a href="index.html" class="font-mono text-lg font-semibold tracking-tight text-ink">Vireon<span class="text-mist">.</span></a>
        <p class="mt-3 max-w-xs text-sm text-mist">An independent design studio for brand and product work.</p>
      </div>
      <div class="flex flex-wrap gap-x-10 gap-y-4">
        <div class="flex flex-col gap-2 text-sm">
          <span class="font-mono text-xs uppercase tracking-widest text-mist">Site</span>
          <a href="about.html" class="text-ink hover:text-mist">About</a>
          <a href="work.html" class="text-ink hover:text-mist">Work</a>
          <a href="services.html" class="text-ink hover:text-mist">Services</a>
          <a href="contact.html" class="text-ink hover:text-mist">Contact</a>
        </div>
        <div class="flex flex-col gap-2 text-sm">
          <span class="font-mono text-xs uppercase tracking-widest text-mist">Follow</span>
          <a href="https://instagram.com" class="text-ink hover:text-mist">Instagram</a>
          <a href="https://linkedin.com" class="text-ink hover:text-mist">LinkedIn</a>
        </div>
      </div>
    </div>
    <p class="mx-auto mt-12 max-w-7xl border-t border-black/10 pt-6 text-xs text-mist">&copy; <span data-current-year>2026</span> Vireon Studio. All rights reserved.</p>
  </footer>
  <!-- block:end footer -->

  <script>
    const menuToggle = document.getElementById('menu-toggle');
    const mobileMenu = document.getElementById('mobile-menu');
    if (menuToggle && mobileMenu) {
      menuToggle.addEventListener('click', () => {
        const expanded = menuToggle.getAttribute('aria-expanded') === 'true';
        menuToggle.setAttribute('aria-expanded', String(!expanded));
        mobileMenu.hidden = expanded;
      });
    }

    document.querySelectorAll('[data-accordion-trigger]').forEach((trigger) => {
      trigger.addEventListener('click', () => {
        const item = trigger.closest('[data-accordion-item]');
        const isOpen = item.getAttribute('aria-expanded') === 'true';
        item.parentElement.querySelectorAll('[data-accordion-item]').forEach((other) => {
          other.setAttribute('aria-expanded', 'false');
          other.querySelector('[data-accordion-trigger]').setAttribute('aria-expanded', 'false');
        });
        item.setAttribute('aria-expanded', String(!isOpen));
        trigger.setAttribute('aria-expanded', String(!isOpen));
      });
    });

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

    const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (!reduceMotion && !navigator.webdriver && 'IntersectionObserver' in window) {
      document.body.classList.add('reveal-ready');
      const revealObserver = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
          if (!entry.isIntersecting) return;
          entry.target.classList.add('is-visible');
          revealObserver.unobserve(entry.target);
        });
      }, { threshold: 0.15 });
      document.querySelectorAll('[data-reveal]').forEach((el) => revealObserver.observe(el));

      const countObserver = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
          if (!entry.isIntersecting) return;
          const el = entry.target;
          const target = parseInt(el.dataset.countTo, 10);
          const start = performance.now();
          const step = (now) => {
            const progress = Math.min((now - start) / 700, 1);
            el.textContent = Math.round(progress * target);
            if (progress < 1) requestAnimationFrame(step);
          };
          requestAnimationFrame(step);
          countObserver.unobserve(el);
        });
      }, { threshold: 0.4 });
      document.querySelectorAll('[data-count-to]').forEach((el) => countObserver.observe(el));
    }
  </script>
</body>
</html>

Unlimited access to all templates

Unlock our entire library of premium UI kits, dashboards, and landing pages. Renews automatically, cancel anytime.

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

More Agency Templates