Skip to content

Features Tabs

Glass pill tab bar (Radix Tabs) with gradient active tab switching a large frosted panel: title, copy and bullets on the left, a layered glass preview on the right.

glass/section/features-tabs
Open ↗

Source

"use client";

import { Tabs } from "radix-ui";
import { CalendarCheck, FileVideo, MessagesSquare, Sparkles, type LucideIcon } from "lucide-react";
import { cn } from "@/lib/utils";

export interface FeaturesTabsItem {
  id: string;
  label: string;
  icon: LucideIcon;
  title: string;
  description: string;
  bullets: string[];
}

export interface FeaturesTabsProps {
  eyebrow?: string;
  title?: string;
  items?: FeaturesTabsItem[];
  className?: string;
}

const GLASS = "da-stroke bg-da-surface backdrop-blur-da backdrop-saturate-150";

const DEFAULT_ITEMS: FeaturesTabsItem[] = [
  {
    id: "recaps",
    label: "Recaps",
    icon: Sparkles,
    title: "A recap your team will actually read",
    description: "Five lines, decisions first, owners tagged. Posted to Slack and email the moment the call ends.",
    bullets: ["Decisions, actions, open questions", "Custom templates per meeting type", "Edit before sharing — or let it auto-post"],
  },
  {
    id: "video",
    label: "Async video",
    icon: FileVideo,
    title: "Replace the status meeting",
    description: "Record your screen and face for two minutes; Halo adds chapters, a transcript and a summary.",
    bullets: ["Chapters and summary auto-generated", "Viewers reply with emoji or text", "1.5× playback by default"],
  },
  {
    id: "prep",
    label: "Prep",
    icon: CalendarCheck,
    title: "Walk in with context",
    description: "Before each meeting Halo sends what was decided last time and what’s still open.",
    bullets: ["Open action items by attendee", "Last three related recaps", "Suggested agenda"],
  },
  {
    id: "ask",
    label: "Ask Halo",
    icon: MessagesSquare,
    title: "Search everything your team said",
    description: "Ask in plain English and get answers with timestamps you can jump to.",
    bullets: ["Answers cite the exact moment", "Respects meeting permissions", "Works across 12 months of calls"],
  },
];

/** Glass pill tabs (Radix Tabs) switching a large frosted panel: copy + bullets on the left, a themed preview on the right. */
export function FeaturesTabs({ eyebrow = "How Halo helps", title = "One assistant, four superpowers", items = DEFAULT_ITEMS, className }: FeaturesTabsProps) {
  return (
    <section aria-labelledby="glass-tabs-title" className={cn("da-section text-da-fg", className)}>
      <div className="da-container">
        <div className="mx-auto max-w-2xl text-center">
          <p className="text-sm font-semibold text-da-primary">{eyebrow}</p>
          <h2
            id="glass-tabs-title"
            className="mt-3 font-da-display text-[clamp(2rem,4.5vw,3.25rem)] leading-[1.08] font-semibold tracking-da-display text-balance"
          >
            {title}
          </h2>
        </div>
        <Tabs.Root defaultValue={items[0]?.id} className="mt-10">
          <Tabs.List aria-label="Features" className={cn("mx-auto flex w-fit max-w-full gap-1 overflow-x-auto rounded-da-pill p-1.5 shadow-da-sm", GLASS)}>
            {items.map((it) => (
              <Tabs.Trigger
                key={it.id}
                value={it.id}
                className="da-focus da-transition inline-flex shrink-0 items-center gap-2 rounded-da-pill px-4 py-2 text-sm font-medium text-da-muted-fg hover:text-da-fg data-[state=active]:bg-gradient-to-r data-[state=active]:from-da-primary data-[state=active]:to-da-accent data-[state=active]:text-da-primary-fg data-[state=active]:shadow-da-sm"
              >
                <it.icon aria-hidden className="size-4" />
                {it.label}
              </Tabs.Trigger>
            ))}
          </Tabs.List>
          {items.map((it, i) => (
            <Tabs.Content
              key={it.id}
              value={it.id}
              className={cn(
                "da-focus mt-8 grid items-center gap-10 rounded-da-lg p-6 shadow-da-lg transition-[opacity,translate] duration-(--da-duration-slow) ease-da starting:translate-y-2 starting:opacity-0 sm:p-10 lg:grid-cols-2",
                GLASS,
              )}
            >
              <div>
                <h3 className="font-da-display text-2xl font-semibold tracking-da-display sm:text-3xl">{it.title}</h3>
                <p className="mt-3 text-da-muted-fg">{it.description}</p>
                <ul className="mt-6 space-y-2.5">
                  {it.bullets.map((b) => (
                    <li key={b} className="flex items-center gap-2.5 text-[15px]">
                      <span aria-hidden className="size-1.5 rounded-full bg-gradient-to-r from-da-primary to-da-accent" />
                      {b}
                    </li>
                  ))}
                </ul>
              </div>
              <div
                aria-hidden
                className="relative aspect-[4/3] overflow-hidden rounded-da-md bg-gradient-to-br from-da-primary/30 via-da-surface-2 to-da-accent/30"
              >
                <div className="absolute inset-x-6 top-6 rounded-da-md bg-da-surface p-4 shadow-da-md backdrop-blur-da">
                  <p className="flex items-center gap-2 text-sm font-semibold">
                    <it.icon className="size-4 text-da-primary" /> {it.label}
                  </p>
                  <div className="mt-3 space-y-2">
                    {[88, 72, 56 + i * 8].map((w, k) => (
                      <span key={k} className="block h-2 rounded-full bg-da-fg/10" style={{ width: `${w}%` }} />
                    ))}
                  </div>
                </div>
                <div className="absolute right-6 bottom-6 left-16 rounded-da-md bg-da-surface p-4 shadow-da-md backdrop-blur-da">
                  <div className="flex gap-2">
                    {it.bullets.map((b) => (
                      <span key={b} className="h-6 flex-1 rounded-da-pill bg-gradient-to-r from-da-primary/40 to-da-accent/40" />
                    ))}
                  </div>
                </div>
              </div>
            </Tabs.Content>
          ))}
        </Tabs.Root>
      </div>
    </section>
  );
}

export default FeaturesTabs;

modules/glass/section/features-tabs/index.tsx

Props

PropTypeDefaultDescription
eyebrow / titlestring—Header.
items{ id, label, icon, title, description, bullets }[]—Tabs.
classNamestring—Classes.

Other features variants in Glass

Features in other art directions

Features Grid

Six features in a single ruled box (1/2/3 columns) with numbered tiles, color-cycling icon blocks that press on hover, and a two-column section header.

BrutalistFeatures

Features Numbered

Full-width ruled rows with giant faded step numbers, uppercase titles, descriptions and a stat chip; each row floods with a different primary color on hover and the number turns solid.

BrutalistFeatures

Features Tabs

Tabbed feature explorer: ruled mono tab bar (ink active tab), then a big split panel with title, description and square-bullet list on the left and a stacked mock preview of the channel on the right.

BrutalistFeatures

Features Versus

Before/after comparison: two slightly tilted cards side by side — the old way in paper with red crosses, the new way in solid yellow with ink checks — row by row on the same topics.

BrutalistFeatures

Features Alternating

Three zig-zag rows, each pairing a numbered kicker, title, copy and link with an HTML product mock-up (routing rules, on-call week, AI postmortem) on a soft tinted plate.

MinimalFeatures

Features Bento

Bento grid of five hairline tiles on a 6-column layout, each with a small token-themed HTML illustration (routing lines, uptime bars, MTTR metric, on-call week) above an icon, title and description.

MinimalFeatures

Features List

Dense four-column feature list: each item has a small indigo line icon, a title and a one-sentence description under a hairline top rule. Eight defaults, left-aligned header.

MinimalFeatures

Features Steps

Five-step workflow (detect, page, coordinate, resolve, learn) laid out horizontally on desktop and vertically on mobile, joined by a hairline, with numbered nodes and timing labels.

MinimalFeatures

Features Index

Features as a numbered index: a label + headline in the left columns, and a two-column ruled list on the right where each item is “01 — Title” with a short description.

Mono CleanFeatures

Features Numbered

Three large numbered steps: giant outlined-looking numerals in muted ink above a hairline, step title and text; columns on desktop, stacked on mobile.

Mono CleanFeatures

Features Showcase

Work showcase as the feature: an asymmetric grid (fixed row heights; wide, tall, square and full-width spans) of neutral gray image frames with mono captions (studio — project, template used); captions underline on hover.

Mono CleanFeatures

Features Specs

Technical spec sheet: grouped key/value definition lists in a 4-column grid, each group under a full-ink rule with a mono heading — reads like a product data sheet.

Mono CleanFeatures

Features Bento

Data-driven bento grid of bordered cards: cash-flow line chart, DSO metric, approval flow, currency list and integrations — each a small realistic mock.

Neo CorporateFeatures

Features Grid

Classic 3×2 bordered feature grid sharing hairline borders (one outer frame), each cell with a blue icon square, title, text and a “Learn more” link.

Neo CorporateFeatures

Features Tabs

Underline tabs (Radix Tabs) switching between product areas: copy + check points on the left, a bordered data card (status rows) on the right.

Neo CorporateFeatures

Features Versus

Before/after comparison: a muted “spreadsheets and email” column with red crosses next to a blue-bordered “with Ledgerly” column with green checks.

Neo CorporateFeatures

Features Alternating

Alternating zig-zag rows: copy with check points on one side, a soft blob-shaped tinted panel holding a small product vignette (suppliers, actions, report) on the other.

Organic SoftFeatures

Features Bento

Soft bento: rounded tinted tiles of mixed sizes — a monthly emissions bar chart, a human equivalence (“= 42 flights”), supplier avatars, a certifications tile and a leaf quote.

Organic SoftFeatures

Features Cards

Three tall rounded cards in sage, clay and paper tints; each has an icon sitting in an organic blob, a serif title and calm copy.

Organic SoftFeatures

Features Journey

Horizontal journey: numbered circles connected by a hand-drawn wavy dashed path (vertical list on mobile), each step with a serif title, text and a mono time estimate.

Organic SoftFeatures

Features Checklist

Interactive split section: copy and a mint progress bar on the left, a white card of four round-checkbox steps on the right that turn mint with a bouncy tick when clicked; celebration at 100%.

Soft FlatFeatures

Features Icons

Centered 4-column grid of eight small features, each with a large round pastel icon badge (colors rotate), rounded title and one-liner.

Soft FlatFeatures

Features Pastel

2×2 grid of large pastel feature cards (peach, mint, lavender, butter), each with icon, rounded title, copy and a tiny flat illustration (mini board, bar week, reminder toast, chat bubbles).

Soft FlatFeatures

Features Steps

Three numbered step cards in peach, lavender and mint joined by a dashed path on desktop, each with a white emoji medallion, mono step label, title and text.

Soft FlatFeatures