← back to Stayclaim

src/components/ConfidenceDot.tsx

41 lines

/**
 * ConfidenceDot — 3-dot scale + anchor-window caption.
 * Always paired with an anchor window; never renders bare.
 *
 *   0.0–0.39  low      (1 dot)
 *   0.40–0.74 medium   (2 dots)
 *   0.75–1.00 high     (3 dots)
 *
 * Constraint source: docs/rent-multiplier-1978-1984.md — every projected number
 * carries its anchor window + confidence dot.
 */

export function ConfidenceDot({
  confidence,
  anchorWindow,
  className = '',
}: {
  confidence: number;
  anchorWindow: string;
  className?: string;
}) {
  const filled = confidence >= 0.75 ? 3 : confidence >= 0.4 ? 2 : 1;
  const tier = confidence >= 0.75 ? 'High' : confidence >= 0.4 ? 'Medium' : 'Low';
  return (
    <span
      className={`inline-flex items-center gap-1.5 text-[10px] uppercase tracking-wider text-ink/60 ${className}`}
      title={`Confidence: ${tier} (${confidence.toFixed(2)}) · Anchor: ${anchorWindow}`}
    >
      <span className="inline-flex gap-0.5" aria-label={`confidence ${tier.toLowerCase()}`}>
        {[0, 1, 2].map(i => (
          <span
            key={i}
            className={`h-1.5 w-1.5 rounded-full ${i < filled ? 'bg-moss' : 'bg-ink/15'}`}
          />
        ))}
      </span>
      <span className="font-mono normal-case tracking-normal">{anchorWindow}</span>
    </span>
  );
}