import React from 'react'; import styled from '@emotion/styled'; import { colors } from '../../theme'; import { getVerdictColor, getHarmColor, getConfidenceColor, getReliabilityColor, getStanceColor, getClaimVerdictColor, getContentUrgencyColor, } from '../../utils/colors'; // Typography constants (matching theme) const fontSize = { small: '14px', medium: '16px', large: '18px', xlarge: '20px', }; const fontWeight = { medium: 500, semiBold: 600, bold: 700, }; // Aggregator-specific types (Universal Analyzer v3) interface SignalBreakdown { signal_name: string; raw_value?: any; transformed_value: number; weight: number; weighted_contribution: number; is_default?: boolean; default_reason?: string; } interface AnalysisQuality { signals_computed: number; signals_defaulted: number; critical_signals_defaulted?: string[]; reliability: 'HIGH' | 'MEDIUM' | 'LOW'; reliability_reason: string; } interface AggregatorOutput { score: number; category: string; category_description: string; breakdown?: SignalBreakdown[]; signals_used: number; signals_missing: number; harm_level?: string; analysis_quality?: AnalysisQuality; } // ==================== V3 EXTENDED TYPES ==================== // Individual source evaluation from source_evaluation node interface SourceEvaluationItem { url: string; base_tier: number; effective_tier: number; stance: 'supports' | 'contradicts' | 'neutral' | 'unrelated'; stance_strength: number; domain_authority?: 'expert' | 'general' | 'unknown'; recency_relevance?: 'current' | 'dated' | 'historical'; circular_sourcing_detected?: boolean; circular_chain?: string[]; is_tier5_primary?: boolean; tier5_primary_type?: string; tier_reasoning?: string; primary_source_linked?: boolean; } // Aggregated stance metrics interface StanceSummary { supporting_sources: number; contradicting_sources: number; neutral_sources: number; unrelated_sources?: number; weighted_stance_score: number; has_relevant_evidence: boolean; } // Source evaluation output from source_evaluation node interface SourceEvaluationOutput { source_evaluations: SourceEvaluationItem[]; stance_summary: StanceSummary; } // Individual claim verdict from verdict node interface ClaimVerdict { claim_id?: number; claim_text: string; verdict: string; verdict_score: number; verdict_explanation: string; evidence_used?: string[]; evidence_against?: string[]; epistemic_assessment?: { evidence_basis?: string; claim_nature?: string; source_attribution?: string; temporal_status?: string; recommended_action?: string; assessment_rationale?: string; }; } // Verdict output from verdict node interface VerdictOutput { claim_verdicts: ClaimVerdict[]; overall_assessment?: { epistemic_assessment?: { evidence_basis?: string; temporal_status?: string; }; }; manipulation_indicators?: string[]; } // Triage output from triage node interface TriageOutput { content_type: 'news_article' | 'social_post' | 'image_text' | 'video' | 'audio' | 'mixed'; urgency: 'breaking' | 'viral' | 'routine' | 'historical'; primary_claims?: string[]; manipulation_detected?: boolean; manipulation_indicators?: string[]; recommended_pipeline?: string; } // Claim extraction output interface ClaimExtractionOutput { final_claims?: Array<{ claim_text?: string; claim_type?: string; ambiguity_flags?: string[]; }>; extraction_quality?: 'high' | 'medium' | 'low'; } interface AnalysisData { verdict: string; confidence: number; explanation: string; harm_level?: string; primary_category?: string; aggregator?: AggregatorOutput; // v3 aggregator data for enhanced display // NEW: v3 extended pipeline outputs source_evaluation?: SourceEvaluationOutput; // Sources evaluated with stance analysis verdict_data?: VerdictOutput; // Per-claim verdicts with epistemic assessment triage?: TriageOutput; // Content type, urgency, manipulation detection claim_extraction?: ClaimExtractionOutput; // Extracted claims with metadata sub_categories?: string[]; key_claims?: Array<{ claim: string; claim_type?: string; verified?: string | boolean; verification_method?: string; sources?: string[]; harm_potential?: string; notes?: string; }>; manipulation_techniques?: string[]; emotional_triggers?: { detected: boolean; types: string[]; severity: string; }; media_authenticity?: { type: string; assessment: string; manipulation_type?: string; confidence?: number; }; source_credibility?: string | { assessment: string; indicators?: string[]; trust_score?: number; }; verification?: { web_search_performed: boolean; fact_check_sites_consulted?: string[]; verification_urls?: string[]; limitations?: string[]; }; viral_risk?: { score: number; level: string; factors?: string[]; assessment?: string; }; recommendations?: { action: string; urgency: string; reason?: string; suggested_interventions?: string[]; }; detailed_analysis?: { content_type?: string; tone?: string; writing_quality?: string; context_analysis?: string; similar_claims?: string; }; metadata?: { pipeline_type?: string; language_detected?: string; }; confidence_factors?: string[]; temporal_context?: string; transcription?: string; } interface AnalysisResultsProps { data: AnalysisData; } export const AnalysisResults: React.FC = ({ data }) => { const [showTranscription, setShowTranscription] = React.useState(false); const [showDetailedAnalysis, setShowDetailedAnalysis] = React.useState(false); const [showSourcesEvaluated, setShowSourcesEvaluated] = React.useState(false); const [showClaimVerdicts, setShowClaimVerdicts] = React.useState(false); // Helper for tier labels (not a color function) const getTierLabel = (tier: number): string => { switch (tier) { case 1: return 'Primary Source'; case 2: return 'Major Wire'; case 3: return 'Quality News'; case 4: return 'Secondary'; case 5: return 'Social/Blog'; default: return `Tier ${tier}`; } }; // Check if we have aggregator data for enhanced display const hasAggregator = data.aggregator && 'score' in data.aggregator; const [showSignalBreakdown, setShowSignalBreakdown] = React.useState(false); // Check if we have v3 extended data const hasSourceEvaluation = data.source_evaluation && data.source_evaluation.source_evaluations?.length > 0; const hasClaimVerdicts = data.verdict_data && data.verdict_data.claim_verdicts?.length > 0; const hasTriage = data.triage && data.triage.content_type; return ( {/* Header Section - Verdict & Confidence */} Verdict {data.verdict.replace(/_/g, ' ').toUpperCase()} Confidence {(data.confidence * 100).toFixed(0)}% {data.harm_level && ( Harm Level {data.harm_level?.toUpperCase()} )} {/* Explanation */} Explanation {data.explanation} {/* Category & Type */} {(data.primary_category || data.metadata?.pipeline_type) && ( {data.primary_category && ( {data.primary_category.replace(/_/g, ' ')} )} {data.metadata?.pipeline_type && ( {data.metadata.pipeline_type} )} {data.metadata?.language_detected && ( {data.metadata.language_detected.toUpperCase()} )} )} {/* Triage Badges (v3) - Content Type, Urgency, Manipulation Status */} {hasTriage && ( {data.triage!.content_type.replace(/_/g, ' ')} {data.triage!.urgency} {data.triage!.manipulation_detected !== undefined && ( {data.triage!.manipulation_detected ? 'Manipulation Detected' : 'No Manipulation'} )} )} {/* Analysis Quality Indicator (v3 Aggregator) */} {hasAggregator && data.aggregator?.analysis_quality && ( Analysis Quality {data.aggregator.analysis_quality.reliability} Reliability Signals Computed {data.aggregator.analysis_quality.signals_computed} Signals Defaulted 0}> {data.aggregator.analysis_quality.signals_defaulted} {data.aggregator.analysis_quality.reliability_reason} {data.aggregator.analysis_quality.critical_signals_defaulted && data.aggregator.analysis_quality.critical_signals_defaulted.length > 0 && ( Critical signals used defaults: {data.aggregator.analysis_quality.critical_signals_defaulted.join(', ')} )} )} {/* Sources Evaluated Section (v3) - Collapsible */} {hasSourceEvaluation && ( setShowSourcesEvaluated(!showSourcesEvaluated)}> Sources Evaluated ({data.source_evaluation!.source_evaluations.length} sources) {showSourcesEvaluated ? '▼' : '▶'} {showSourcesEvaluated && ( {data.source_evaluation!.source_evaluations.map((source, idx) => ( {source.url.length > 60 ? source.url.substring(0, 60) + '...' : source.url} Tier {source.effective_tier} ({getTierLabel(source.effective_tier)}) {source.stance} ({(source.stance_strength * 100).toFixed(0)}%) {source.domain_authority && source.domain_authority !== 'unknown' && ( {source.domain_authority} )} {source.recency_relevance && ( {source.recency_relevance} )} {source.circular_sourcing_detected && ( Circular sourcing detected {source.circular_chain && source.circular_chain.length > 0 && ( Chain: {source.circular_chain.join(' → ')} )} )} {source.is_tier5_primary && source.tier5_primary_type && ( Social media IS the primary source ({source.tier5_primary_type}) )} {source.tier_reasoning && ( {source.tier_reasoning} )} ))} )} )} {/* Stance Summary (v3) - Visual Bar */} {hasSourceEvaluation && data.source_evaluation!.stance_summary && ( Evidence Stance Summary {data.source_evaluation!.stance_summary.supporting_sources > 0 && ( Supporting {data.source_evaluation!.stance_summary.supporting_sources} sources )} {data.source_evaluation!.stance_summary.contradicting_sources > 0 && ( Contradicting {data.source_evaluation!.stance_summary.contradicting_sources} sources )} {data.source_evaluation!.stance_summary.neutral_sources > 0 && ( Neutral {data.source_evaluation!.stance_summary.neutral_sources} sources )} {(data.source_evaluation!.stance_summary.unrelated_sources ?? 0) > 0 && ( Unrelated {data.source_evaluation!.stance_summary.unrelated_sources} sources )} Weighted Stance Score: {data.source_evaluation!.stance_summary.weighted_stance_score > 0 ? '+' : ''} {data.source_evaluation!.stance_summary.weighted_stance_score.toFixed(2)} {data.source_evaluation!.stance_summary.weighted_stance_score > 0.5 ? ' (Strongly Supporting)' : data.source_evaluation!.stance_summary.weighted_stance_score > 0.2 ? ' (Leans Supporting)' : data.source_evaluation!.stance_summary.weighted_stance_score > -0.2 ? ' (Neutral/Mixed)' : data.source_evaluation!.stance_summary.weighted_stance_score > -0.5 ? ' (Leans Contradicting)' : ' (Strongly Contradicting)'} {!data.source_evaluation!.stance_summary.has_relevant_evidence && ( No relevant evidence found - claim may be unverifiable )} )} {/* Signal Breakdown (v3 Aggregator) - Collapsible */} {hasAggregator && data.aggregator?.breakdown && data.aggregator.breakdown.length > 0 && ( setShowSignalBreakdown(!showSignalBreakdown)}> Signal Breakdown ({data.aggregator.breakdown.length} signals) {showSignalBreakdown ? '▼' : '▶'} {showSignalBreakdown && ( {data.aggregator.breakdown.map((signal, idx) => ( {signal.signal_name.replace(/_/g, ' ')} Weight: {(signal.weight * 100).toFixed(0)}% {signal.is_default && ( Using Default )} {(signal.transformed_value * 100).toFixed(0)}% Contribution to score: {(signal.weighted_contribution * 100).toFixed(1)}% {signal.default_reason && ( {signal.default_reason} )} ))} Aggregated Score {(data.aggregator.score * 100).toFixed(0)}% )} )} {/* Per-Claim Verdicts (v3) - Enhanced claims with individual verdicts */} {hasClaimVerdicts && ( setShowClaimVerdicts(!showClaimVerdicts)}> Claim Analysis ({data.verdict_data!.claim_verdicts.length} claims) {showClaimVerdicts ? '▼' : '▶'} {showClaimVerdicts && ( {data.verdict_data!.claim_verdicts.map((claim, idx) => ( Claim #{idx + 1} {claim.verdict.replace(/_/g, ' ')} {(claim.verdict_score * 100).toFixed(0)}% confidence "{claim.claim_text}" {claim.verdict_explanation} {/* Evidence For */} {claim.evidence_used && claim.evidence_used.length > 0 && ( Evidence For ({claim.evidence_used.length}): {claim.evidence_used.map((source, sidx) => ( {source.startsWith('http') ? ( {source.length > 50 ? source.substring(0, 50) + '...' : source} ) : ( source )} ))} )} {/* Evidence Against */} {claim.evidence_against && claim.evidence_against.length > 0 && ( Evidence Against ({claim.evidence_against.length}): {claim.evidence_against.map((source, sidx) => ( {source.startsWith('http') ? ( {source.length > 50 ? source.substring(0, 50) + '...' : source} ) : ( source )} ))} )} {/* Epistemic Assessment */} {claim.epistemic_assessment && ( {claim.epistemic_assessment.evidence_basis && ( {claim.epistemic_assessment.evidence_basis.replace(/_/g, ' ')} )} {claim.epistemic_assessment.claim_nature && ( {claim.epistemic_assessment.claim_nature.replace(/_/g, ' ')} )} {claim.epistemic_assessment.temporal_status && ( {claim.epistemic_assessment.temporal_status.replace(/_/g, ' ')} )} {claim.epistemic_assessment.recommended_action && ( Recommended: {claim.epistemic_assessment.recommended_action.replace(/_/g, ' ')} )} )} ))} )} )} {/* Key Claims */} {data.key_claims && data.key_claims.length > 0 && ( Key Claims ({data.key_claims.length}) {data.key_claims.map((claim, idx) => ( #{idx + 1} {claim.verified !== undefined && claim.verified !== 'unknown' && ( {claim.verified === true || claim.verified === 'true' ? 'Verified' : 'False'} )} {claim.harm_potential && claim.harm_potential !== 'none' && ( {claim.harm_potential} )} {claim.claim} {claim.sources && claim.sources.length > 0 && ( Sources: {claim.sources.map((source, sidx) => ( {source} ))} )} {claim.notes && {claim.notes}} ))} )} {/* Manipulation Techniques */} {data.manipulation_techniques && data.manipulation_techniques.length > 0 && ( Manipulation Techniques Detected {data.manipulation_techniques.map((tech, idx) => ( {tech.replace(/_/g, ' ')} ))} )} {/* Emotional Triggers */} {data.emotional_triggers?.detected && ( Emotional Triggers {data.emotional_triggers.severity?.toUpperCase()} severity {data.emotional_triggers.types.map((trigger, idx) => ( {trigger} ))} )} {/* Media Authenticity */} {data.media_authenticity && data.media_authenticity.type !== 'text' && ( Media Authenticity Type: {data.media_authenticity.type?.toUpperCase()} Assessment: {data.media_authenticity.assessment} {data.media_authenticity.manipulation_type && data.media_authenticity.manipulation_type !== 'none' && ( Manipulation: {data.media_authenticity.manipulation_type} )} )} {/* Verification */} {data.verification && ( {data.verification.web_search_performed ? 'Web Verification Performed' : 'Verification Status'} {data.verification.web_search_performed ? ( <> {data.verification.fact_check_sites_consulted && data.verification.fact_check_sites_consulted.length > 0 && ( Fact-Check Sites: {data.verification.fact_check_sites_consulted.map((site, idx) => ( {site} ))} )} {data.verification.verification_urls && data.verification.verification_urls.length > 0 && ( Verification URLs: {data.verification.verification_urls.map((url, idx) => ( {url} ))} )} ) : ( {data.verification.limitations && data.verification.limitations.length > 0 ? data.verification.limitations.join(', ') : 'Basic analysis without web verification'} )} )} {/* Viral Risk */} {data.viral_risk && ( Viral Risk Assessment Risk Level: {data.viral_risk.level?.toUpperCase()} Score: {(data.viral_risk.score * 100).toFixed(0)}% {data.viral_risk.factors && data.viral_risk.factors.length > 0 && ( {data.viral_risk.factors.map((factor, idx) => ( {factor.replace(/_/g, ' ')} ))} )} {data.viral_risk.assessment && ( {data.viral_risk.assessment} )} )} {/* Recommendations */} {data.recommendations && ( Recommendations Action: {data.recommendations.action} Urgency: {data.recommendations.urgency?.toUpperCase()} {data.recommendations.reason && ( {data.recommendations.reason} )} )} {/* Source Credibility */} {data.source_credibility && ( Source Credibility {typeof data.source_credibility === 'string' ? data.source_credibility : data.source_credibility.assessment} )} {/* Temporal Context */} {data.temporal_context && ( Temporal Context {data.temporal_context} )} {/* Confidence Factors */} {data.confidence_factors && data.confidence_factors.length > 0 && ( Confidence Factors ({data.confidence_factors.length}) {data.confidence_factors.map((factor, idx) => ( • {factor} ))} )} {/* Detailed Analysis - Collapsible */} {data.detailed_analysis && ( setShowDetailedAnalysis(!showDetailedAnalysis)}> Detailed Analysis {showDetailedAnalysis ? '▼' : '▶'} {showDetailedAnalysis && ( {data.detailed_analysis.context_analysis && ( Context Analysis: {data.detailed_analysis.context_analysis} )} {data.detailed_analysis.similar_claims && ( Similar Claims: {data.detailed_analysis.similar_claims} )} {data.detailed_analysis.content_type && ( Content Type: {data.detailed_analysis.content_type} )} {data.detailed_analysis.tone && ( Tone: {data.detailed_analysis.tone} )} )} )} {/* Transcription - Collapsible (for Audio/Video) */} {data.transcription && ( setShowTranscription(!showTranscription)}> Transcription ({data.transcription.length} characters) {showTranscription ? '▼' : '▶'} {showTranscription && ( {data.transcription} )} )} ); }; // ==================== STYLED COMPONENTS ==================== const Container = styled.div` display: flex; flex-direction: column; gap: 32px; /* HUGE space between all major sections */ padding: 16px 0; max-width: 100%; `; const HeaderSection = styled.div` display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 32px; /* More space between header cards */ `; const Card = styled.div` background: var(--bg-surface); border-radius: 16px; /* Slightly rounder corners */ padding: 16px; /* More internal padding */ border: 1px solid var(--accent-border); box-shadow: var(--shadow-sm); /* Subtle shadow for depth */ `; const VerdictCard = styled(Card)<{ color: string }>` border-left: 4px solid ${props => props.color}; `; const VerdictLabel = styled.div` font-size: ${fontSize.small}; color: var(--fg-secondary); margin-bottom: 32px; `; const VerdictValue = styled.div` font-size: ${fontSize.large}; font-weight: ${fontWeight.bold}; color: var(--fg-primary); `; const ConfidenceCard = styled(Card)``; const ConfidenceLabel = styled(VerdictLabel)``; const ConfidenceValue = styled.div` font-size: ${fontSize.xlarge}; font-weight: ${fontWeight.bold}; color: var(--fg-primary); margin-bottom: 32px; `; const ConfidenceBar = styled.div` height: 8px; background: var(--accent-subtle); border-radius: 4px; overflow: hidden; `; const ConfidenceFill = styled.div<{ width: number; color: string }>` height: 100%; width: ${props => props.width}%; background: ${props => props.color}; transition: width 0.3s ease; `; const HarmCard = styled(Card)<{ color: string }>` border-left: 4px solid ${props => props.color}; `; const HarmLabel = styled(VerdictLabel)``; const HarmValue = styled(VerdictValue)``; const ExplanationSection = styled(Card)``; const SectionTitle = styled.h3` font-size: ${fontSize.large}; /* Bigger title */ font-weight: ${fontWeight.bold}; /* Bolder */ color: var(--fg-primary); margin: 0 0 32px 0; /* More space below title */ display: flex; align-items: center; gap: 32px; `; const ExplanationText = styled.p` font-size: ${fontSize.medium}; line-height: 1.7; /* More line height for readability */ color: var(--fg-secondary); margin: 0; `; const CategorySection = styled.div` display: flex; gap: 32px; flex-wrap: wrap; `; const Badge = styled.span` padding: 8px 20px; border-radius: 20px; font-size: ${fontSize.small}; font-weight: ${fontWeight.medium}; `; const CategoryBadge = styled(Badge)` background: var(--accent-subtle); color: var(--accent-text); border: 1px solid var(--accent-border); `; const TypeBadge = styled(Badge)` background: ${colors.insightOrange}20; color: ${colors.insightOrange}; border: 1px solid ${colors.insightOrange}40; `; const LangBadge = styled(Badge)` background: var(--accent-subtle); color: var(--fg-secondary); border: 1px solid var(--accent-border); `; const ClaimsSection = styled(Card)``; const ClaimsList = styled.div` display: flex; flex-direction: column; gap: 24px; /* HUGE gap between each claim card */ `; const ClaimCard = styled.div` background: var(--accent-subtle); border-radius: 12px; /* Rounder corners */ padding: 16px; /* More internal padding */ border: 1px solid var(--accent-border); transition: all 0.2s ease; &:hover { background: var(--bg-hover); border-color: var(--accent-border); transform: translateX(4px); } `; const ClaimHeader = styled.div` display: flex; align-items: center; gap: 32px; margin-bottom: 32px; `; const ClaimNumber = styled.span` background: var(--accent-subtle); color: var(--accent-text); padding: 2px 8px; border-radius: 4px; font-size: ${fontSize.small}; font-weight: ${fontWeight.semiBold}; `; const VerifiedBadge = styled.span<{ verified: boolean }>` background: ${props => props.verified ? colors.truthGreen : colors.cautionRed}20; color: ${props => props.verified ? colors.truthGreen : colors.cautionRed}; padding: 2px 8px; border-radius: 4px; font-size: ${fontSize.small}; font-weight: ${fontWeight.medium}; `; const HarmBadge = styled.span<{ level: string }>` background: ${props => { const l = props.level?.toLowerCase(); if (l === 'critical') return '#8B0000'; if (l === 'high') return colors.cautionRed; if (l === 'medium') return '#FFA500'; return '#FFD700'; }}20; color: ${props => { const l = props.level?.toLowerCase(); if (l === 'critical') return '#8B0000'; if (l === 'high') return colors.cautionRed; if (l === 'medium') return '#FFA500'; return '#FFD700'; }}; padding: 2px 8px; border-radius: 4px; font-size: ${fontSize.small}; `; const ClaimText = styled.p` color: var(--fg-primary); margin: 0 0 12px 0; line-height: 1.5; `; const SourcesList = styled.div` margin-top: 12px; `; const SourcesLabel = styled.div` font-size: ${fontSize.small}; color: var(--fg-secondary); margin-bottom: 4px; `; const SourceLink = styled.a` display: block; color: var(--accent-text); font-size: ${fontSize.small}; text-decoration: none; margin: 4px 0; word-break: break-all; &:hover { text-decoration: underline; } `; const ClaimNotes = styled.div` font-size: ${fontSize.small}; color: var(--fg-secondary); font-style: italic; margin-top: 12px; `; const ManipulationSection = styled(Card)``; const TechniquesList = styled.div` display: flex; flex-wrap: wrap; gap: 20px; /* More space between tags */ `; const TechniqueTag = styled.span` background: ${colors.cautionRed}20; color: ${colors.cautionRed}; padding: 12px 20px; /* Bigger tags */ border-radius: 8px; /* Rounder */ font-size: ${fontSize.small}; border: 1px solid ${colors.cautionRed}40; font-weight: ${fontWeight.medium}; transition: all 0.2s ease; &:hover { background: ${colors.cautionRed}30; transform: translateY(-2px); box-shadow: var(--shadow-md); } `; const EmotionalSection = styled(Card)<{ severity?: string }>` border-left: 4px solid ${props => { const s = props.severity?.toLowerCase(); if (s === 'high') return colors.cautionRed; if (s === 'medium') return '#FFA500'; return '#FFD700'; }}; `; const EmotionalContent = styled.div``; const SeverityBadge = styled.span<{ severity?: string }>` background: ${props => { const s = props.severity?.toLowerCase(); if (s === 'high') return colors.cautionRed; if (s === 'medium') return '#FFA500'; return '#FFD700'; }}20; color: ${props => { const s = props.severity?.toLowerCase(); if (s === 'high') return colors.cautionRed; if (s === 'medium') return '#FFA500'; return '#FFD700'; }}; padding: 4px 12px; border-radius: 6px; font-size: ${fontSize.small}; font-weight: ${fontWeight.semiBold}; display: inline-block; margin-bottom: 32px; `; const TriggersList = styled(TechniquesList)``; const TriggerTag = styled.span` background: #FFA50020; color: #FFA500; padding: 8px 12px; border-radius: 6px; font-size: ${fontSize.small}; border: 1px solid #FFA50040; `; const MediaSection = styled(Card)``; const MediaGrid = styled.div` display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 20px; `; const MediaItem = styled.div``; const MediaLabel = styled.div` font-size: ${fontSize.small}; color: var(--fg-secondary); margin-bottom: 4px; `; const MediaValue = styled.div` color: var(--fg-primary); font-weight: ${fontWeight.medium}; `; const AssessmentBadge = styled.span<{ assessment: string }>` background: ${props => { const a = props.assessment?.toLowerCase(); if (a === 'authentic') return colors.truthGreen; if (a === 'manipulated') return colors.cautionRed; if (a === 'suspicious') return '#FFA500'; return colors.steelGray; }}20; color: ${props => { const a = props.assessment?.toLowerCase(); if (a === 'authentic') return colors.truthGreen; if (a === 'manipulated') return colors.cautionRed; if (a === 'suspicious') return '#FFA500'; return colors.steelGray; }}; padding: 4px 12px; border-radius: 6px; font-size: ${fontSize.small}; font-weight: ${fontWeight.medium}; `; const VerificationSection = styled(Card)<{ performed: boolean }>` border-left: 4px solid ${props => props.performed ? colors.truthGreen : 'var(--border-strong)'}; `; const VerifItem = styled.div` margin-bottom: 32px; &:last-child { margin-bottom: 0; } `; const VerifLabel = styled.div` font-size: ${fontSize.small}; color: var(--fg-secondary); margin-bottom: 8px; `; const SitesList = styled.div` display: flex; flex-wrap: wrap; gap: 8px; `; const SiteTag = styled.span` background: ${colors.truthGreen}20; color: ${colors.truthGreen}; padding: 4px 10px; border-radius: 6px; font-size: ${fontSize.small}; `; const UrlsList = styled.div` display: flex; flex-direction: column; gap: 4px; `; const UrlLink = styled.a` color: var(--accent-text); font-size: ${fontSize.small}; text-decoration: none; word-break: break-all; &:hover { text-decoration: underline; } `; const LimitationText = styled.p` color: var(--fg-secondary); font-size: ${fontSize.small}; font-style: italic; margin: 0; `; const ViralSection = styled(Card)<{ level?: string }>` border-left: 4px solid ${props => { const l = props.level?.toLowerCase(); if (l === 'critical') return '#8B0000'; if (l === 'high') return colors.cautionRed; if (l === 'medium') return '#FFA500'; return colors.truthGreen; }}; `; const ViralGrid = styled.div` display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 20px; margin-bottom: 32px; `; const ViralItem = styled.div``; const ViralLabel = styled(MediaLabel)``; const RiskBadge = styled.span<{ level: string }>` background: ${props => { const l = props.level?.toLowerCase(); if (l === 'critical') return '#8B0000'; if (l === 'high') return colors.cautionRed; if (l === 'medium') return '#FFA500'; return colors.truthGreen; }}20; color: ${props => { const l = props.level?.toLowerCase(); if (l === 'critical') return '#8B0000'; if (l === 'high') return colors.cautionRed; if (l === 'medium') return '#FFA500'; return colors.truthGreen; }}; padding: 4px 12px; border-radius: 6px; font-size: ${fontSize.small}; font-weight: ${fontWeight.semiBold}; `; const ScoreValue = styled.div` color: var(--fg-primary); font-size: ${fontSize.large}; font-weight: ${fontWeight.bold}; `; const FactorsList = styled(TechniquesList)``; const FactorTag = styled.span` background: var(--accent-subtle); color: var(--fg-secondary); padding: 8px 12px; border-radius: 6px; font-size: ${fontSize.small}; border: 1px solid var(--accent-border); `; const AssessmentText = styled.p` color: var(--fg-secondary); font-size: ${fontSize.small}; margin: 20px 0 0 0; line-height: 1.5; `; const RecommendationsSection = styled(Card)<{ urgency?: string }>` border-left: 4px solid ${props => { const u = props.urgency?.toLowerCase(); if (u === 'critical') return '#8B0000'; if (u === 'high') return colors.cautionRed; if (u === 'medium') return '#FFA500'; return colors.truthGreen; }}; `; const RecommendationGrid = styled.div` display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 20px; margin-bottom: 32px; `; const RecommendItem = styled.div``; const RecommendLabel = styled(MediaLabel)``; const ActionBadge = styled.span<{ action: string }>` background: ${props => { const a = props.action?.toLowerCase(); if (a === 'remove' || a === 'escalate') return colors.cautionRed; if (a === 'flag') return '#FFA500'; if (a === 'fact_check') return colors.honestTeal; return colors.truthGreen; }}20; color: ${props => { const a = props.action?.toLowerCase(); if (a === 'remove' || a === 'escalate') return colors.cautionRed; if (a === 'flag') return '#FFA500'; if (a === 'fact_check') return colors.honestTeal; return colors.truthGreen; }}; padding: 4px 12px; border-radius: 6px; font-size: ${fontSize.small}; font-weight: ${fontWeight.medium}; `; const UrgencyBadge = styled(RiskBadge)``; const ReasonText = styled.p` color: var(--fg-secondary); font-size: ${fontSize.small}; margin: 0; line-height: 1.5; `; // ==================== NEW SECTIONS ==================== const SourceCredibilitySection = styled(Card)` border-left: 4px solid var(--accent); `; const CredibilityText = styled.p` color: var(--fg-secondary); font-size: ${fontSize.medium}; margin: 0; line-height: 1.6; `; const TemporalSection = styled(Card)` border-left: 4px solid ${colors.insightOrange}; `; const TemporalText = styled.p` color: var(--fg-secondary); font-size: ${fontSize.medium}; margin: 0; line-height: 1.6; font-style: italic; `; const ConfidenceFactorsSection = styled(Card)` border-left: 4px solid ${colors.truthGreen}; `; const ConfidenceFactorsList = styled.div` display: flex; flex-direction: column; gap: 12px; `; const ConfidenceFactorItem = styled.div` color: var(--fg-secondary); font-size: ${fontSize.medium}; line-height: 1.5; padding-left: 8px; `; const DetailedAnalysisSection = styled(Card)` border-left: 4px solid var(--border-strong); `; const ToggleHeader = styled.div` display: flex; justify-content: space-between; align-items: center; cursor: pointer; user-select: none; &:hover { opacity: 0.8; } `; const ToggleIcon = styled.span` color: var(--fg-secondary); font-size: ${fontSize.large}; margin-left: 16px; `; const DetailedContent = styled.div` margin-top: 24px; display: flex; flex-direction: column; gap: 20px; `; const DetailItem = styled.div` display: flex; flex-direction: column; gap: 8px; `; const DetailLabel = styled.div` color: var(--fg-secondary); font-size: ${fontSize.small}; font-weight: ${fontWeight.semiBold}; text-transform: uppercase; letter-spacing: 0.5px; `; const DetailText = styled.p` color: var(--fg-primary); font-size: ${fontSize.medium}; margin: 0; line-height: 1.6; `; const DetailBadge = styled.span` background: var(--accent-subtle); color: var(--fg-primary); padding: 6px 14px; border-radius: 6px; font-size: ${fontSize.small}; font-weight: ${fontWeight.medium}; display: inline-block;`; const TranscriptionSection = styled(Card)` border-left: 4px solid var(--accent); `; const TranscriptionContent = styled.pre` background: var(--accent-subtle); border: 1px solid var(--accent-border); border-radius: 8px; padding: 20px; margin-top: 16px; color: var(--fg-secondary); font-size: ${fontSize.small}; line-height: 1.8; white-space: pre-wrap; word-wrap: break-word; max-height: 400px; overflow-y: auto; font-family: 'Courier New', monospace; /* Custom scrollbar */ &::-webkit-scrollbar { width: 8px; } &::-webkit-scrollbar-track { background: var(--bg-active); border-radius: 4px; } &::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 4px; } &::-webkit-scrollbar-thumb:hover { background: var(--fg-muted); } `; // ==================== AGGREGATOR QUALITY STYLES (v3) ==================== const QualitySection = styled(Card)<{ reliability: string }>` border-left: 4px solid ${props => { switch (props.reliability?.toUpperCase()) { case 'HIGH': return colors.truthGreen; case 'MEDIUM': return '#FFD700'; case 'LOW': return colors.cautionRed; default: return colors.steelGray; } }}; `; const QualityHeader = styled.div` display: flex; align-items: center; gap: 24px; flex-wrap: wrap; margin-bottom: 16px; `; const ReliabilityBadge = styled.span<{ color: string }>` background: ${props => props.color}20; color: ${props => props.color}; padding: 8px 16px; border-radius: 8px; font-size: ${fontSize.medium}; font-weight: ${fontWeight.bold}; border: 1px solid ${props => props.color}40; `; const SignalStats = styled.div` display: flex; gap: 24px; `; const StatItem = styled.div` display: flex; flex-direction: column; gap: 4px; `; const StatLabel = styled.span` font-size: ${fontSize.small}; color: var(--fg-secondary); `; const StatValue = styled.span<{ warning?: boolean }>` font-size: ${fontSize.large}; font-weight: ${fontWeight.bold}; color: ${props => props.warning ? '#FFA500' : 'var(--fg-primary)'}; [data-theme="light"] & { color: ${props => props.warning ? '#f97316' : 'var(--fg-primary)'}; } `; const QualityReason = styled.p` color: var(--fg-secondary); font-size: ${fontSize.medium}; margin: 0; line-height: 1.6; `; const CriticalWarning = styled.div` margin-top: 16px; padding: 12px 16px; background: ${colors.cautionRed}15; border: 1px solid ${colors.cautionRed}40; border-radius: 8px; color: ${colors.cautionRed}; font-size: ${fontSize.small}; font-weight: ${fontWeight.medium}; `; // ==================== SIGNAL BREAKDOWN STYLES (v3) ==================== const SignalBreakdownSection = styled(Card)` border-left: 4px solid var(--accent); `; const SignalBreakdownContent = styled.div` display: flex; flex-direction: column; gap: 16px; margin-top: 16px; `; const SignalCard = styled.div<{ isDefault?: boolean }>` background: ${props => props.isDefault ? 'rgba(255, 165, 0, 0.05)' : 'var(--accent-subtle)'}; border: 1px solid ${props => props.isDefault ? 'rgba(255, 165, 0, 0.2)' : 'var(--accent-border)'}; border-radius: 12px; padding: 16px; transition: all 0.2s ease; &:hover { background: ${props => props.isDefault ? 'rgba(255, 165, 0, 0.08)' : 'var(--bg-hover)'}; } `; const SignalHeader = styled.div` display: flex; align-items: center; gap: 16px; margin-bottom: 12px; flex-wrap: wrap; `; const SignalName = styled.span` color: var(--fg-primary); font-size: ${fontSize.medium}; font-weight: ${fontWeight.semiBold}; text-transform: capitalize; `; const SignalWeight = styled.span` color: var(--fg-secondary); font-size: ${fontSize.small}; padding: 4px 8px; background: var(--accent-subtle); border-radius: 4px; `; const DefaultBadge = styled.span` background: #FFA50020; color: #FFA500; padding: 4px 8px; border-radius: 4px; font-size: ${fontSize.small}; font-weight: ${fontWeight.medium}; `; const SignalBarContainer = styled.div` display: flex; align-items: center; gap: 12px; `; const SignalBar = styled.div` flex: 1; height: 8px; background: var(--accent-subtle); border-radius: 4px; overflow: hidden; `; const SignalBarFill = styled.div<{ width: number; color: string }>` height: 100%; width: ${props => Math.min(100, Math.max(0, props.width))}%; background: ${props => props.color}; transition: width 0.3s ease; `; const SignalScore = styled.span` color: var(--fg-primary); font-size: ${fontSize.medium}; font-weight: ${fontWeight.bold}; min-width: 48px; text-align: right; `; const SignalContribution = styled.div` color: var(--fg-secondary); font-size: ${fontSize.small}; margin-top: 8px; `; const DefaultReasonText = styled.div` color: #FFA500; font-size: ${fontSize.small}; margin-top: 8px; font-style: italic; `; const TotalScoreCard = styled.div` background: var(--accent-subtle); border: 1px solid var(--accent-border); border-radius: 12px; padding: 20px; display: flex; justify-content: space-between; align-items: center; margin-top: 8px; `; const TotalLabel = styled.span` color: var(--fg-primary); font-size: ${fontSize.large}; font-weight: ${fontWeight.semiBold}; `; const TotalScore = styled.span<{ color: string }>` font-size: ${fontSize.xlarge}; font-weight: ${fontWeight.bold}; color: ${props => props.color}; `; // ==================== TRIAGE BADGES STYLES (v3) ==================== const TriageSection = styled.div` display: flex; gap: 12px; flex-wrap: wrap; `; const TriageBadge = styled.span<{ color: string }>` background: ${props => props.color}20; color: ${props => props.color}; padding: 8px 16px; border-radius: 8px; font-size: ${fontSize.small}; font-weight: ${fontWeight.semiBold}; border: 1px solid ${props => props.color}40; display: inline-flex; align-items: center; gap: 6px; text-transform: capitalize; `; // ==================== SOURCES EVALUATED STYLES (v3) ==================== const SourcesEvaluatedSection = styled(Card)` border-left: 4px solid var(--accent); `; const SourcesEvaluatedContent = styled.div` display: flex; flex-direction: column; gap: 12px; margin-top: 16px; `; const SourceCard = styled.div<{ stance: string }>` background: var(--accent-subtle); border: 1px solid ${props => { switch (props.stance) { case 'supports': return `${colors.truthGreen}30`; case 'contradicts': return `${colors.cautionRed}30`; case 'neutral': return '#FFD70030'; default: return 'var(--accent-border)'; } }}; border-radius: 12px; padding: 16px; transition: all 0.2s ease; &:hover { background: var(--bg-hover); } `; const SourceUrlRow = styled.div` display: flex; align-items: center; gap: 8px; margin-bottom: 12px; `; const SourceIcon = styled.span` font-size: ${fontSize.medium}; `; const SourceUrl = styled.a` color: var(--accent-text); font-size: ${fontSize.medium}; text-decoration: none; word-break: break-all; font-weight: ${fontWeight.medium}; &:hover { text-decoration: underline; } `; const SourceMetaRow = styled.div` display: flex; flex-wrap: wrap; gap: 8px; align-items: center; `; const TierBadge = styled.span<{ tier: number }>` background: ${props => { if (props.tier <= 2) return colors.truthGreen; if (props.tier <= 3) return '#FFD700'; if (props.tier <= 4) return '#FFA500'; return colors.cautionRed; }}20; color: ${props => { if (props.tier <= 2) return colors.truthGreen; if (props.tier <= 3) return '#FFD700'; if (props.tier <= 4) return '#FFA500'; return colors.cautionRed; }}; padding: 4px 10px; border-radius: 6px; font-size: ${fontSize.small}; font-weight: ${fontWeight.medium}; `; const StanceBadge = styled.span<{ color: string }>` background: ${props => props.color}20; color: ${props => props.color}; padding: 4px 10px; border-radius: 6px; font-size: ${fontSize.small}; font-weight: ${fontWeight.semiBold}; text-transform: capitalize; `; const AuthorityBadge = styled.span` background: var(--accent-subtle); color: var(--fg-primary); padding: 4px 10px; border-radius: 6px; font-size: ${fontSize.small}; text-transform: capitalize; `; const RecencyBadge = styled.span<{ recency: string }>` background: ${props => { switch (props.recency) { case 'current': return colors.truthGreen; case 'dated': return '#FFA500'; case 'historical': return colors.steelGray; default: return colors.steelGray; } }}20; color: ${props => { switch (props.recency) { case 'current': return colors.truthGreen; case 'dated': return '#FFA500'; case 'historical': return colors.steelGray; default: return colors.steelGray; } }}; padding: 4px 10px; border-radius: 6px; font-size: ${fontSize.small}; text-transform: capitalize; `; const CircularWarning = styled.div` margin-top: 12px; padding: 8px 12px; background: ${colors.cautionRed}15; border: 1px solid ${colors.cautionRed}40; border-radius: 6px; color: ${colors.cautionRed}; font-size: ${fontSize.small}; `; const CircularChain = styled.div` margin-top: 4px; font-size: ${fontSize.small}; opacity: 0.8; `; const PrimarySourceNote = styled.div` margin-top: 12px; padding: 8px 12px; background: var(--accent-subtle); border: 1px solid var(--accent-border); border-radius: 6px; color: var(--accent-text); font-size: ${fontSize.small}; `; const TierReasoning = styled.div` margin-top: 12px; color: var(--fg-secondary); font-size: ${fontSize.small}; font-style: italic; line-height: 1.5; `; // ==================== STANCE SUMMARY STYLES (v3) ==================== const StanceSummarySection = styled(Card)` border-left: 4px solid ${colors.insightOrange}; `; const StanceBars = styled.div` display: flex; flex-direction: column; gap: 12px; margin-bottom: 20px; `; const StanceBarRow = styled.div` display: flex; align-items: center; gap: 12px; `; const StanceBarLabel = styled.span` min-width: 100px; color: var(--fg-secondary); font-size: ${fontSize.small}; `; const StanceBarContainer = styled.div` flex: 1; height: 12px; background: var(--accent-subtle); border-radius: 6px; overflow: hidden; `; const StanceBarFill = styled.div<{ width: number; color: string }>` height: 100%; width: ${props => Math.min(100, Math.max(0, props.width))}%; background: ${props => props.color}; transition: width 0.3s ease; `; const StanceBarCount = styled.span` min-width: 80px; color: var(--fg-primary); font-size: ${fontSize.small}; font-weight: ${fontWeight.medium}; text-align: right; `; const WeightedStanceRow = styled.div` display: flex; align-items: center; gap: 12px; padding: 16px; background: var(--accent-subtle); border-radius: 12px; margin-top: 8px; `; const WeightedStanceLabel = styled.span` color: var(--fg-secondary); font-size: ${fontSize.medium}; `; const WeightedStanceValue = styled.div<{ score: number }>` color: ${props => { if (props.score > 0.3) return colors.truthGreen; if (props.score > -0.3) return '#FFD700'; return colors.cautionRed; }}; font-size: ${fontSize.large}; font-weight: ${fontWeight.bold}; display: flex; align-items: center; gap: 8px; `; const WeightedStanceInterpretation = styled.span` font-size: ${fontSize.small}; font-weight: ${fontWeight.medium}; opacity: 0.8; `; const NoRelevantEvidenceWarning = styled.div` margin-top: 16px; padding: 12px 16px; background: ${colors.cautionRed}15; border: 1px solid ${colors.cautionRed}40; border-radius: 8px; color: ${colors.cautionRed}; font-size: ${fontSize.small}; font-weight: ${fontWeight.medium}; `; // ==================== CLAIM VERDICTS STYLES (v3) ==================== const ClaimVerdictsSection = styled(Card)` border-left: 4px solid var(--accent); `; const ClaimVerdictsContent = styled.div` display: flex; flex-direction: column; gap: 20px; margin-top: 16px; `; const ClaimVerdictCard = styled.div` background: var(--accent-subtle); border: 1px solid var(--accent-border); border-radius: 12px; padding: 20px; transition: all 0.2s ease; &:hover { background: var(--bg-hover); border-color: var(--accent-border); } `; const ClaimVerdictHeader = styled.div` display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; `; const ClaimVerdictNumber = styled.span` background: var(--accent-subtle); color: var(--fg-primary); padding: 4px 10px; border-radius: 6px; font-size: ${fontSize.small}; font-weight: ${fontWeight.semiBold}; `; const ClaimVerdictBadge = styled.span<{ color: string }>` background: ${props => props.color}20; color: ${props => props.color}; padding: 6px 14px; border-radius: 8px; font-size: ${fontSize.medium}; font-weight: ${fontWeight.bold}; text-transform: uppercase; border: 1px solid ${props => props.color}40; `; const ClaimVerdictScore = styled.span` color: var(--fg-secondary); font-size: ${fontSize.small}; `; const ClaimVerdictText = styled.div` color: var(--fg-primary); font-size: ${fontSize.medium}; line-height: 1.6; margin-bottom: 12px; font-style: italic; padding-left: 16px; border-left: 2px solid var(--accent-border); `; const ClaimVerdictExplanation = styled.p` color: var(--fg-secondary); font-size: ${fontSize.medium}; line-height: 1.6; margin: 0 0 16px 0; `; const EvidenceSection = styled.div` margin-top: 12px; `; const EvidenceLabel = styled.div` color: var(--fg-secondary); font-size: ${fontSize.small}; font-weight: ${fontWeight.semiBold}; margin-bottom: 8px; `; const EvidenceList = styled.div` display: flex; flex-direction: column; gap: 4px; padding-left: 16px; `; const EvidenceItem = styled.div<{ type: 'for' | 'against' }>` color: ${props => props.type === 'for' ? colors.truthGreen : colors.cautionRed}; font-size: ${fontSize.small}; line-height: 1.5; `; const EvidenceLink = styled.a` color: inherit; text-decoration: none; word-break: break-all; &:hover { text-decoration: underline; } `; const EpistemicSection = styled.div` margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--accent-border); `; const EpistemicRow = styled.div` display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; `; const EpistemicBadge = styled.span<{ type: 'evidence' | 'nature' | 'temporal' }>` background: ${props => { switch (props.type) { case 'evidence': return colors.honestTeal; case 'nature': return colors.insightOrange; case 'temporal': return colors.deepBlue; default: return colors.steelGray; } }}20; color: ${props => { switch (props.type) { case 'evidence': return colors.honestTeal; case 'nature': return colors.insightOrange; case 'temporal': return colors.deepBlue; default: return colors.steelGray; } }}; padding: 4px 10px; border-radius: 6px; font-size: ${fontSize.small}; text-transform: capitalize; `; const RecommendedActionRow = styled.div` display: flex; align-items: center; gap: 8px; margin-top: 8px; `; const RecommendedActionLabel = styled.span` color: var(--fg-secondary); font-size: ${fontSize.small}; `; const RecommendedActionValue = styled.span` color: var(--fg-primary); font-size: ${fontSize.small}; font-weight: ${fontWeight.medium}; text-transform: capitalize; `;