Mariam-cc / templates /mariam-ai-mobile.html
Docfile's picture
Upload mariam-ai-mobile.html
16d9b01 verified
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mariam AI - Analyse Littéraire</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.6/marked.min.js"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&family=Inter:wght@300;400;500;600;700&display=swap');
:root {
--primary: #4361ee;
--primary-dark: #3a56d4;
--secondary: #2b2d42;
--accent: #ef476f;
--light: #f8f9fa;
--gray-100: #f1f3f5;
--gray-200: #e9ecef;
--gray-300: #dee2e6;
--gray-400: #ced4da;
--gray-700: #495057;
--shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
--shadow-md: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -1px rgba(0,0,0,0.06);
--shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05);
--radius-sm: 0.375rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
background: linear-gradient(135deg, #f6f8fb 0%, #f1f3f5 100%);
color: var(--secondary);
line-height: 1.6;
padding-bottom: 2rem;
}
header {
background-color: white;
padding: 1.5rem 1rem;
text-align: center;
box-shadow: var(--shadow-sm);
position: relative;
z-index: 10;
}
.logo {
font-family: 'Playfair Display', serif;
font-size: 2rem;
color: var(--secondary);
margin-bottom: 0.25rem;
}
.tagline {
font-size: 0.9rem;
color: var(--gray-700);
font-weight: 500;
}
.card {
background: white;
border-radius: var(--radius-lg);
box-shadow: var(--shadow-md);
padding: 1.5rem;
margin: 1rem;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.upload-area {
border: 2px dashed var(--gray-300);
border-radius: var(--radius-md);
padding: 1.5rem 1rem;
text-align: center;
cursor: pointer;
transition: all 0.2s ease;
margin: 1.5rem 0;
}
.upload-area:hover, .upload-area.active {
border-color: var(--primary);
background-color: rgba(67, 97, 238, 0.05);
}
.upload-icon {
width: 3.5rem;
height: 3.5rem;
margin: 0 auto 1rem;
color: var(--gray-400);
}
.upload-area:hover .upload-icon, .upload-area.active .upload-icon {
color: var(--primary);
}
.input-group {
margin-bottom: 1.5rem;
}
.label {
display: block;
margin-bottom: 0.5rem;
font-weight: 600;
font-size: 0.9rem;
}
.input {
width: 100%;
padding: 0.75rem;
border: 1px solid var(--gray-300);
border-radius: var(--radius-md);
font-family: 'Inter', sans-serif;
font-size: 1rem;
transition: border-color 0.2s ease;
}
.input:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.1);
}
.preview-container {
margin: 1.5rem 0;
}
.preview-title {
font-weight: 600;
margin-bottom: 0.5rem;
font-size: 0.9rem;
}
.preview-image-container {
background-color: var(--gray-100);
border-radius: var(--radius-md);
overflow: hidden;
position: relative;
}
.preview-image {
max-width: 100%;
max-height: 15rem;
margin: 0 auto;
display: block;
}
.btn {
display: block;
width: 100%;
padding: 0.875rem;
font-weight: 600;
text-align: center;
border: none;
border-radius: var(--radius-md);
cursor: pointer;
transition: all 0.2s ease;
font-size: 1rem;
}
.btn-primary {
background-color: var(--primary);
color: white;
}
.btn-primary:hover, .btn-primary:focus {
background-color: var(--primary-dark);
transform: translateY(-1px);
box-shadow: var(--shadow-md);
}
.btn-primary:active {
transform: translateY(0);
}
.loading-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 100;
}
.loading-card {
background-color: white;
padding: 2rem;
border-radius: var(--radius-lg);
box-shadow: var(--shadow-lg);
text-align: center;
max-width: 80%;
}
.spinner {
width: 3rem;
height: 3rem;
border: 4px solid var(--gray-200);
border-radius: 50%;
border-top-color: var(--primary);
animation: spin 1s linear infinite;
margin: 0 auto 1rem;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.result-card {
padding: 0;
overflow: hidden;
}
.tabs {
display: flex;
border-bottom: 1px solid var(--gray-200);
}
.tab {
flex: 1;
text-align: center;
padding: 1rem 0.5rem;
font-weight: 600;
font-size: 0.9rem;
color: var(--gray-700);
background-color: transparent;
border: none;
border-bottom: 2px solid transparent;
cursor: pointer;
}
.tab.active {
color: var(--primary);
border-bottom-color: var(--primary);
}
.tab-content {
padding: 1.5rem;
}
.custom-prose {
font-size: 1rem;
line-height: 1.8;
}
.custom-prose h1, .custom-prose h2, .custom-prose h3 {
font-family: 'Playfair Display', serif;
margin-top: 1.5em;
margin-bottom: 0.75em;
line-height: 1.3;
}
.custom-prose h1 {
font-size: 1.75rem;
}
.custom-prose h2 {
font-size: 1.5rem;
}
.custom-prose h3 {
font-size: 1.25rem;
}
.custom-prose p {
margin-bottom: 1.25em;
}
.custom-prose ul, .custom-prose ol {
margin-top: 1em;
margin-bottom: 1em;
padding-left: 1.5em;
}
.custom-prose li {
margin-bottom: 0.5em;
}
.markdown-table {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.markdown-table table {
width: 100%;
border-collapse: separate;
border-spacing: 0;
margin: 1em 0;
}
.markdown-table th {
background: var(--primary);
color: white;
font-weight: 600;
padding: 0.75rem;
text-align: left;
font-size: 0.9rem;
}
.markdown-table td {
padding: 0.75rem;
border-bottom: 1px solid var(--gray-200);
font-size: 0.9rem;
}
.markdown-table tr:hover {
background: var(--gray-100);
}
.upload-instructions {
font-size: 0.85rem;
color: var(--gray-700);
margin-top: 0.5rem;
}
.file-input {
display: none;
}
.slide-up {
animation: slide-up 0.4s ease forwards;
}
@keyframes slide-up {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.shimmer {
position: absolute;
top: 0;
left: -100%;
width: 50%;
height: 100%;
background: linear-gradient(90deg,
rgba(255,255,255,0) 0%,
rgba(255,255,255,0.2) 50%,
rgba(255,255,255,0) 100%);
animation: shimmer 2s infinite;
}
@keyframes shimmer {
to {
left: 100%;
}
}
</style>
</head>
<body>
<header>
<h1 class="logo">Mariam AI</h1>
<p class="tagline">Assistant d'Analyse Littéraire</p>
</header>
<main>
<div class="card">
<form id="uploadForm">
<div class="input-group">
<label for="imageInput" class="label">Votre document</label>
<div id="uploadArea" class="upload-area">
<svg class="upload-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
</svg>
<p>Touchez pour télécharger</p>
<p class="upload-instructions">PNG, JPG jusqu'à 10MB</p>
<input id="imageInput" type="file" class="file-input" accept="image/*" required>
</div>
</div>
<div class="input-group">
<label for="consignesInput" class="label">Consignes (optionnel)</label>
<input id="consignesInput" type="text" class="input" placeholder="Entrez vos consignes ici">
</div>
<div id="previewContainer" class="preview-container" style="display: none;">
<p class="preview-title">Aperçu du document</p>
<div class="preview-image-container">
<img id="previewImage" class="preview-image" src="#" alt="Aperçu">
</div>
</div>
<button type="submit" class="btn btn-primary">
Lancer l'analyse
</button>
</form>
</div>
<div id="result" class="card result-card" style="display: none;">
<div class="tabs">
<button id="dissertationTab" class="tab active">Dissertation</button>
<button id="tableauTab" class="tab">Tableau</button>
</div>
<div class="tab-content">
<div id="dissertationContent" class="custom-prose"></div>
<div id="tableauContent" class="markdown-table" style="display: none;"></div>
</div>
</div>
</main>
<div id="loading" class="loading-overlay" style="display: none;">
<div class="loading-card">
<div class="spinner"></div>
<p>Analyse en cours...</p>
</div>
</div>
<script>
const uploadForm = document.getElementById('uploadForm');
const imageInput = document.getElementById('imageInput');
const uploadArea = document.getElementById('uploadArea');
const previewContainer = document.getElementById('previewContainer');
const previewImage = document.getElementById('previewImage');
const loadingIndicator = document.getElementById('loading');
const resultDiv = document.getElementById('result');
const dissertationTab = document.getElementById('dissertationTab');
const tableauTab = document.getElementById('tableauTab');
const dissertationContent = document.getElementById('dissertationContent');
const tableauContent = document.getElementById('tableauContent');
// Configuration de marked
marked.setOptions({
breaks: true,
gfm: true
});
// Événements tactiles pour l'upload
uploadArea.addEventListener('click', function() {
imageInput.click();
});
// Effet visuel au toucher pour mobiles
uploadArea.addEventListener('touchstart', function() {
this.classList.add('active');
});
uploadArea.addEventListener('touchend', function() {
this.classList.remove('active');
});
// Prévisualisation
imageInput.addEventListener('change', function() {
const file = this.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
previewImage.src = e.target.result;
previewContainer.style.display = 'block';
previewContainer.classList.add('slide-up');
// Animation de l'effet de focus
uploadArea.classList.add('active');
setTimeout(() => uploadArea.classList.remove('active'), 500);
}
reader.readAsDataURL(file);
} else {
previewContainer.style.display = 'none';
}
});
// Gestion des onglets
dissertationTab.addEventListener('click', function() {
dissertationTab.classList.add('active');
tableauTab.classList.remove('active');
dissertationContent.style.display = 'block';
tableauContent.style.display = 'none';
});
tableauTab.addEventListener('click', function() {
tableauTab.classList.add('active');
dissertationTab.classList.remove('active');
tableauContent.style.display = 'block';
dissertationContent.style.display = 'none';
});
// Soumission du formulaire
uploadForm.addEventListener('submit', function(e) {
e.preventDefault();
loadingIndicator.style.display = 'flex';
// Simulation de l'envoi et réception des données
// Dans une application réelle, utilisez fetch() comme dans le code original
setTimeout(() => {
loadingIndicator.style.display = 'none';
// Données fictives pour la démonstration
const data = {
dissertation: `# Analyse de Baudelaire: Les Fleurs du Mal
Dans cette œuvre majeure du XIXe siècle, Baudelaire révèle la dualité de l'existence humaine à travers une poésie à la fois sublime et déchirante.
## Le spleen et l'idéal
Baudelaire explore la tension entre l'aspiration à la beauté et le poids de l'existence quotidienne. Cette dualité constitue l'essence même de sa poétique.
## La modernité baudelairienne
En faisant de la ville et de ses aspects les plus sombres un objet poétique, Baudelaire invente une nouvelle façon de percevoir la modernité et influence toute la poésie qui suivra.`,
tableau: `| Thème | Poèmes représentatifs | Analyse |
|-------|----------------------|---------|
| Spleen | "Spleen I-IV", "De profundis clamavi" | Expression du mal-être, ennui, mélancolie |
| Idéal | "L'Invitation au voyage", "Élévation" | Aspiration vers la beauté, évasion |
| Amour | "À une passante", "Le Vampire" | Amour impossible, femme fatale |
| Mort | "La Charogne", "Une Martyre" | Fascination pour la décomposition |`
};
dissertationContent.innerHTML = marked.parse(data.dissertation);
tableauContent.innerHTML = marked.parse(data.tableau);
resultDiv.style.display = 'block';
resultDiv.classList.add('slide-up');
// Scroll vers les résultats
resultDiv.scrollIntoView({ behavior: 'smooth' });
}, 2000);
});
// Amélioration de l'expérience tactile
document.addEventListener('DOMContentLoaded', function() {
const interactiveElements = document.querySelectorAll('.btn, .tab, .upload-area');
interactiveElements.forEach(el => {
el.addEventListener('touchstart', function() {
this.style.transform = 'scale(0.98)';
});
el.addEventListener('touchend', function() {
this.style.transform = 'scale(1)';
});
});
});
</script>
</body>
</html>