- Surse complete web (React/Vite) + mobil (React Native/Expo) + extensie (MV3) - Documentație de livrare: ghid utilizare, matrice trasabilitate cerințe, raport testare furnizor - Artefacte binare: imagine Docker didi-frontend:lot3-1.0, APK, extensie v3.2.6 + SHA256SUMS - Configurare adresă platformă externalizată (build args / .env / config.js) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2173 lines
65 KiB
TypeScript
2173 lines
65 KiB
TypeScript
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<AnalysisResultsProps> = ({ 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 (
|
|
<Container>
|
|
{/* Header Section - Verdict & Confidence */}
|
|
<HeaderSection>
|
|
<VerdictCard color={getVerdictColor(data.verdict)}>
|
|
<VerdictLabel>Verdict</VerdictLabel>
|
|
<VerdictValue>{data.verdict.replace(/_/g, ' ').toUpperCase()}</VerdictValue>
|
|
</VerdictCard>
|
|
|
|
<ConfidenceCard>
|
|
<ConfidenceLabel>Confidence</ConfidenceLabel>
|
|
<ConfidenceValue>{(data.confidence * 100).toFixed(0)}%</ConfidenceValue>
|
|
<ConfidenceBar>
|
|
<ConfidenceFill
|
|
width={(data.confidence * 100)}
|
|
color={getConfidenceColor(data.confidence)}
|
|
/>
|
|
</ConfidenceBar>
|
|
</ConfidenceCard>
|
|
|
|
{data.harm_level && (
|
|
<HarmCard color={getHarmColor(data.harm_level)}>
|
|
<HarmLabel>Harm Level</HarmLabel>
|
|
<HarmValue>{data.harm_level?.toUpperCase()}</HarmValue>
|
|
</HarmCard>
|
|
)}
|
|
</HeaderSection>
|
|
|
|
{/* Explanation */}
|
|
<ExplanationSection>
|
|
<SectionTitle>Explanation</SectionTitle>
|
|
<ExplanationText>{data.explanation}</ExplanationText>
|
|
</ExplanationSection>
|
|
|
|
{/* Category & Type */}
|
|
{(data.primary_category || data.metadata?.pipeline_type) && (
|
|
<CategorySection>
|
|
{data.primary_category && (
|
|
<CategoryBadge>{data.primary_category.replace(/_/g, ' ')}</CategoryBadge>
|
|
)}
|
|
{data.metadata?.pipeline_type && (
|
|
<TypeBadge>{data.metadata.pipeline_type}</TypeBadge>
|
|
)}
|
|
{data.metadata?.language_detected && (
|
|
<LangBadge>{data.metadata.language_detected.toUpperCase()}</LangBadge>
|
|
)}
|
|
</CategorySection>
|
|
)}
|
|
|
|
{/* Triage Badges (v3) - Content Type, Urgency, Manipulation Status */}
|
|
{hasTriage && (
|
|
<TriageSection>
|
|
<TriageBadge color={colors.deepBlue}>
|
|
{data.triage!.content_type.replace(/_/g, ' ')}
|
|
</TriageBadge>
|
|
<TriageBadge color={getContentUrgencyColor(data.triage!.urgency)}>
|
|
{data.triage!.urgency}
|
|
</TriageBadge>
|
|
{data.triage!.manipulation_detected !== undefined && (
|
|
<TriageBadge color={data.triage!.manipulation_detected ? colors.cautionRed : colors.truthGreen}>
|
|
{data.triage!.manipulation_detected ? 'Manipulation Detected' : 'No Manipulation'}
|
|
</TriageBadge>
|
|
)}
|
|
</TriageSection>
|
|
)}
|
|
|
|
{/* Analysis Quality Indicator (v3 Aggregator) */}
|
|
{hasAggregator && data.aggregator?.analysis_quality && (
|
|
<QualitySection reliability={data.aggregator.analysis_quality.reliability}>
|
|
<SectionTitle>Analysis Quality</SectionTitle>
|
|
<QualityHeader>
|
|
<ReliabilityBadge color={getReliabilityColor(data.aggregator.analysis_quality.reliability)}>
|
|
{data.aggregator.analysis_quality.reliability} Reliability
|
|
</ReliabilityBadge>
|
|
<SignalStats>
|
|
<StatItem>
|
|
<StatLabel>Signals Computed</StatLabel>
|
|
<StatValue>{data.aggregator.analysis_quality.signals_computed}</StatValue>
|
|
</StatItem>
|
|
<StatItem>
|
|
<StatLabel>Signals Defaulted</StatLabel>
|
|
<StatValue warning={data.aggregator.analysis_quality.signals_defaulted > 0}>
|
|
{data.aggregator.analysis_quality.signals_defaulted}
|
|
</StatValue>
|
|
</StatItem>
|
|
</SignalStats>
|
|
</QualityHeader>
|
|
<QualityReason>{data.aggregator.analysis_quality.reliability_reason}</QualityReason>
|
|
{data.aggregator.analysis_quality.critical_signals_defaulted &&
|
|
data.aggregator.analysis_quality.critical_signals_defaulted.length > 0 && (
|
|
<CriticalWarning>
|
|
Critical signals used defaults: {data.aggregator.analysis_quality.critical_signals_defaulted.join(', ')}
|
|
</CriticalWarning>
|
|
)}
|
|
</QualitySection>
|
|
)}
|
|
|
|
{/* Sources Evaluated Section (v3) - Collapsible */}
|
|
{hasSourceEvaluation && (
|
|
<SourcesEvaluatedSection>
|
|
<ToggleHeader onClick={() => setShowSourcesEvaluated(!showSourcesEvaluated)}>
|
|
<SectionTitle>Sources Evaluated ({data.source_evaluation!.source_evaluations.length} sources)</SectionTitle>
|
|
<ToggleIcon>{showSourcesEvaluated ? '▼' : '▶'}</ToggleIcon>
|
|
</ToggleHeader>
|
|
{showSourcesEvaluated && (
|
|
<SourcesEvaluatedContent>
|
|
{data.source_evaluation!.source_evaluations.map((source, idx) => (
|
|
<SourceCard key={idx} stance={source.stance}>
|
|
<SourceUrlRow>
|
|
<SourceUrl href={source.url} target="_blank" rel="noopener noreferrer">
|
|
{source.url.length > 60 ? source.url.substring(0, 60) + '...' : source.url}
|
|
</SourceUrl>
|
|
</SourceUrlRow>
|
|
<SourceMetaRow>
|
|
<TierBadge tier={source.effective_tier}>
|
|
Tier {source.effective_tier} ({getTierLabel(source.effective_tier)})
|
|
</TierBadge>
|
|
<StanceBadge color={getStanceColor(source.stance)}>
|
|
{source.stance} ({(source.stance_strength * 100).toFixed(0)}%)
|
|
</StanceBadge>
|
|
{source.domain_authority && source.domain_authority !== 'unknown' && (
|
|
<AuthorityBadge>{source.domain_authority}</AuthorityBadge>
|
|
)}
|
|
{source.recency_relevance && (
|
|
<RecencyBadge recency={source.recency_relevance}>{source.recency_relevance}</RecencyBadge>
|
|
)}
|
|
</SourceMetaRow>
|
|
{source.circular_sourcing_detected && (
|
|
<CircularWarning>
|
|
Circular sourcing detected
|
|
{source.circular_chain && source.circular_chain.length > 0 && (
|
|
<CircularChain>Chain: {source.circular_chain.join(' → ')}</CircularChain>
|
|
)}
|
|
</CircularWarning>
|
|
)}
|
|
{source.is_tier5_primary && source.tier5_primary_type && (
|
|
<PrimarySourceNote>
|
|
Social media IS the primary source ({source.tier5_primary_type})
|
|
</PrimarySourceNote>
|
|
)}
|
|
{source.tier_reasoning && (
|
|
<TierReasoning>{source.tier_reasoning}</TierReasoning>
|
|
)}
|
|
</SourceCard>
|
|
))}
|
|
</SourcesEvaluatedContent>
|
|
)}
|
|
</SourcesEvaluatedSection>
|
|
)}
|
|
|
|
{/* Stance Summary (v3) - Visual Bar */}
|
|
{hasSourceEvaluation && data.source_evaluation!.stance_summary && (
|
|
<StanceSummarySection>
|
|
<SectionTitle>Evidence Stance Summary</SectionTitle>
|
|
<StanceBars>
|
|
{data.source_evaluation!.stance_summary.supporting_sources > 0 && (
|
|
<StanceBarRow>
|
|
<StanceBarLabel>Supporting</StanceBarLabel>
|
|
<StanceBarContainer>
|
|
<StanceBarFill
|
|
width={(data.source_evaluation!.stance_summary.supporting_sources / data.source_evaluation!.source_evaluations.length) * 100}
|
|
color={colors.truthGreen}
|
|
/>
|
|
</StanceBarContainer>
|
|
<StanceBarCount>{data.source_evaluation!.stance_summary.supporting_sources} sources</StanceBarCount>
|
|
</StanceBarRow>
|
|
)}
|
|
{data.source_evaluation!.stance_summary.contradicting_sources > 0 && (
|
|
<StanceBarRow>
|
|
<StanceBarLabel>Contradicting</StanceBarLabel>
|
|
<StanceBarContainer>
|
|
<StanceBarFill
|
|
width={(data.source_evaluation!.stance_summary.contradicting_sources / data.source_evaluation!.source_evaluations.length) * 100}
|
|
color={colors.cautionRed}
|
|
/>
|
|
</StanceBarContainer>
|
|
<StanceBarCount>{data.source_evaluation!.stance_summary.contradicting_sources} sources</StanceBarCount>
|
|
</StanceBarRow>
|
|
)}
|
|
{data.source_evaluation!.stance_summary.neutral_sources > 0 && (
|
|
<StanceBarRow>
|
|
<StanceBarLabel>Neutral</StanceBarLabel>
|
|
<StanceBarContainer>
|
|
<StanceBarFill
|
|
width={(data.source_evaluation!.stance_summary.neutral_sources / data.source_evaluation!.source_evaluations.length) * 100}
|
|
color="#FFD700"
|
|
/>
|
|
</StanceBarContainer>
|
|
<StanceBarCount>{data.source_evaluation!.stance_summary.neutral_sources} sources</StanceBarCount>
|
|
</StanceBarRow>
|
|
)}
|
|
{(data.source_evaluation!.stance_summary.unrelated_sources ?? 0) > 0 && (
|
|
<StanceBarRow>
|
|
<StanceBarLabel>Unrelated</StanceBarLabel>
|
|
<StanceBarContainer>
|
|
<StanceBarFill
|
|
width={((data.source_evaluation!.stance_summary.unrelated_sources ?? 0) / data.source_evaluation!.source_evaluations.length) * 100}
|
|
color={colors.steelGray}
|
|
/>
|
|
</StanceBarContainer>
|
|
<StanceBarCount>{data.source_evaluation!.stance_summary.unrelated_sources} sources</StanceBarCount>
|
|
</StanceBarRow>
|
|
)}
|
|
</StanceBars>
|
|
<WeightedStanceRow>
|
|
<WeightedStanceLabel>Weighted Stance Score:</WeightedStanceLabel>
|
|
<WeightedStanceValue score={data.source_evaluation!.stance_summary.weighted_stance_score}>
|
|
{data.source_evaluation!.stance_summary.weighted_stance_score > 0 ? '+' : ''}
|
|
{data.source_evaluation!.stance_summary.weighted_stance_score.toFixed(2)}
|
|
<WeightedStanceInterpretation>
|
|
{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)'}
|
|
</WeightedStanceInterpretation>
|
|
</WeightedStanceValue>
|
|
</WeightedStanceRow>
|
|
{!data.source_evaluation!.stance_summary.has_relevant_evidence && (
|
|
<NoRelevantEvidenceWarning>
|
|
No relevant evidence found - claim may be unverifiable
|
|
</NoRelevantEvidenceWarning>
|
|
)}
|
|
</StanceSummarySection>
|
|
)}
|
|
|
|
{/* Signal Breakdown (v3 Aggregator) - Collapsible */}
|
|
{hasAggregator && data.aggregator?.breakdown && data.aggregator.breakdown.length > 0 && (
|
|
<SignalBreakdownSection>
|
|
<ToggleHeader onClick={() => setShowSignalBreakdown(!showSignalBreakdown)}>
|
|
<SectionTitle>Signal Breakdown ({data.aggregator.breakdown.length} signals)</SectionTitle>
|
|
<ToggleIcon>{showSignalBreakdown ? '▼' : '▶'}</ToggleIcon>
|
|
</ToggleHeader>
|
|
{showSignalBreakdown && (
|
|
<SignalBreakdownContent>
|
|
{data.aggregator.breakdown.map((signal, idx) => (
|
|
<SignalCard key={idx} isDefault={signal.is_default || false}>
|
|
<SignalHeader>
|
|
<SignalName>{signal.signal_name.replace(/_/g, ' ')}</SignalName>
|
|
<SignalWeight>Weight: {(signal.weight * 100).toFixed(0)}%</SignalWeight>
|
|
{signal.is_default && (
|
|
<DefaultBadge>Using Default</DefaultBadge>
|
|
)}
|
|
</SignalHeader>
|
|
<SignalBarContainer>
|
|
<SignalBar>
|
|
<SignalBarFill
|
|
width={signal.transformed_value * 100}
|
|
color={getConfidenceColor(signal.transformed_value)}
|
|
/>
|
|
</SignalBar>
|
|
<SignalScore>{(signal.transformed_value * 100).toFixed(0)}%</SignalScore>
|
|
</SignalBarContainer>
|
|
<SignalContribution>
|
|
Contribution to score: {(signal.weighted_contribution * 100).toFixed(1)}%
|
|
</SignalContribution>
|
|
{signal.default_reason && (
|
|
<DefaultReasonText>{signal.default_reason}</DefaultReasonText>
|
|
)}
|
|
</SignalCard>
|
|
))}
|
|
<TotalScoreCard>
|
|
<TotalLabel>Aggregated Score</TotalLabel>
|
|
<TotalScore color={getConfidenceColor(data.aggregator.score)}>
|
|
{(data.aggregator.score * 100).toFixed(0)}%
|
|
</TotalScore>
|
|
</TotalScoreCard>
|
|
</SignalBreakdownContent>
|
|
)}
|
|
</SignalBreakdownSection>
|
|
)}
|
|
|
|
{/* Per-Claim Verdicts (v3) - Enhanced claims with individual verdicts */}
|
|
{hasClaimVerdicts && (
|
|
<ClaimVerdictsSection>
|
|
<ToggleHeader onClick={() => setShowClaimVerdicts(!showClaimVerdicts)}>
|
|
<SectionTitle>Claim Analysis ({data.verdict_data!.claim_verdicts.length} claims)</SectionTitle>
|
|
<ToggleIcon>{showClaimVerdicts ? '▼' : '▶'}</ToggleIcon>
|
|
</ToggleHeader>
|
|
{showClaimVerdicts && (
|
|
<ClaimVerdictsContent>
|
|
{data.verdict_data!.claim_verdicts.map((claim, idx) => (
|
|
<ClaimVerdictCard key={idx}>
|
|
<ClaimVerdictHeader>
|
|
<ClaimVerdictNumber>Claim #{idx + 1}</ClaimVerdictNumber>
|
|
<ClaimVerdictBadge color={getClaimVerdictColor(claim.verdict)}>
|
|
{claim.verdict.replace(/_/g, ' ')}
|
|
</ClaimVerdictBadge>
|
|
<ClaimVerdictScore>
|
|
{(claim.verdict_score * 100).toFixed(0)}% confidence
|
|
</ClaimVerdictScore>
|
|
</ClaimVerdictHeader>
|
|
<ClaimVerdictText>"{claim.claim_text}"</ClaimVerdictText>
|
|
<ClaimVerdictExplanation>{claim.verdict_explanation}</ClaimVerdictExplanation>
|
|
|
|
{/* Evidence For */}
|
|
{claim.evidence_used && claim.evidence_used.length > 0 && (
|
|
<EvidenceSection>
|
|
<EvidenceLabel>Evidence For ({claim.evidence_used.length}):</EvidenceLabel>
|
|
<EvidenceList>
|
|
{claim.evidence_used.map((source, sidx) => (
|
|
<EvidenceItem key={sidx} type="for">
|
|
{source.startsWith('http') ? (
|
|
<EvidenceLink href={source} target="_blank" rel="noopener noreferrer">
|
|
{source.length > 50 ? source.substring(0, 50) + '...' : source}
|
|
</EvidenceLink>
|
|
) : (
|
|
source
|
|
)}
|
|
</EvidenceItem>
|
|
))}
|
|
</EvidenceList>
|
|
</EvidenceSection>
|
|
)}
|
|
|
|
{/* Evidence Against */}
|
|
{claim.evidence_against && claim.evidence_against.length > 0 && (
|
|
<EvidenceSection>
|
|
<EvidenceLabel>Evidence Against ({claim.evidence_against.length}):</EvidenceLabel>
|
|
<EvidenceList>
|
|
{claim.evidence_against.map((source, sidx) => (
|
|
<EvidenceItem key={sidx} type="against">
|
|
{source.startsWith('http') ? (
|
|
<EvidenceLink href={source} target="_blank" rel="noopener noreferrer">
|
|
{source.length > 50 ? source.substring(0, 50) + '...' : source}
|
|
</EvidenceLink>
|
|
) : (
|
|
source
|
|
)}
|
|
</EvidenceItem>
|
|
))}
|
|
</EvidenceList>
|
|
</EvidenceSection>
|
|
)}
|
|
|
|
{/* Epistemic Assessment */}
|
|
{claim.epistemic_assessment && (
|
|
<EpistemicSection>
|
|
<EpistemicRow>
|
|
{claim.epistemic_assessment.evidence_basis && (
|
|
<EpistemicBadge type="evidence">
|
|
{claim.epistemic_assessment.evidence_basis.replace(/_/g, ' ')}
|
|
</EpistemicBadge>
|
|
)}
|
|
{claim.epistemic_assessment.claim_nature && (
|
|
<EpistemicBadge type="nature">
|
|
{claim.epistemic_assessment.claim_nature.replace(/_/g, ' ')}
|
|
</EpistemicBadge>
|
|
)}
|
|
{claim.epistemic_assessment.temporal_status && (
|
|
<EpistemicBadge type="temporal">
|
|
{claim.epistemic_assessment.temporal_status.replace(/_/g, ' ')}
|
|
</EpistemicBadge>
|
|
)}
|
|
</EpistemicRow>
|
|
{claim.epistemic_assessment.recommended_action && (
|
|
<RecommendedActionRow>
|
|
<RecommendedActionLabel>Recommended:</RecommendedActionLabel>
|
|
<RecommendedActionValue>
|
|
{claim.epistemic_assessment.recommended_action.replace(/_/g, ' ')}
|
|
</RecommendedActionValue>
|
|
</RecommendedActionRow>
|
|
)}
|
|
</EpistemicSection>
|
|
)}
|
|
</ClaimVerdictCard>
|
|
))}
|
|
</ClaimVerdictsContent>
|
|
)}
|
|
</ClaimVerdictsSection>
|
|
)}
|
|
|
|
{/* Key Claims */}
|
|
{data.key_claims && data.key_claims.length > 0 && (
|
|
<ClaimsSection>
|
|
<SectionTitle>Key Claims ({data.key_claims.length})</SectionTitle>
|
|
<ClaimsList>
|
|
{data.key_claims.map((claim, idx) => (
|
|
<ClaimCard key={idx}>
|
|
<ClaimHeader>
|
|
<ClaimNumber>#{idx + 1}</ClaimNumber>
|
|
{claim.verified !== undefined && claim.verified !== 'unknown' && (
|
|
<VerifiedBadge verified={claim.verified === true || claim.verified === 'true'}>
|
|
{claim.verified === true || claim.verified === 'true' ? 'Verified' : 'False'}
|
|
</VerifiedBadge>
|
|
)}
|
|
{claim.harm_potential && claim.harm_potential !== 'none' && (
|
|
<HarmBadge level={claim.harm_potential}>
|
|
{claim.harm_potential}
|
|
</HarmBadge>
|
|
)}
|
|
</ClaimHeader>
|
|
<ClaimText>{claim.claim}</ClaimText>
|
|
{claim.sources && claim.sources.length > 0 && (
|
|
<SourcesList>
|
|
<SourcesLabel>Sources:</SourcesLabel>
|
|
{claim.sources.map((source, sidx) => (
|
|
<SourceLink key={sidx} href={source} target="_blank" rel="noopener noreferrer">
|
|
{source}
|
|
</SourceLink>
|
|
))}
|
|
</SourcesList>
|
|
)}
|
|
{claim.notes && <ClaimNotes>{claim.notes}</ClaimNotes>}
|
|
</ClaimCard>
|
|
))}
|
|
</ClaimsList>
|
|
</ClaimsSection>
|
|
)}
|
|
|
|
{/* Manipulation Techniques */}
|
|
{data.manipulation_techniques && data.manipulation_techniques.length > 0 && (
|
|
<ManipulationSection>
|
|
<SectionTitle>Manipulation Techniques Detected</SectionTitle>
|
|
<TechniquesList>
|
|
{data.manipulation_techniques.map((tech, idx) => (
|
|
<TechniqueTag key={idx}>{tech.replace(/_/g, ' ')}</TechniqueTag>
|
|
))}
|
|
</TechniquesList>
|
|
</ManipulationSection>
|
|
)}
|
|
|
|
{/* Emotional Triggers */}
|
|
{data.emotional_triggers?.detected && (
|
|
<EmotionalSection severity={data.emotional_triggers.severity}>
|
|
<SectionTitle>Emotional Triggers</SectionTitle>
|
|
<EmotionalContent>
|
|
<SeverityBadge severity={data.emotional_triggers.severity}>
|
|
{data.emotional_triggers.severity?.toUpperCase()} severity
|
|
</SeverityBadge>
|
|
<TriggersList>
|
|
{data.emotional_triggers.types.map((trigger, idx) => (
|
|
<TriggerTag key={idx}>{trigger}</TriggerTag>
|
|
))}
|
|
</TriggersList>
|
|
</EmotionalContent>
|
|
</EmotionalSection>
|
|
)}
|
|
|
|
{/* Media Authenticity */}
|
|
{data.media_authenticity && data.media_authenticity.type !== 'text' && (
|
|
<MediaSection>
|
|
<SectionTitle>Media Authenticity</SectionTitle>
|
|
<MediaGrid>
|
|
<MediaItem>
|
|
<MediaLabel>Type:</MediaLabel>
|
|
<MediaValue>{data.media_authenticity.type?.toUpperCase()}</MediaValue>
|
|
</MediaItem>
|
|
<MediaItem>
|
|
<MediaLabel>Assessment:</MediaLabel>
|
|
<AssessmentBadge assessment={data.media_authenticity.assessment}>
|
|
{data.media_authenticity.assessment}
|
|
</AssessmentBadge>
|
|
</MediaItem>
|
|
{data.media_authenticity.manipulation_type && data.media_authenticity.manipulation_type !== 'none' && (
|
|
<MediaItem>
|
|
<MediaLabel>Manipulation:</MediaLabel>
|
|
<MediaValue>{data.media_authenticity.manipulation_type}</MediaValue>
|
|
</MediaItem>
|
|
)}
|
|
</MediaGrid>
|
|
</MediaSection>
|
|
)}
|
|
|
|
{/* Verification */}
|
|
{data.verification && (
|
|
<VerificationSection performed={data.verification.web_search_performed}>
|
|
<SectionTitle>
|
|
{data.verification.web_search_performed ? 'Web Verification Performed' : 'Verification Status'}
|
|
</SectionTitle>
|
|
{data.verification.web_search_performed ? (
|
|
<>
|
|
{data.verification.fact_check_sites_consulted && data.verification.fact_check_sites_consulted.length > 0 && (
|
|
<VerifItem>
|
|
<VerifLabel>Fact-Check Sites:</VerifLabel>
|
|
<SitesList>
|
|
{data.verification.fact_check_sites_consulted.map((site, idx) => (
|
|
<SiteTag key={idx}>{site}</SiteTag>
|
|
))}
|
|
</SitesList>
|
|
</VerifItem>
|
|
)}
|
|
{data.verification.verification_urls && data.verification.verification_urls.length > 0 && (
|
|
<VerifItem>
|
|
<VerifLabel>Verification URLs:</VerifLabel>
|
|
<UrlsList>
|
|
{data.verification.verification_urls.map((url, idx) => (
|
|
<UrlLink key={idx} href={url} target="_blank" rel="noopener noreferrer">
|
|
{url}
|
|
</UrlLink>
|
|
))}
|
|
</UrlsList>
|
|
</VerifItem>
|
|
)}
|
|
</>
|
|
) : (
|
|
<LimitationText>
|
|
{data.verification.limitations && data.verification.limitations.length > 0
|
|
? data.verification.limitations.join(', ')
|
|
: 'Basic analysis without web verification'}
|
|
</LimitationText>
|
|
)}
|
|
</VerificationSection>
|
|
)}
|
|
|
|
{/* Viral Risk */}
|
|
{data.viral_risk && (
|
|
<ViralSection level={data.viral_risk.level}>
|
|
<SectionTitle>Viral Risk Assessment</SectionTitle>
|
|
<ViralGrid>
|
|
<ViralItem>
|
|
<ViralLabel>Risk Level:</ViralLabel>
|
|
<RiskBadge level={data.viral_risk.level}>
|
|
{data.viral_risk.level?.toUpperCase()}
|
|
</RiskBadge>
|
|
</ViralItem>
|
|
<ViralItem>
|
|
<ViralLabel>Score:</ViralLabel>
|
|
<ScoreValue>{(data.viral_risk.score * 100).toFixed(0)}%</ScoreValue>
|
|
</ViralItem>
|
|
</ViralGrid>
|
|
{data.viral_risk.factors && data.viral_risk.factors.length > 0 && (
|
|
<FactorsList>
|
|
{data.viral_risk.factors.map((factor, idx) => (
|
|
<FactorTag key={idx}>{factor.replace(/_/g, ' ')}</FactorTag>
|
|
))}
|
|
</FactorsList>
|
|
)}
|
|
{data.viral_risk.assessment && (
|
|
<AssessmentText>{data.viral_risk.assessment}</AssessmentText>
|
|
)}
|
|
</ViralSection>
|
|
)}
|
|
|
|
{/* Recommendations */}
|
|
{data.recommendations && (
|
|
<RecommendationsSection urgency={data.recommendations.urgency}>
|
|
<SectionTitle>Recommendations</SectionTitle>
|
|
<RecommendationGrid>
|
|
<RecommendItem>
|
|
<RecommendLabel>Action:</RecommendLabel>
|
|
<ActionBadge action={data.recommendations.action}>
|
|
{data.recommendations.action}
|
|
</ActionBadge>
|
|
</RecommendItem>
|
|
<RecommendItem>
|
|
<RecommendLabel>Urgency:</RecommendLabel>
|
|
<UrgencyBadge level={data.recommendations.urgency}>
|
|
{data.recommendations.urgency?.toUpperCase()}
|
|
</UrgencyBadge>
|
|
</RecommendItem>
|
|
</RecommendationGrid>
|
|
{data.recommendations.reason && (
|
|
<ReasonText>{data.recommendations.reason}</ReasonText>
|
|
)}
|
|
</RecommendationsSection>
|
|
)}
|
|
|
|
{/* Source Credibility */}
|
|
{data.source_credibility && (
|
|
<SourceCredibilitySection>
|
|
<SectionTitle>Source Credibility</SectionTitle>
|
|
<CredibilityText>
|
|
{typeof data.source_credibility === 'string'
|
|
? data.source_credibility
|
|
: data.source_credibility.assessment}
|
|
</CredibilityText>
|
|
</SourceCredibilitySection>
|
|
)}
|
|
|
|
{/* Temporal Context */}
|
|
{data.temporal_context && (
|
|
<TemporalSection>
|
|
<SectionTitle>Temporal Context</SectionTitle>
|
|
<TemporalText>{data.temporal_context}</TemporalText>
|
|
</TemporalSection>
|
|
)}
|
|
|
|
{/* Confidence Factors */}
|
|
{data.confidence_factors && data.confidence_factors.length > 0 && (
|
|
<ConfidenceFactorsSection>
|
|
<SectionTitle>Confidence Factors ({data.confidence_factors.length})</SectionTitle>
|
|
<ConfidenceFactorsList>
|
|
{data.confidence_factors.map((factor, idx) => (
|
|
<ConfidenceFactorItem key={idx}>• {factor}</ConfidenceFactorItem>
|
|
))}
|
|
</ConfidenceFactorsList>
|
|
</ConfidenceFactorsSection>
|
|
)}
|
|
|
|
{/* Detailed Analysis - Collapsible */}
|
|
{data.detailed_analysis && (
|
|
<DetailedAnalysisSection>
|
|
<ToggleHeader onClick={() => setShowDetailedAnalysis(!showDetailedAnalysis)}>
|
|
<SectionTitle>Detailed Analysis</SectionTitle>
|
|
<ToggleIcon>{showDetailedAnalysis ? '▼' : '▶'}</ToggleIcon>
|
|
</ToggleHeader>
|
|
{showDetailedAnalysis && (
|
|
<DetailedContent>
|
|
{data.detailed_analysis.context_analysis && (
|
|
<DetailItem>
|
|
<DetailLabel>Context Analysis:</DetailLabel>
|
|
<DetailText>{data.detailed_analysis.context_analysis}</DetailText>
|
|
</DetailItem>
|
|
)}
|
|
{data.detailed_analysis.similar_claims && (
|
|
<DetailItem>
|
|
<DetailLabel>Similar Claims:</DetailLabel>
|
|
<DetailText>{data.detailed_analysis.similar_claims}</DetailText>
|
|
</DetailItem>
|
|
)}
|
|
{data.detailed_analysis.content_type && (
|
|
<DetailItem>
|
|
<DetailLabel>Content Type:</DetailLabel>
|
|
<DetailBadge>{data.detailed_analysis.content_type}</DetailBadge>
|
|
</DetailItem>
|
|
)}
|
|
{data.detailed_analysis.tone && (
|
|
<DetailItem>
|
|
<DetailLabel>Tone:</DetailLabel>
|
|
<DetailBadge>{data.detailed_analysis.tone}</DetailBadge>
|
|
</DetailItem>
|
|
)}
|
|
</DetailedContent>
|
|
)}
|
|
</DetailedAnalysisSection>
|
|
)}
|
|
|
|
{/* Transcription - Collapsible (for Audio/Video) */}
|
|
{data.transcription && (
|
|
<TranscriptionSection>
|
|
<ToggleHeader onClick={() => setShowTranscription(!showTranscription)}>
|
|
<SectionTitle>Transcription ({data.transcription.length} characters)</SectionTitle>
|
|
<ToggleIcon>{showTranscription ? '▼' : '▶'}</ToggleIcon>
|
|
</ToggleHeader>
|
|
{showTranscription && (
|
|
<TranscriptionContent>
|
|
{data.transcription}
|
|
</TranscriptionContent>
|
|
)}
|
|
</TranscriptionSection>
|
|
)}
|
|
</Container>
|
|
);
|
|
};
|
|
|
|
// ==================== 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;
|
|
`;
|