quantum-ai/data_analyzer/templates/data_analyzer/detail.html
Claude 8e3cf451a1 Rebrand platform from NetCop Hub to Quantum Tasks AI
- Update domain configuration to quantumtaskai.com
- Change all page titles and branding across templates
- Update Stripe integration with new domain URLs
- Modify settings.py for new domain and cache prefixes
- Update project documentation and test files
- Change company name and contact information

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 22:21:45 +05:30

929 lines
30 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends 'base.html' %}
{% load static %}
{% block title %}Data Analyzer - Quantum Tasks AI{% endblock %}
{% block extra_css %}
<link rel="stylesheet" href="{% static 'css/agent-base.css' %}?v={{ timestamp }}">
{% endblock %}
{% block content %}
<script>
// Consolidated DOMContentLoaded initialization
document.addEventListener('DOMContentLoaded', function() {
// Set data for JavaScript access
document.body.setAttribute('data-user-authenticated', '{{ user.is_authenticated|yesno:"true,false" }}');
document.body.setAttribute('data-agent-price', '5.00');
// Initialize form submission
const form = document.getElementById('agentForm');
if (form) {
form.addEventListener('submit', handleFormSubmission);
}
// Initialize file upload
const fileInput = document.getElementById('dataFile');
if (fileInput) {
fileInput.addEventListener('change', handleFileChange);
}
// Initialize drag and drop
const uploadArea = document.querySelector('.file-upload-area');
if (uploadArea) {
setupDragAndDrop(uploadArea, fileInput);
}
// Set initial radio selection
const firstRadio = document.querySelector('.radio-card');
if (firstRadio && !document.querySelector('.radio-card.selected')) {
firstRadio.classList.add('selected');
const input = firstRadio.querySelector('input[type="radio"]');
if (input) input.checked = true;
}
});
// Data Analyzer Utils
const DataAnalyzerUtils = {
// Update wallet balance display
updateWalletBalance(newBalance) {
if (newBalance !== undefined) {
// Update header balance
const headerBalance = document.querySelector('a[data-wallet-balance]');
if (headerBalance) {
headerBalance.textContent = `💰 ${newBalance.toFixed(2)} AED`;
}
// Update page balance
const pageBalance = document.getElementById('walletBalance');
if (pageBalance) {
pageBalance.textContent = newBalance.toFixed(2);
}
// Update all data attributes
document.querySelectorAll('[data-wallet-balance]').forEach(element => {
element.textContent = `${newBalance.toFixed(2)} AED`;
});
// Store current balance globally
window.currentWalletBalance = newBalance;
}
},
// Show toast notification
showToast(message, type = 'info') {
// Remove existing toasts
document.querySelectorAll('.toast').forEach(toast => toast.remove());
// Create new toast
const toast = document.createElement('div');
toast.className = `toast ${type}`;
toast.textContent = message;
// Add to page
document.body.appendChild(toast);
// Show toast
setTimeout(() => toast.classList.add('show'), 100);
// Auto remove after 3 seconds
setTimeout(() => {
toast.classList.remove('show');
setTimeout(() => toast.remove(), 300);
}, 3000);
},
// Display processing status
showProcessing() {
const processingStatus = document.getElementById('processingStatus');
const resultsContainer = document.getElementById('resultsContainer');
if (processingStatus) processingStatus.style.display = 'block';
if (resultsContainer) resultsContainer.style.display = 'none';
this.showToast('🔄 Processing your data file...', 'success');
},
// Hide processing status
hideProcessing() {
const processingStatus = document.getElementById('processingStatus');
if (processingStatus) processingStatus.style.display = 'none';
},
// Display analysis results
displayResults(result) {
const resultsContainer = document.getElementById('resultsContainer');
const resultsContent = document.getElementById('resultsContent');
const processingStatus = document.getElementById('processingStatus');
if (result.success) {
// Hide processing status
this.hideProcessing();
// Show results with rich formatting
const analysisText = result.report_text || result.insights_summary || result.analysis_results || 'Analysis completed successfully.';
if (resultsContent) {
// Convert newlines to HTML and preserve formatting
const formattedText = analysisText
.replace(/\n\n/g, '</p><p>')
.replace(/\n/g, '<br>')
.replace(/### (.*?)(<br>|$)/g, '<h3>$1</h3>')
.replace(/## (.*?)(<br>|$)/g, '<h2>$1</h2>')
.replace(/# (.*?)(<br>|$)/g, '<h1>$1</h1>')
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
.replace(/\*(.*?)\*/g, '<em>$1</em>');
resultsContent.innerHTML = `<p>${formattedText}</p>`;
}
// Show results container
if (resultsContainer) {
resultsContainer.style.display = 'block';
}
// Update wallet balance if provided
if (result.wallet_balance !== undefined) {
this.updateWalletBalance(result.wallet_balance);
}
this.showToast('✅ Data analysis completed successfully!', 'success');
} else if (result.error) {
this.hideProcessing();
this.showToast(`❌ Error: ${result.error}`, 'error');
} else {
this.hideProcessing();
this.showToast('❌ Analysis failed. Please try again.', 'error');
}
}
};
// For backward compatibility
const AgentUtils = DataAnalyzerUtils;
// Modern Radio Selection
function selectRadio(value) {
// Remove selected class from all cards
document.querySelectorAll('.radio-card').forEach(card => {
card.classList.remove('selected');
});
// Add selected class to clicked card
const selectedCard = document.querySelector(`input[value="${value}"]`).closest('.radio-card');
if (selectedCard) {
selectedCard.classList.add('selected');
}
// Select the radio button
const radioInput = document.getElementById(value);
if (radioInput) {
radioInput.checked = true;
}
}
// File upload handling
function handleFileChange(event) {
const file = event.target.files[0];
const uploadArea = document.querySelector('.file-upload-area');
const uploadText = document.querySelector('.upload-text');
if (file) {
uploadArea.classList.add('file-selected');
uploadText.innerHTML = `
<div style="display: flex; align-items: center; gap: 8px;">
<span>📄</span>
<div>
<div style="font-weight: 500;">${file.name}</div>
<div style="font-size: 12px; color: var(--on-surface-variant);">${(file.size / 1024 / 1024).toFixed(2)} MB</div>
</div>
</div>
`;
DataAnalyzerUtils.showToast(`File selected: ${file.name}`, 'success');
} else {
uploadArea.classList.remove('file-selected');
uploadText.innerHTML = `
<div class="upload-icon">📁</div>
<div><strong>Click to upload</strong> or drag and drop</div>
<div>PDF files only</div>
`;
}
}
// Drag and drop setup
function setupDragAndDrop(uploadArea, fileInput) {
let dragCounter = 0;
function handleDragOver(e) {
e.preventDefault();
e.stopPropagation();
uploadArea.classList.add('drag-over');
}
function handleDragLeave(e) {
e.preventDefault();
e.stopPropagation();
dragCounter--;
if (dragCounter <= 0) {
uploadArea.classList.remove('drag-over');
dragCounter = 0;
}
}
function handleDragEnter(e) {
e.preventDefault();
e.stopPropagation();
dragCounter++;
uploadArea.classList.add('drag-over');
}
function handleDrop(e) {
e.preventDefault();
e.stopPropagation();
dragCounter = 0;
uploadArea.classList.remove('drag-over');
const files = e.dataTransfer.files;
if (files.length > 0) {
fileInput.files = files;
handleFileChange({ target: fileInput });
}
}
uploadArea.addEventListener('dragenter', handleDragEnter);
uploadArea.addEventListener('dragover', handleDragOver);
uploadArea.addEventListener('dragleave', handleDragLeave);
uploadArea.addEventListener('drop', handleDrop);
}
// Form validation
function isFormValid() {
const fileInput = document.getElementById('dataFile');
const analysisType = document.querySelector('input[name="analysisType"]:checked');
if (!fileInput.files || fileInput.files.length === 0) {
DataAnalyzerUtils.showToast('Please select a data file', 'error');
return false;
}
if (!analysisType) {
DataAnalyzerUtils.showToast('Please select an analysis type', 'error');
return false;
}
return true;
}
// Copy analysis results
function copyResults() {
const content = document.getElementById('resultsContent');
if (content) {
const text = content.textContent || '';
navigator.clipboard.writeText(text).then(() => {
DataAnalyzerUtils.showToast('📋 Analysis results copied to clipboard!', 'success');
}).catch(() => {
DataAnalyzerUtils.showToast('❌ Failed to copy to clipboard', 'error');
});
}
}
// Download analysis results
function downloadResults() {
const content = document.getElementById('resultsContent');
if (content) {
const text = content.textContent || '';
const blob = new Blob([text], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'data-analysis-results.txt';
a.click();
URL.revokeObjectURL(url);
DataAnalyzerUtils.showToast('💾 Analysis results downloaded!', 'success');
}
}
// Reset form for new analysis
function resetForm() {
const form = document.getElementById('agentForm');
if (form) {
form.reset();
}
const resultsContainer = document.getElementById('resultsContainer');
const processingStatus = document.getElementById('processingStatus');
if (resultsContainer) resultsContainer.style.display = 'none';
if (processingStatus) processingStatus.style.display = 'none';
// Reset file upload area
const uploadArea = document.querySelector('.file-upload-area');
const uploadText = document.querySelector('.upload-text');
if (uploadArea) uploadArea.classList.remove('file-selected');
if (uploadText) {
uploadText.innerHTML = `
<div class="upload-icon">📁</div>
<div><strong>Click to upload</strong> or drag and drop</div>
<div>PDF files only</div>
`;
}
// Reset radio selection
document.querySelectorAll('.radio-card').forEach(card => {
card.classList.remove('selected');
});
const firstCard = document.querySelector('.radio-card');
if (firstCard) {
firstCard.classList.add('selected');
const input = firstCard.querySelector('input[type="radio"]');
if (input) input.checked = true;
}
DataAnalyzerUtils.showToast('🔄 Form reset - ready for new analysis', 'success');
}
// Quick Agent Access Functions
function toggleQuickAgents() {
const panel = document.getElementById('quickAgentsPanel');
const overlay = document.getElementById('quickAgentsOverlay');
const toggle = document.querySelector('.quick-agent-toggle');
if (!panel || !overlay) return;
const isActive = panel.classList.contains('active');
if (isActive) {
// Close panel
panel.classList.remove('active');
overlay.classList.remove('active');
if (toggle) toggle.classList.remove('active');
// Update ARIA attributes
if (toggle) toggle.setAttribute('aria-expanded', 'false');
panel.setAttribute('aria-hidden', 'true');
overlay.setAttribute('aria-hidden', 'true');
} else {
// Open panel
panel.classList.add('active');
overlay.classList.add('active');
if (toggle) toggle.classList.add('active');
// Update ARIA attributes
if (toggle) toggle.setAttribute('aria-expanded', 'true');
panel.setAttribute('aria-hidden', 'false');
overlay.setAttribute('aria-hidden', 'false');
}
}
function closeQuickAgents() {
const panel = document.getElementById('quickAgentsPanel');
const overlay = document.getElementById('quickAgentsOverlay');
const toggle = document.querySelector('.quick-agent-toggle');
if (panel) panel.classList.remove('active');
if (overlay) overlay.classList.remove('active');
if (toggle) toggle.classList.remove('active');
// Update ARIA attributes
if (toggle) toggle.setAttribute('aria-expanded', 'false');
if (panel) panel.setAttribute('aria-hidden', 'true');
if (overlay) overlay.setAttribute('aria-hidden', 'true');
}
// Form submission handler
function handleFormSubmission(e) {
e.preventDefault();
if (!isFormValid()) {
return;
}
// Check authentication and balance
const isAuthenticated = document.body.getAttribute('data-user-authenticated') === 'true';
if (!isAuthenticated) {
DataAnalyzerUtils.showToast('Please login to continue', 'error');
window.location.href = "{% url 'authentication:login' %}";
return;
}
const walletBalance = parseFloat(document.getElementById('walletBalance')?.textContent) || 0;
if (walletBalance < 5.00) {
DataAnalyzerUtils.showToast('Insufficient wallet balance', 'error');
setTimeout(() => {
window.location.href = "{% url 'wallet:wallet' %}";
}, 2000);
return;
}
// Show processing status
DataAnalyzerUtils.showProcessing();
// Submit form with AJAX
const formData = new FormData(e.target);
fetch(window.location.href, {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(result => {
if (result.success && result.request_id) {
// Start polling for results
checkResults(result.request_id);
DataAnalyzerUtils.updateWalletBalance(result.wallet_balance);
} else {
DataAnalyzerUtils.hideProcessing();
DataAnalyzerUtils.showToast(`${result.error || 'Processing failed'}`, 'error');
}
})
.catch(error => {
console.error('Form submission error:', error);
DataAnalyzerUtils.hideProcessing();
DataAnalyzerUtils.showToast('❌ Connection error. Please try again.', 'error');
});
}
// Check results (polling for webhook completion)
function checkResults(requestId) {
let pollCount = 0;
const maxPolls = 30; // 5 minutes max
const pollInterval = setInterval(() => {
pollCount++;
fetch(`/agents/data-analyzer/status/${requestId}/`)
.then(response => response.json())
.then(result => {
if (result.status === 'completed') {
clearInterval(pollInterval);
DataAnalyzerUtils.displayResults(result);
} else if (result.status === 'failed') {
clearInterval(pollInterval);
DataAnalyzerUtils.hideProcessing();
DataAnalyzerUtils.showToast('❌ Analysis failed. Please try again.', 'error');
} else if (pollCount >= maxPolls) {
clearInterval(pollInterval);
DataAnalyzerUtils.hideProcessing();
DataAnalyzerUtils.showToast('⏰ Analysis is taking longer than expected. Please check back later.', 'error');
}
// Continue polling if still processing
})
.catch(error => {
console.error('Status check error:', error);
if (pollCount >= maxPolls) {
clearInterval(pollInterval);
DataAnalyzerUtils.hideProcessing();
DataAnalyzerUtils.showToast('❌ Connection error during processing.', 'error');
}
});
}, 10000); // Check every 10 seconds
}
// Close panel with Escape key
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
closeQuickAgents();
}
});
</script>
<div class="agent-container">
<!-- Agent Header -->
{% include "components/agent_header.html" with agent_title="Data Analyzer" agent_subtitle="AI-powered analysis of your data files with comprehensive insights" %}
<!-- Quick Agent Access Panel -->
{% include "components/quick_agents_panel.html" %}
<!-- Agent Grid -->
<div class="agent-grid">
<!-- Data Analysis Form Widget -->
<div class="agent-widget widget-large" style="flex: 1; margin-right: clamp(0px, var(--spacing-lg), 2vw);">
<div class="widget-header">
<h3 class="widget-title">
<span class="widget-icon">📊</span>
Data Analysis Configuration
</h3>
</div>
<div class="widget-content">
<form id="agentForm" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<!-- File Upload -->
<div class="form-group">
<label class="form-label">📁 Upload Data File</label>
<div class="file-upload-area" onclick="document.getElementById('dataFile').click()"
role="button" tabindex="0" aria-label="Click to upload data file or drag and drop"
onkeydown="if(event.key==='Enter'||event.key===' '){document.getElementById('dataFile').click()}">
<div class="upload-text">
<div class="upload-icon">📁</div>
<div><strong>Click to upload</strong> or drag and drop</div>
<div>PDF files only</div>
</div>
</div>
<input type="file" id="dataFile" name="file" accept=".pdf" style="display: none;" required>
<div class="form-help">Supported format: PDF files only. Max size: 10MB</div>
</div>
<!-- Analysis Type Selection -->
<div class="form-group">
<label class="form-label">📈 Analysis Type</label>
<div class="radio-grid">
<div class="radio-card selected" onclick="selectRadio('summary')">
<input type="radio" id="summary" name="analysisType" value="summary" checked>
<div class="radio-button"></div>
<label for="summary" class="radio-label">📋 Summary</label>
</div>
<div class="radio-card" onclick="selectRadio('detailed')">
<input type="radio" id="detailed" name="analysisType" value="detailed">
<div class="radio-button"></div>
<label for="detailed" class="radio-label">📈 Detailed</label>
</div>
<div class="radio-card" onclick="selectRadio('statistical')">
<input type="radio" id="statistical" name="analysisType" value="statistical">
<div class="radio-button"></div>
<label for="statistical" class="radio-label">🔢 Statistical</label>
</div>
</div>
</div>
<!-- Submit Button -->
<div style="margin-top: var(--spacing-lg);">
{% if user.is_authenticated %}
{% if user.wallet_balance >= 5.00 %}
<button type="submit" class="btn btn-primary btn-full" id="analyzeBtn">
🚀 Analyze Data (5.00 AED)
</button>
{% else %}
<div style="background: #fef2f2; color: #dc2626; padding: var(--spacing-md); border-radius: var(--radius-md); margin-bottom: var(--spacing-md); font-size: 14px; font-weight: 500; text-align: center;">
Insufficient balance! You need 5.00 AED.
</div>
<a href="{% url 'wallet:wallet' %}" class="btn btn-primary btn-full" style="text-decoration: none;">
💰 Top Up Wallet
</a>
{% endif %}
{% else %}
<a href="{% url 'authentication:login' %}" class="btn btn-primary btn-full">
🔐 Login to Continue
</a>
{% endif %}
</div>
</form>
</div>
</div>
<!-- How It Works Widget - Positioned on the right -->
<div class="agent-widget widget-small" style="min-width: min(280px, 100%); max-width: min(280px, 100%); margin-left: auto;">
<div class="widget-header">
<h3 class="widget-title">
<span class="widget-icon"></span>
How It Works
</h3>
</div>
<div class="widget-content">
<ol class="info-list">
<li>Upload your PDF file</li>
<li>Choose analysis type and preferences</li>
<li>Our AI analyzes your data</li>
<li>Get comprehensive insights and reports</li>
</ol>
<!-- Other Agents Button -->
<button class="quick-agent-toggle btn btn-secondary btn-full" onclick="toggleQuickAgents()"
title="Quick access to other agents"
aria-label="Open quick access panel for other AI agents"
aria-expanded="false"
aria-controls="quickAgentsPanel"
style="margin-top: var(--spacing-md);">
<span class="toggle-icon" aria-hidden="true">🚀</span>
<span class="toggle-text">Explore Other Agents</span>
</button>
</div>
</div>
</div>
<!-- Main Content Grid -->
<div class="agent-grid">
<!-- Processing Status -->
{% include "components/processing_status.html" with status_title="Analyzing Your Data..." status_text="Please wait while our AI processes your file..." %}
<!-- Results Widget -->
{% include "components/results_container.html" with results_title="Analysis Results" %}
</div>
</div>
<style>
/* Data Analyzer Specific Styles */
.file-upload-area {
border: 2px dashed var(--outline);
border-radius: var(--radius-md);
padding: var(--spacing-xl);
text-align: center;
cursor: pointer;
transition: all 0.2s ease;
background: var(--surface-variant);
margin-bottom: var(--spacing-sm);
}
.file-upload-area:hover {
border-color: var(--primary);
background: var(--surface);
transform: translateY(-1px);
box-shadow: var(--shadow-sm);
}
.file-upload-area.drag-over {
border-color: var(--primary);
background: rgba(0, 0, 0, 0.02);
transform: scale(1.02);
}
.file-upload-area.file-selected {
border-color: var(--success);
background: #f0fdf4;
color: #16a34a;
}
.upload-icon {
font-size: 48px;
margin-bottom: var(--spacing-md);
opacity: 0.7;
}
.upload-text {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--spacing-sm);
color: var(--on-surface-variant);
}
.upload-text > div:first-child {
font-weight: 500;
color: var(--on-surface);
}
.radio-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: var(--spacing-md);
margin-top: var(--spacing-sm);
}
.radio-card {
display: flex;
align-items: center;
gap: var(--spacing-sm);
padding: var(--spacing-md);
border: 2px solid var(--outline-variant);
border-radius: var(--radius-md);
cursor: pointer;
transition: all 0.2s ease;
background: var(--surface);
position: relative;
}
.radio-card:hover {
border-color: var(--primary);
background: var(--surface-variant);
transform: translateY(-1px);
box-shadow: var(--shadow-sm);
}
.radio-card.selected {
border-color: var(--primary);
background: rgba(0, 0, 0, 0.02);
}
.radio-card input[type="radio"] {
position: absolute;
opacity: 0;
pointer-events: none;
}
.radio-button {
width: 20px;
height: 20px;
border: 2px solid var(--outline);
border-radius: 50%;
position: relative;
transition: all 0.2s ease;
flex-shrink: 0;
}
.radio-card.selected .radio-button {
border-color: var(--primary);
}
.radio-card.selected .radio-button::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 8px;
height: 8px;
background: var(--primary);
border-radius: 50%;
transform: translate(-50%, -50%);
}
.radio-label {
font-size: 14px;
font-weight: 500;
color: var(--on-surface);
cursor: pointer;
display: flex;
align-items: center;
gap: var(--spacing-xs);
}
/* Toast Notifications */
.toast {
position: fixed;
top: 20px;
right: 20px;
background: var(--surface);
border: 1px solid var(--outline);
border-radius: var(--radius-md);
padding: var(--spacing-md) var(--spacing-lg);
box-shadow: var(--shadow-lg);
z-index: 1000;
max-width: 400px;
font-size: 14px;
font-weight: 500;
transform: translateX(100%);
transition: transform 0.3s ease;
}
.toast.show {
transform: translateX(0);
}
.toast.success {
border-color: var(--success);
background: #f0fdf4;
color: #16a34a;
}
.toast.error {
border-color: var(--error);
background: #fef2f2;
color: #dc2626;
}
/* Enhanced Results Display - Restored from Original */
.results-content {
background: var(--surface-variant);
border-radius: var(--radius-md);
padding: var(--spacing-xl);
margin-bottom: var(--spacing-lg);
line-height: 1.7;
color: var(--on-surface);
font-size: 15px;
}
/* Enhanced Results Typography */
.results-content h1,
.results-content h2,
.results-content h3 {
color: var(--primary);
font-weight: 700;
margin: var(--spacing-xl) 0 var(--spacing-md) 0;
line-height: 1.3;
}
.results-content h1 {
font-size: 24px;
border-bottom: 3px solid var(--primary);
padding-bottom: var(--spacing-sm);
margin-bottom: var(--spacing-lg);
}
.results-content h2 {
font-size: 20px;
margin-top: var(--spacing-xl);
position: relative;
padding-left: var(--spacing-md);
}
.results-content h2::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 4px;
background: var(--primary);
border-radius: 2px;
}
.results-content h3 {
font-size: 18px;
color: var(--on-surface);
font-weight: 600;
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
padding: var(--spacing-md) var(--spacing-lg);
border-radius: var(--radius-sm);
border-left: 4px solid var(--primary);
margin: var(--spacing-lg) 0 var(--spacing-md) 0;
}
.results-content p {
margin: var(--spacing-md) 0;
text-align: justify;
}
.results-content ul,
.results-content ol {
margin: var(--spacing-md) 0;
padding-left: var(--spacing-xl);
}
.results-content li {
margin: var(--spacing-sm) 0;
position: relative;
}
.results-content ul li::marker {
color: var(--primary);
font-weight: bold;
}
.results-content ol li::marker {
color: var(--primary);
font-weight: bold;
}
/* Modern Info Boxes */
.results-content .key-points,
.results-content .insights,
.results-content .summary {
background: var(--surface);
border: 1px solid var(--outline-variant);
border-radius: var(--radius-md);
padding: var(--spacing-lg);
margin: var(--spacing-lg) 0;
box-shadow: var(--shadow-sm);
}
.results-content .key-points {
border-left: 4px solid #3b82f6;
}
.results-content .insights {
border-left: 4px solid #10b981;
}
.results-content .summary {
border-left: 4px solid #f59e0b;
}
/* Strong text styling */
.results-content strong {
color: var(--primary);
font-weight: 600;
}
/* Code and technical terms */
.results-content code {
background: #f1f5f9;
padding: 2px 6px;
border-radius: 4px;
font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
font-size: 14px;
color: #1e293b;
}
@media (max-width: 768px) {
.radio-grid {
grid-template-columns: 1fr;
}
.toast {
left: 20px;
right: 20px;
max-width: none;
transform: translateY(-100%);
}
.toast.show {
transform: translateY(0);
}
.results-content {
padding: var(--spacing-md);
font-size: 14px;
}
.results-content h1 {
font-size: 20px;
}
.results-content h2 {
font-size: 18px;
}
.results-content h3 {
font-size: 16px;
padding: var(--spacing-sm) var(--spacing-md);
}
}
</style>
{% endblock %}