import { AFFINITY_PROGRESS_MARKERS, AFFINITY_PROGRESS_MAX, AFFINITY_PROGRESS_MIN, getAffinityLevelMeta, } from '../data/affinityLevels'; type AffinityProgressMarker = (typeof AFFINITY_PROGRESS_MARKERS)[number]; function clamp(value: number, min: number, max: number) { return Math.min(max, Math.max(min, value)); } function getNextAffinityMarker(affinity: number) { const currentLevel = getAffinityLevelMeta(affinity); if (currentLevel.nextAffinity == null) return null; return ( AFFINITY_PROGRESS_MARKERS.find( (marker) => marker.value === currentLevel.nextAffinity, ) ?? null ); } function getAffinityProgressRatio(value: number) { return clamp( (value - AFFINITY_PROGRESS_MIN) / (AFFINITY_PROGRESS_MAX - AFFINITY_PROGRESS_MIN), 0, 1, ); } function getAnchorTransform(ratio: number) { if (ratio <= 0.02) return 'translateX(0)'; if (ratio >= 0.98) return 'translateX(-100%)'; return 'translateX(-50%)'; } function isMarkerReached(marker: AffinityProgressMarker, affinity: number) { if (marker.value < 0) { return affinity < 0; } return affinity >= marker.value; } export function AffinityStatusCard({ affinity }: { affinity: number }) { const currentLevel = getAffinityLevelMeta(affinity); const nextLevel = getNextAffinityMarker(affinity); const currentRatio = getAffinityProgressRatio(affinity); const zeroRatio = getAffinityProgressRatio(0); const activeMarkerValue = currentLevel.minAffinity <= AFFINITY_PROGRESS_MIN ? AFFINITY_PROGRESS_MIN : currentLevel.minAffinity; const fillLeftRatio = Math.min(currentRatio, zeroRatio); const fillWidthRatio = Math.abs(currentRatio - zeroRatio); const fillWidthPercent = fillWidthRatio > 0 ? `${Math.max(fillWidthRatio * 100, 1)}%` : '0%'; const currentPointerTone = affinity < 0 ? 'border-rose-100/90 bg-rose-300 shadow-[0_0_16px_rgba(251,113,133,0.45)]' : 'border-sky-50/90 bg-sky-300 shadow-[0_0_18px_rgba(125,211,252,0.35)]'; const fillGradient = affinity < 0 ? 'linear-gradient(90deg, rgba(251,113,133,0.92) 0%, rgba(253,164,175,0.98) 100%)' : 'linear-gradient(90deg, rgba(125,211,252,0.92) 0%, rgba(251,191,36,0.94) 60%, rgba(251,113,133,0.96) 100%)'; return (
{currentLevel.description}