Skip to content
LuoForge/Tungsten
← All recipes

Skill radar

The product’s signature 8-axis data visualization. Ember Orange carries the data shape; gray category rings mark skill tier; dashed brand ring is the 70% readiness target. Tier-colored numeric values render outside the polygon. Skill identity lives in the axis label, never the hue.

Preview

Skill radar · you vs. 70% targetBRAND · DATA  ·  GRAY · CATEGORY
0.7 TARGETREQUIREMENTSSCALE EST.API DESIGNHLDBOTTLENECKSSCALINGTRADE-OFFSCOMMS78%44%62%80%56%70%76%64%
FoundationStructureDepthDelivery70% Target

Source

apps/docs/app/recipes/radar/recipe.tsx
const AXES = [
  { x: 0, y: -94, l: 75 },
  { x: 37.5, y: -37.5, l: 75 },
  { x: 74, y: 0, l: 60 },
  { x: 67.9, y: 67.9, l: 60 },
  { x: 0, y: 67, l: 45 },
  { x: -59.4, y: 59.4, l: 45 },
  { x: -91, y: 0, l: 35 },
  { x: -54.4, y: -54.4, l: 35 },
];

const CATEGORIES = [
  { label: 'Foundation', l: 75 },
  { label: 'Structure', l: 60 },
  { label: 'Depth', l: 45 },
  { label: 'Delivery', l: 35 },
];

export default function RadarRecipe() {
  return (
    <div className="border-stroke bg-surface-2 rounded-2xl border p-6">
      <header className="mb-2 flex items-baseline justify-between">
        <span className="tracking-label text-ink-3 text-label font-mono font-bold uppercase">
          Skill radar · you vs. 70% target
        </span>
        <span className="text-ink-3 font-mono text-3xs tracking-[0.06em] uppercase">
          BRAND · DATA &nbsp;·&nbsp; GRAY · CATEGORY
        </span>
      </header>

      <svg viewBox="0 0 360 320" width="100%" height="280" aria-label="Skill radar chart">
        <g transform="translate(180,158)">
          {/* concentric category rings */}
          <g fill="none" stroke="var(--chart-gridline)">
            <circle r="120" strokeWidth="1" opacity="0.55" />
            <circle r="90" strokeWidth="1" opacity="0.35" />
            <circle r="60" strokeWidth="1" opacity="0.25" />
            <circle r="30" strokeWidth="1" opacity="0.18" />
          </g>

          {/* 8 axis spokes */}
          <g stroke="var(--text-ink-3)" strokeWidth="1" opacity="0.18">
            <line x1="0" y1="0" x2="0" y2="-120" />
            <line x1="0" y1="0" x2="84.85" y2="-84.85" />
            <line x1="0" y1="0" x2="120" y2="0" />
            <line x1="0" y1="0" x2="84.85" y2="84.85" />
            <line x1="0" y1="0" x2="0" y2="120" />
            <line x1="0" y1="0" x2="-84.85" y2="84.85" />
            <line x1="0" y1="0" x2="-120" y2="0" />
            <line x1="0" y1="0" x2="-84.85" y2="-84.85" />
          </g>

          {/* 0.7 readiness target ring */}
          <circle
            r="84"
            fill="none"
            stroke="var(--color-brand)"
            strokeWidth="1.25"
            strokeDasharray="4 4"
            opacity="0.7"
          />
          <text
            x="0"
            y="-87"
            textAnchor="middle"
            fontFamily="ui-monospace, monospace"
            style={{ fontSize: 'var(--text-3xs)' }}
            fontWeight="700"
            fill="var(--color-brand)"
            letterSpacing="0.08em"
            opacity="0.85"
          >
            0.7 TARGET
          </text>

          {/* data polygon */}
          <polygon
            points="0,-94 37.5,-37.5 74,0 67.9,67.9 0,67 -59.4,59.4 -91,0 -54.4,-54.4"
            fill="var(--color-brand-overlay-15)"
            stroke="var(--color-brand)"
            strokeWidth="1.75"
          />

          {/* per-axis nodes: gray category ring + brand-fill dot */}
          {AXES.map(({ x, y, l }, i) => (
            <g key={i}>
              <circle
                cx={x}
                cy={y}
                r="6.5"
                fill="var(--bg-surface-2)"
                stroke={`oklch(${l}% 0 0)`}
                strokeWidth="1.6"
              />
              <circle cx={x} cy={y} r="3.2" fill="var(--color-brand)" />
            </g>
          ))}

          {/* axis labels */}
          <g
            fontFamily="ui-monospace, monospace"
            style={{ fontSize: 'var(--text-3xs)' }}
            fontWeight="700"
            letterSpacing="0.08em"
            fill="var(--text-ink-2)"
          >
            <text x="0" y="-138" textAnchor="middle">REQUIREMENTS</text>
            <text x="98" y="-98" textAnchor="middle">SCALE EST.</text>
            <text x="138" y="3" textAnchor="start">API DESIGN</text>
            <text x="98" y="105" textAnchor="middle">HLD</text>
            <text x="0" y="142" textAnchor="middle">BOTTLENECKS</text>
            <text x="-98" y="105" textAnchor="middle">SCALING</text>
            <text x="-138" y="3" textAnchor="end">TRADE-OFFS</text>
            <text x="-98" y="-98" textAnchor="middle">COMMS</text>
          </g>

          {/* tier-colored score values outside the polygon */}
          <g fontFamily="ui-monospace, monospace" style={{ fontSize: 'var(--text-3xs)' }} fontWeight="700">
            <text x="0" y="-126" textAnchor="middle" fill="var(--color-score-passing-text)">78%</text>
            <text x="98" y="-86" textAnchor="middle" fill="var(--color-score-below-text)">44%</text>
            <text x="138" y="15" textAnchor="start" fill="var(--color-score-approaching-text)">62%</text>
            <text x="98" y="117" textAnchor="middle" fill="var(--color-score-passing-text)">80%</text>
            <text x="0" y="154" textAnchor="middle" fill="var(--color-score-below-text)">56%</text>
            <text x="-98" y="117" textAnchor="middle" fill="var(--color-score-passing-text)">70%</text>
            <text x="-138" y="15" textAnchor="end" fill="var(--color-score-passing-text)">76%</text>
            <text x="-98" y="-86" textAnchor="middle" fill="var(--color-score-approaching-text)">64%</text>
          </g>
        </g>
      </svg>

      {/* category legend */}
      <div className="border-stroke mt-4 flex flex-wrap items-center gap-4 border-t border-dashed pt-4">
        {CATEGORIES.map(({ label, l }) => (
          <span
            key={label}
            className="tracking-label text-ink-3 inline-flex items-center gap-1.5 font-mono text-3xs font-bold uppercase"
          >
            <span
              aria-hidden
              className="bg-surface-2 inline-block h-2 w-2 rounded-full"
              style={{ border: `1.5px solid oklch(${l}% 0 0)` }}
            />
            {label}
          </span>
        ))}
        <span className="tracking-label text-brand ml-auto inline-flex items-center gap-1.5 font-mono text-3xs font-bold uppercase">
          <span
            aria-hidden
            className="inline-block h-0 w-3.5"
            style={{ borderTop: '1.25px dashed var(--color-brand)' }}
          />
          70% Target
        </span>
      </div>
    </div>
  );
}
const AXES = [
  { x: 0, y: -94, l: 75 },
  { x: 37.5, y: -37.5, l: 75 },
  { x: 74, y: 0, l: 60 },
  { x: 67.9, y: 67.9, l: 60 },
  { x: 0, y: 67, l: 45 },
  { x: -59.4, y: 59.4, l: 45 },
  { x: -91, y: 0, l: 35 },
  { x: -54.4, y: -54.4, l: 35 },
];

const CATEGORIES = [
  { label: 'Foundation', l: 75 },
  { label: 'Structure', l: 60 },
  { label: 'Depth', l: 45 },
  { label: 'Delivery', l: 35 },
];

export default function RadarRecipe() {
  return (
    <div className="border-stroke bg-surface-2 rounded-2xl border p-6">
      <header className="mb-2 flex items-baseline justify-between">
        <span className="tracking-label text-ink-3 text-label font-mono font-bold uppercase">
          Skill radar · you vs. 70% target
        </span>
        <span className="text-ink-3 font-mono text-3xs tracking-[0.06em] uppercase">
          BRAND · DATA &nbsp;·&nbsp; GRAY · CATEGORY
        </span>
      </header>

      <svg viewBox="0 0 360 320" width="100%" height="280" aria-label="Skill radar chart">
        <g transform="translate(180,158)">
          {/* concentric category rings */}
          <g fill="none" stroke="var(--chart-gridline)">
            <circle r="120" strokeWidth="1" opacity="0.55" />
            <circle r="90" strokeWidth="1" opacity="0.35" />
            <circle r="60" strokeWidth="1" opacity="0.25" />
            <circle r="30" strokeWidth="1" opacity="0.18" />
          </g>

          {/* 8 axis spokes */}
          <g stroke="var(--text-ink-3)" strokeWidth="1" opacity="0.18">
            <line x1="0" y1="0" x2="0" y2="-120" />
            <line x1="0" y1="0" x2="84.85" y2="-84.85" />
            <line x1="0" y1="0" x2="120" y2="0" />
            <line x1="0" y1="0" x2="84.85" y2="84.85" />
            <line x1="0" y1="0" x2="0" y2="120" />
            <line x1="0" y1="0" x2="-84.85" y2="84.85" />
            <line x1="0" y1="0" x2="-120" y2="0" />
            <line x1="0" y1="0" x2="-84.85" y2="-84.85" />
          </g>

          {/* 0.7 readiness target ring */}
          <circle
            r="84"
            fill="none"
            stroke="var(--color-brand)"
            strokeWidth="1.25"
            strokeDasharray="4 4"
            opacity="0.7"
          />
          <text
            x="0"
            y="-87"
            textAnchor="middle"
            fontFamily="ui-monospace, monospace"
            style={{ fontSize: 'var(--text-3xs)' }}
            fontWeight="700"
            fill="var(--color-brand)"
            letterSpacing="0.08em"
            opacity="0.85"
          >
            0.7 TARGET
          </text>

          {/* data polygon */}
          <polygon
            points="0,-94 37.5,-37.5 74,0 67.9,67.9 0,67 -59.4,59.4 -91,0 -54.4,-54.4"
            fill="var(--color-brand-overlay-15)"
            stroke="var(--color-brand)"
            strokeWidth="1.75"
          />

          {/* per-axis nodes: gray category ring + brand-fill dot */}
          {AXES.map(({ x, y, l }, i) => (
            <g key={i}>
              <circle
                cx={x}
                cy={y}
                r="6.5"
                fill="var(--bg-surface-2)"
                stroke={`oklch(${l}% 0 0)`}
                strokeWidth="1.6"
              />
              <circle cx={x} cy={y} r="3.2" fill="var(--color-brand)" />
            </g>
          ))}

          {/* axis labels */}
          <g
            fontFamily="ui-monospace, monospace"
            style={{ fontSize: 'var(--text-3xs)' }}
            fontWeight="700"
            letterSpacing="0.08em"
            fill="var(--text-ink-2)"
          >
            <text x="0" y="-138" textAnchor="middle">REQUIREMENTS</text>
            <text x="98" y="-98" textAnchor="middle">SCALE EST.</text>
            <text x="138" y="3" textAnchor="start">API DESIGN</text>
            <text x="98" y="105" textAnchor="middle">HLD</text>
            <text x="0" y="142" textAnchor="middle">BOTTLENECKS</text>
            <text x="-98" y="105" textAnchor="middle">SCALING</text>
            <text x="-138" y="3" textAnchor="end">TRADE-OFFS</text>
            <text x="-98" y="-98" textAnchor="middle">COMMS</text>
          </g>

          {/* tier-colored score values outside the polygon */}
          <g fontFamily="ui-monospace, monospace" style={{ fontSize: 'var(--text-3xs)' }} fontWeight="700">
            <text x="0" y="-126" textAnchor="middle" fill="var(--color-score-passing-text)">78%</text>
            <text x="98" y="-86" textAnchor="middle" fill="var(--color-score-below-text)">44%</text>
            <text x="138" y="15" textAnchor="start" fill="var(--color-score-approaching-text)">62%</text>
            <text x="98" y="117" textAnchor="middle" fill="var(--color-score-passing-text)">80%</text>
            <text x="0" y="154" textAnchor="middle" fill="var(--color-score-below-text)">56%</text>
            <text x="-98" y="117" textAnchor="middle" fill="var(--color-score-passing-text)">70%</text>
            <text x="-138" y="15" textAnchor="end" fill="var(--color-score-passing-text)">76%</text>
            <text x="-98" y="-86" textAnchor="middle" fill="var(--color-score-approaching-text)">64%</text>
          </g>
        </g>
      </svg>

      {/* category legend */}
      <div className="border-stroke mt-4 flex flex-wrap items-center gap-4 border-t border-dashed pt-4">
        {CATEGORIES.map(({ label, l }) => (
          <span
            key={label}
            className="tracking-label text-ink-3 inline-flex items-center gap-1.5 font-mono text-3xs font-bold uppercase"
          >
            <span
              aria-hidden
              className="bg-surface-2 inline-block h-2 w-2 rounded-full"
              style={{ border: `1.5px solid oklch(${l}% 0 0)` }}
            />
            {label}
          </span>
        ))}
        <span className="tracking-label text-brand ml-auto inline-flex items-center gap-1.5 font-mono text-3xs font-bold uppercase">
          <span
            aria-hidden
            className="inline-block h-0 w-3.5"
            style={{ borderTop: '1.25px dashed var(--color-brand)' }}
          />
          70% Target
        </span>
      </div>
    </div>
  );
}