# Value Pill

> Inline badge that sets a value off from running text.

- **Slug:** `value-pill`
- **Kind:** atom · **Category:** Content
- **Source:** ported from [Beautiful UI](https://github.com/slev12397/beautiful-ui/blob/main/components/atoms/ValuePill.tsx) (MIT)
- **Docs page:** https://viewership.ai/ui/components/value-pill
- **All files in one bundle:** https://viewership.ai/ui/components/value-pill.bundle.txt
- **Structured JSON:** https://viewership.ai/ui/components/value-pill.json

## Install

1. Import the foundation tokens once (download: https://viewership.ai/ui/raw/foundation.css.txt):

```astro
---
// src/layouts/Layout.astro
import "../styles/foundation.css";
---
```

2. Copy this file into `src/components/viewership/value-pill/`:

   - `ValuePill.astro` (raw: https://viewership.ai/ui/raw/value-pill/ValuePill.astro.txt)

npm packages: none.

## Usage

```astro
---
import ValuePill from "../components/viewership/value-pill/ValuePill.astro";
---

<ValuePill />
```

## Example

The gallery demo, verbatim. Use the import path from Usage instead of `./`.

```astro
---
import ValuePill from "./ValuePill.astro";

interface Props {
  variant?: string;
}
const { variant = "In prose" } = Astro.props;
---

{variant === "In prose" && (
  <div class="card">
    <p>
      Approve the draft within <ValuePill tone="green">9 days</ValuePill> so it ships before
      the <ValuePill>Spring Trail</ValuePill> launch on <ValuePill tone="accent">Nov 18</ValuePill>.
    </p>
    <p>
      Bounce rate on the trail pack page hit <ValuePill tone="orange">62.4%</ValuePill>, and two links are
      <ValuePill tone="red">broken</ValuePill>.
    </p>
  </div>
)}

{variant === "Tones" && (
  <div class="row">
    <ValuePill>Organic</ValuePill>
    <ValuePill tone="green">9 days</ValuePill>
    <ValuePill tone="orange">62.4% bounce</ValuePill>
    <ValuePill tone="red">2 broken links</ValuePill>
    <ValuePill tone="accent">Nov 18</ValuePill>
  </div>
)}

<style>
  .card {
    max-width: 440px;
    margin: 0 auto;
    padding: 16px 18px;
    border-radius: var(--vs-radius-card);
    background: var(--vs-surface);
    box-shadow: var(--vs-shadow-card);
  }
  p {
    margin: 0;
    font-size: 13px;
    line-height: 1.75;
    color: var(--vs-ink);
  }
  p + p {
    margin-top: 8px;
  }
  .row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 6px;
  }
</style>
```

## Variants

Demo variants: `In prose`, `Tones`.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `tone` | `"neutral" \| "green" \| "orange" \| "red" \| "accent"` | `"neutral"` | Tint, ring and text color. |

## Used by

[Recommendation Card](https://viewership.ai/ui/components/recommendation-card.md)

## Source

### `src/components/viewership/value-pill/ValuePill.astro`

```astro
---
/**
 * ValuePill: inline badge that sets a plain value off from running text.
 *
 * Ported from Beautiful UI `components/atoms/ValuePill.tsx`
 * (MIT, © 2026 Shane Levine). Softer than a StatusPill (no dot) and not a
 * mono token (see Chip).
 *
 * @example
 * with a CTR of <ValuePill tone="green">4.1%</ValuePill>
 */
import type { HTMLAttributes } from "astro/types";

type Tone = "neutral" | "green" | "orange" | "red" | "accent";

type Props = HTMLAttributes<"span"> & {
  tone?: Tone;
};

const { tone = "neutral", class: className, ...rest } = Astro.props;
---

<span class:list={["vs-value-pill", `vs-value-pill--${tone}`, className]} {...rest}><slot /></span>

<style>
  .vs-value-pill {
    display: inline-flex;
    align-items: center;
    margin: 0 2px;
    padding: 0 6px;
    border-radius: var(--vs-radius-pill);
    font-size: 12px;
    font-weight: 500;
    vertical-align: middle;
  }
  .vs-value-pill--neutral {
    background: var(--vs-field);
    color: var(--vs-ink-2);
    box-shadow: var(--vs-shadow-hairline);
  }
  .vs-value-pill--green {
    background: var(--vs-green-tint);
    color: var(--vs-green);
    box-shadow: 0 0 0 1px color-mix(in oklch, var(--vs-green) 28%, transparent);
  }
  .vs-value-pill--orange {
    background: var(--vs-orange-tint);
    color: var(--vs-orange);
    box-shadow: 0 0 0 1px color-mix(in oklch, var(--vs-orange) 28%, transparent);
  }
  .vs-value-pill--red {
    background: var(--vs-red-tint);
    color: var(--vs-red);
    box-shadow: 0 0 0 1px color-mix(in oklch, var(--vs-red) 28%, transparent);
  }
  .vs-value-pill--accent {
    background: var(--vs-accent-tint);
    color: var(--vs-accent-ink);
    box-shadow: 0 0 0 1px color-mix(in oklch, var(--vs-accent) 28%, transparent);
  }
  @media (forced-colors: active) {
    .vs-value-pill {
      outline: 1px solid CanvasText;
    }
  }
</style>
```
