Skip to content
LuoForge/Tungsten
Components/Card·

Card

since v0.1.0

Card — surface primitive for grouped content.

Hairline-only depth: variants differ by border + tinted background, never by shadow.

Variants:

  • default — flat surface tile, 1px hairline
  • elevated — same hairline, lifted onto canvas-soft bg (matches the design spec's .card.elevated)
  • active — surface tile with brand accent border only (single-element rule — no fill tint)
  • bezel — static glass tile; provides its own surface (40% surface tint + backdrop-blur).

Compare with vanilla Card, which expects a solid surface.

  • inverse-ink — dark ink surface with cream text; use once per page for the primary spotlight card.
  • success / warning / error — tinted surface for status content.

Forwards ref to the root <div>.

Install

Add the package and import the component.

pnpm add @hey-mike/tungsten
pnpm add @hey-mike/tungsten
import { Card } from '@hey-mike/tungsten';
import { Card } from '@hey-mike/tungsten';

Preview

Same fixtures used by the visual-regression suite.

Usage

apps/docs/app/snapshots/card/page.tsx

import { Card } from '@hey-mike/tungsten';
import { VariantGrid } from '../_components/VariantGrid';
import { HeroSpecimen } from '../_components/HeroSpecimen';

function CardBody({
  label,
  title,
  body,
}: {
  label: string;
  title: string;
  body: string;
}) {
  return (
    <div className="space-y-1.5">
      <p className="text-ink-3 font-mono text-2xs uppercase tracking-label">{label}</p>
      <p className="text-ink-1 text-sm font-medium">{title}</p>
      <p className="text-ink-2 text-sm leading-relaxed">{body}</p>
    </div>
  );
}

export default function CardSnapshot() {
  return (
    <VariantGrid
      title="Card"
      hero={
        <HeroSpecimen>
          <Card>
            <div className="space-y-1">
              <p className="text-ink-3 tracking-label font-mono text-2xs uppercase">evaluation</p>
              <p className="text-ink-1 text-sm font-medium">Response Quality</p>
              <p className="text-ink-2 text-xs leading-relaxed">Clarity, depth, correctness.</p>
            </div>
          </Card>
        </HeroSpecimen>
      }
      variants={[
        {
          label: 'default',
          node: (
            <Card>
              <CardBody label="evaluation · run 42" title="Response Quality" body="Evaluates clarity, depth, and factual correctness of model output." />
            </Card>
          ),
        },
        {
          label: 'elevated',
          node: (
            <Card variant="elevated">
              <CardBody label="evaluation · run 42" title="Response Quality" body="Evaluates clarity, depth, and factual correctness of model output." />
            </Card>
          ),
        },
        {
          label: 'active',
          node: (
            <Card variant="active">
              <CardBody label="selected" title="Response Quality" body="Evaluates clarity, depth, and factual correctness of model output." />
            </Card>
          ),
        },
        {
          label: 'inverse-ink',
          node: (
            <Card variant="inverse-ink">
              {/* text-ink-* would be dark-on-dark; inherit text-on-ink from card and use opacity tiers */}
              <div className="space-y-1.5">
                <p className="font-mono text-2xs uppercase tracking-label opacity-60">spotlight</p>
                <p className="text-sm font-medium">Response Quality</p>
                <p className="text-sm leading-relaxed opacity-75">Evaluates clarity, depth, and factual correctness of model output.</p>
              </div>
            </Card>
          ),
        },
        {
          label: 'success',
          node: (
            <Card variant="success">
              <CardBody label="passed · 3 min ago" title="All checks passed" body="Every assertion in the evaluation suite passed on this run." />
            </Card>
          ),
        },
        {
          label: 'warning',
          node: (
            <Card variant="warning">
              <CardBody label="warning · 3 min ago" title="Partial match" body="3 of 7 assertions passed. Review edge cases before promoting." />
            </Card>
          ),
        },
        {
          label: 'error',
          node: (
            <Card variant="error">
              <CardBody label="failed · 3 min ago" title="Evaluation failed" body="The model response did not meet the required quality threshold." />
            </Card>
          ),
        },
        {
          label: 'bezel',
          node: (
            <Card bezel>
              <CardBody label="glass surface" title="Response Quality" body="Evaluates clarity, depth, and factual correctness of model output." />
            </Card>
          ),
        },
      ]}
    />
  );
}
import { Card } from '@hey-mike/tungsten';
import { VariantGrid } from '../_components/VariantGrid';
import { HeroSpecimen } from '../_components/HeroSpecimen';

function CardBody({
  label,
  title,
  body,
}: {
  label: string;
  title: string;
  body: string;
}) {
  return (
    <div className="space-y-1.5">
      <p className="text-ink-3 font-mono text-2xs uppercase tracking-label">{label}</p>
      <p className="text-ink-1 text-sm font-medium">{title}</p>
      <p className="text-ink-2 text-sm leading-relaxed">{body}</p>
    </div>
  );
}

export default function CardSnapshot() {
  return (
    <VariantGrid
      title="Card"
      hero={
        <HeroSpecimen>
          <Card>
            <div className="space-y-1">
              <p className="text-ink-3 tracking-label font-mono text-2xs uppercase">evaluation</p>
              <p className="text-ink-1 text-sm font-medium">Response Quality</p>
              <p className="text-ink-2 text-xs leading-relaxed">Clarity, depth, correctness.</p>
            </div>
          </Card>
        </HeroSpecimen>
      }
      variants={[
        {
          label: 'default',
          node: (
            <Card>
              <CardBody label="evaluation · run 42" title="Response Quality" body="Evaluates clarity, depth, and factual correctness of model output." />
            </Card>
          ),
        },
        {
          label: 'elevated',
          node: (
            <Card variant="elevated">
              <CardBody label="evaluation · run 42" title="Response Quality" body="Evaluates clarity, depth, and factual correctness of model output." />
            </Card>
          ),
        },
        {
          label: 'active',
          node: (
            <Card variant="active">
              <CardBody label="selected" title="Response Quality" body="Evaluates clarity, depth, and factual correctness of model output." />
            </Card>
          ),
        },
        {
          label: 'inverse-ink',
          node: (
            <Card variant="inverse-ink">
              {/* text-ink-* would be dark-on-dark; inherit text-on-ink from card and use opacity tiers */}
              <div className="space-y-1.5">
                <p className="font-mono text-2xs uppercase tracking-label opacity-60">spotlight</p>
                <p className="text-sm font-medium">Response Quality</p>
                <p className="text-sm leading-relaxed opacity-75">Evaluates clarity, depth, and factual correctness of model output.</p>
              </div>
            </Card>
          ),
        },
        {
          label: 'success',
          node: (
            <Card variant="success">
              <CardBody label="passed · 3 min ago" title="All checks passed" body="Every assertion in the evaluation suite passed on this run." />
            </Card>
          ),
        },
        {
          label: 'warning',
          node: (
            <Card variant="warning">
              <CardBody label="warning · 3 min ago" title="Partial match" body="3 of 7 assertions passed. Review edge cases before promoting." />
            </Card>
          ),
        },
        {
          label: 'error',
          node: (
            <Card variant="error">
              <CardBody label="failed · 3 min ago" title="Evaluation failed" body="The model response did not meet the required quality threshold." />
            </Card>
          ),
        },
        {
          label: 'bezel',
          node: (
            <Card bezel>
              <CardBody label="glass surface" title="Response Quality" body="Evaluates clarity, depth, and factual correctness of model output." />
            </Card>
          ),
        },
      ]}
    />
  );
}

Props

Surface specific to <Card />.

PropTypeDefaultDescription
padding"none" | "sm" | "md" | "lg"md
variant"default" | "elevated" | "active" | "inverse-ink" | "success" | "warning" | "error"default
bezelbooleanfalseRender the bezel/edge-lit treatment. When true, variant is ignored — the bezel design intentionally has only one look.

Used in recipes

Compositions from the /recipes reference that use this component.

Source