Skip to content
LuoForge/Tungsten
← All recipes

Action card

Stack of numbered next-action cards on /results. Four semantic variants (warn/info/success/error) signal urgency and category. Numbered prefix anchors scan order.

Preview

Source

apps/docs/app/recipes/action-card/recipe.tsx
export default function ActionCardRecipe() {
  return (
    <div className="border-stroke bg-surface-2 flex flex-col gap-2.5 rounded-2xl border p-5">
      {[
        {
          num: '01',
          title: 'Re-attempt Scale Estimation today',
          sub: 'Hot now — your score dipped 0.4',
          bg: 'var(--color-warning-surface)',
          border: 'var(--color-warning-border)',
          numBg: 'oklch(60% 0.15 85 / 0.2)',
          numColor: 'var(--color-warning-text)',
          arrowColor: 'var(--color-warning-text)',
        },
        {
          num: '02',
          title: 'Read: capacity planning checklist',
          sub: '4 min · primer',
          bg: 'var(--bg-surface)',
          border: 'var(--color-border)',
          numBg: 'var(--color-info-surface)',
          numColor: 'var(--color-info-text)',
          arrowColor: 'var(--color-info-text)',
        },
        {
          num: '03',
          title: 'Schedule a Mock for Friday',
          sub: 'Aim for ≥ 70% average',
          bg: 'var(--bg-surface)',
          border: 'var(--color-border)',
          numBg: 'var(--color-success-surface)',
          numColor: 'var(--color-success-text)',
          arrowColor: 'var(--color-success-text)',
        },
        {
          num: '04',
          title: 'Block: Server unreachable',
          sub: 'Retry the evaluation',
          bg: 'var(--color-error-surface)',
          border: 'var(--color-error-border)',
          numBg: 'var(--color-error-surface)',
          numColor: 'var(--color-error-border)',
          arrowColor: 'var(--color-error-text)',
        },
      ].map((card) => (
        <button
          key={card.num}
          type="button"
          className="flex w-full cursor-pointer items-center gap-3.5 rounded-xl border px-4 py-4 text-left"
          style={{ background: card.bg, borderColor: card.border }}
        >
          <span
            className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg font-mono text-xs font-bold"
            style={{ background: card.numBg, color: card.numColor }}
          >
            {card.num}
          </span>
          <span className="flex flex-1 flex-col gap-0.5">
            <span className="text-ink-1 text-sm font-semibold">{card.title}</span>
            <span className="text-ink-3 text-xs">{card.sub}</span>
          </span>
          <span className="shrink-0 text-base" style={{ color: card.arrowColor }}>

          </span>
        </button>
      ))}
    </div>
  );
}
export default function ActionCardRecipe() {
  return (
    <div className="border-stroke bg-surface-2 flex flex-col gap-2.5 rounded-2xl border p-5">
      {[
        {
          num: '01',
          title: 'Re-attempt Scale Estimation today',
          sub: 'Hot now — your score dipped 0.4',
          bg: 'var(--color-warning-surface)',
          border: 'var(--color-warning-border)',
          numBg: 'oklch(60% 0.15 85 / 0.2)',
          numColor: 'var(--color-warning-text)',
          arrowColor: 'var(--color-warning-text)',
        },
        {
          num: '02',
          title: 'Read: capacity planning checklist',
          sub: '4 min · primer',
          bg: 'var(--bg-surface)',
          border: 'var(--color-border)',
          numBg: 'var(--color-info-surface)',
          numColor: 'var(--color-info-text)',
          arrowColor: 'var(--color-info-text)',
        },
        {
          num: '03',
          title: 'Schedule a Mock for Friday',
          sub: 'Aim for ≥ 70% average',
          bg: 'var(--bg-surface)',
          border: 'var(--color-border)',
          numBg: 'var(--color-success-surface)',
          numColor: 'var(--color-success-text)',
          arrowColor: 'var(--color-success-text)',
        },
        {
          num: '04',
          title: 'Block: Server unreachable',
          sub: 'Retry the evaluation',
          bg: 'var(--color-error-surface)',
          border: 'var(--color-error-border)',
          numBg: 'var(--color-error-surface)',
          numColor: 'var(--color-error-border)',
          arrowColor: 'var(--color-error-text)',
        },
      ].map((card) => (
        <button
          key={card.num}
          type="button"
          className="flex w-full cursor-pointer items-center gap-3.5 rounded-xl border px-4 py-4 text-left"
          style={{ background: card.bg, borderColor: card.border }}
        >
          <span
            className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg font-mono text-xs font-bold"
            style={{ background: card.numBg, color: card.numColor }}
          >
            {card.num}
          </span>
          <span className="flex flex-1 flex-col gap-0.5">
            <span className="text-ink-1 text-sm font-semibold">{card.title}</span>
            <span className="text-ink-3 text-xs">{card.sub}</span>
          </span>
          <span className="shrink-0 text-base" style={{ color: card.arrowColor }}>

          </span>
        </button>
      ))}
    </div>
  );
}