1655 lines
74 KiB
HTML
1655 lines
74 KiB
HTML
{% extends "base.html" %}
|
||
{% from 'components/common/macros.html' import hero_section %}
|
||
|
||
{% block title %}Préparation Conseil de Classe - {{ class_group.name }} - T{{ trimester }}{% endblock %}
|
||
|
||
{# Override le style du main container pour éviter le clipping des hover effects #}
|
||
{% block main_class %}w-full px-8 py-8 bg-gray-100{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="council-preparation" data-council-preparation data-class-id="{{ class_group.id }}" data-trimester="{{ trimester }}">
|
||
|
||
<!-- Loading overlay -->
|
||
<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50" data-loading-overlay>
|
||
<div class="bg-white rounded-xl p-6 flex items-center space-x-3">
|
||
<svg class="animate-spin w-6 h-6 text-purple-600" fill="none" viewBox="0 0 24 24">
|
||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||
</svg>
|
||
<span class="text-gray-700 font-medium">Chargement...</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="max-w-7xl mx-auto">
|
||
<div class="space-y-8" style="overflow: visible; padding: 8px; margin: -8px;">
|
||
|
||
{# 1. Hero Section #}
|
||
{% set meta_info = [
|
||
{
|
||
'icon': '<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20"><path d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"/></svg>',
|
||
'text': council_data.total_students ~ ' élèves'
|
||
},
|
||
{
|
||
'icon': '<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z" clip-rule="evenodd"/></svg>',
|
||
'text': 'Trimestre ' ~ trimester
|
||
},
|
||
{
|
||
'icon': '<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1117.07 2.93 10 10 0 012.93 17.07zM11.4 10.6L9 8.2V4.5a.5.5 0 00-1 0v4a.5.5 0 00.15.35l2.7 2.7a.5.5 0 00.7-.7z"/></svg>',
|
||
'text': council_data.completed_appreciations ~ '/' ~ council_data.total_students ~ ' appréciations rédigées'
|
||
}
|
||
] %}
|
||
|
||
<div class="list-mode-hero">
|
||
{{ hero_section(
|
||
title="📊 Préparation Conseil de Classe",
|
||
subtitle="Rédaction des appréciations • " + class_group.name,
|
||
meta_info=meta_info,
|
||
gradient_class="from-purple-600 to-orange-500"
|
||
) }}
|
||
</div>
|
||
|
||
{# Breadcrumb de retour et sélecteur de trimestre #}
|
||
<div class="list-mode-breadcrumb flex flex-col sm:flex-row sm:items-center justify-between space-y-3 sm:space-y-0">
|
||
<div class="flex items-center text-sm text-gray-600">
|
||
<a href="{{ url_for('classes.dashboard', id=class_group.id) }}" class="hover:text-blue-600 transition-colors flex items-center">
|
||
<svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||
</svg>
|
||
Retour au dashboard de classe
|
||
</a>
|
||
</div>
|
||
|
||
{# Sélecteur de trimestre #}
|
||
<div class="flex items-center space-x-3">
|
||
<label class="text-sm font-medium text-gray-700">Trimestre :</label>
|
||
<select id="trimester-selector"
|
||
data-trimester-selector
|
||
class="border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-purple-500 focus:border-purple-500 bg-white shadow-sm">
|
||
<option value="1" {% if trimester == 1 %}selected{% endif %}>Trimestre 1</option>
|
||
<option value="2" {% if trimester == 2 %}selected{% endif %}>Trimestre 2</option>
|
||
<option value="3" {% if trimester == 3 %}selected{% endif %}>Trimestre 3</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
{# 2. Filtres et Actions Principales #}
|
||
<div class="list-mode-filters-section bg-white rounded-xl shadow-sm border border-gray-200 p-6">
|
||
<div class="flex flex-col lg:flex-row lg:items-center justify-between space-y-4 lg:space-y-0">
|
||
|
||
{# Recherche et filtres - masqués en mode focus #}
|
||
<div class="list-mode-filters flex flex-col sm:flex-row space-y-2 sm:space-y-0 sm:space-x-4">
|
||
<div class="relative">
|
||
<input type="text"
|
||
data-search-students
|
||
placeholder="Rechercher un élève..."
|
||
class="pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 text-sm w-64">
|
||
<svg class="w-4 h-4 text-gray-400 absolute left-3 top-3" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd"/>
|
||
</svg>
|
||
</div>
|
||
|
||
<select data-sort-students class="border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-purple-500 focus:border-purple-500">
|
||
<option value="alphabetical">Trier par nom</option>
|
||
<option value="average">Trier par moyenne</option>
|
||
<option value="status">Trier par statut</option>
|
||
</select>
|
||
|
||
<select data-filter-status class="border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-purple-500 focus:border-purple-500">
|
||
<option value="all">Tous les élèves</option>
|
||
<option value="completed">Appréciations rédigées</option>
|
||
<option value="pending">À rédiger</option>
|
||
<option value="struggling">Élèves en difficulté</option>
|
||
</select>
|
||
</div>
|
||
|
||
{# Actions globales #}
|
||
<div class="flex space-x-3">
|
||
{# Toujours visible : bouton mode focus #}
|
||
<button data-toggle-focus-mode
|
||
class="inline-flex items-center px-4 py-2 bg-gradient-to-r from-purple-500 to-purple-600 text-white rounded-lg hover:from-purple-600 hover:to-purple-700 transition-all duration-300 text-sm font-medium transform hover:scale-[1.02] shadow-lg hover:shadow-xl">
|
||
<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M3 4a1 1 0 011-1h4a1 1 0 010 2H6.414l2.293 2.293a1 1 0 01-1.414 1.414L5 6.414V8a1 1 0 01-2 0V4zm9 1a1 1 0 010-2h4a1 1 0 011 1v4a1 1 0 01-2 0V6.414l-2.293 2.293a1 1 0 11-1.414-1.414L13.586 5H12zm-9 7a1 1 0 012 0v1.586l2.293-2.293a1 1 0 111.414 1.414L6.414 15H8a1 1 0 010 2H4a1 1 0 01-1-1v-4zm13-1a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 010-2h1.586l-2.293-2.293a1 1 0 111.414-1.414L15 13.586V12a1 1 0 011-1z" clip-rule="evenodd"/>
|
||
</svg>
|
||
<span data-focus-mode-text>Mode Focus</span>
|
||
</button>
|
||
|
||
{# Actions masquées en mode focus #}
|
||
<div class="list-mode-actions space-x-3 flex">
|
||
<button data-export-pdf
|
||
class="inline-flex items-center px-4 py-2 bg-gradient-to-r from-green-500 to-green-600 text-white rounded-lg hover:from-green-600 hover:to-green-700 transition-all duration-300 text-sm font-medium transform hover:scale-[1.02] shadow-lg hover:shadow-xl">
|
||
<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd"/>
|
||
</svg>
|
||
Exporter PDF
|
||
</button>
|
||
|
||
<button data-class-synthesis
|
||
class="inline-flex items-center px-4 py-2 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-lg hover:from-blue-600 hover:to-blue-700 transition-all duration-300 text-sm font-medium transform hover:scale-[1.02] shadow-lg hover:shadow-xl">
|
||
<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||
<path d="M2 11a1 1 0 011-1h2a1 1 0 011 1v5a1 1 0 01-1 1H3a1 1 0 01-1-1v-5zM8 7a1 1 0 011-1h2a1 1 0 011 1v9a1 1 0 01-1 1H9a1 1 0 01-1-1V7zM14 4a1 1 0 011-1h2a1 1 0 011 1v12a1 1 0 01-1 1h-2a1 1 0 01-1-1V4z"/>
|
||
</svg>
|
||
Synthèse classe
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{# Compteur de résultats et contrôles mode focus #}
|
||
<div class="mt-4 pt-4 border-t border-gray-200">
|
||
{# Mode liste - compteur normal #}
|
||
<div class="list-mode-controls">
|
||
<p class="text-sm text-gray-600" data-results-counter>
|
||
{{ student_summaries|length }} élèves affichés
|
||
</p>
|
||
</div>
|
||
|
||
{# Mode focus - contrôles de navigation #}
|
||
<div class="focus-mode-controls hidden">
|
||
<div class="flex items-center justify-between">
|
||
<div class="flex items-center space-x-4">
|
||
<button data-focus-prev
|
||
class="inline-flex items-center px-3 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg transition-colors text-sm font-medium disabled:opacity-50 disabled:cursor-not-allowed">
|
||
<svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||
</svg>
|
||
Précédent
|
||
</button>
|
||
|
||
<div class="text-sm text-gray-600 bg-gray-50 px-3 py-2 rounded-lg">
|
||
Élève <span data-focus-current>1</span> sur <span data-focus-total>{{ student_summaries|length }}</span>
|
||
</div>
|
||
|
||
<button data-focus-next
|
||
class="inline-flex items-center px-3 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg transition-colors text-sm font-medium disabled:opacity-50 disabled:cursor-not-allowed">
|
||
Suivant
|
||
<svg class="w-4 h-4 ml-1" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="flex items-center space-x-2 text-xs text-gray-500">
|
||
<span>Navigation: ← → | Échap pour quitter</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{# Header compact mode focus - visible uniquement en mode focus #}
|
||
<div class="focus-mode-header hidden bg-white rounded-lg shadow-sm border border-gray-200 p-3 mb-4">
|
||
<div class="flex items-center justify-between">
|
||
<div class="flex items-center space-x-3">
|
||
<button data-toggle-focus-mode
|
||
class="inline-flex items-center px-3 py-1.5 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-md transition-colors text-sm font-medium">
|
||
<svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clip-rule="evenodd"/>
|
||
</svg>
|
||
Mode Liste
|
||
</button>
|
||
|
||
<div class="text-sm text-gray-600">
|
||
<strong>{{ class_group.name }}</strong> • Trimestre {{ trimester }}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flex items-center space-x-3">
|
||
<button data-focus-prev
|
||
class="inline-flex items-center px-2 py-1 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed">
|
||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||
</svg>
|
||
</button>
|
||
|
||
<div class="text-sm text-gray-600 bg-gray-50 px-2 py-1 rounded">
|
||
<span data-focus-current>1</span>/<span data-focus-total>{{ student_summaries|length }}</span>
|
||
</div>
|
||
|
||
<button data-focus-next
|
||
class="inline-flex items-center px-2 py-1 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed">
|
||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/>
|
||
</svg>
|
||
</button>
|
||
|
||
<div class="text-xs text-gray-500">← → Échap</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{# 3. Liste des Élèves (Cards Expandables) #}
|
||
<div class="students-display">
|
||
{# Mode liste - tous les élèves visibles #}
|
||
<div class="list-mode-display space-y-4" data-students-container>
|
||
{% for summary in student_summaries %}
|
||
<div class="bg-white rounded-xl shadow-sm border border-gray-200 hover:shadow-md transition-all duration-300
|
||
{% if summary.performance_status == 'struggling' %}border-l-4 border-l-red-400{% endif %}
|
||
{% if summary.performance_status == 'excellent' %}border-l-4 border-l-green-400{% endif %}
|
||
{% if summary.performance_status == 'good' %}border-l-4 border-l-blue-400{% endif %}
|
||
{% if summary.performance_status == 'no_data' %}border-l-4 border-l-gray-400{% endif %}"
|
||
data-student-card="{{ summary.student.id }}"
|
||
data-student-name="{{ summary.student.last_name }} {{ summary.student.first_name }}"
|
||
data-student-average="{{ summary.overall_average or 0 }}"
|
||
data-performance-status="{{ summary.performance_status }}"
|
||
data-has-appreciation="{{ 'true' if summary.has_appreciation else 'false' }}">
|
||
|
||
{# Header avec layout en deux colonnes principales #}
|
||
<div class="px-6 py-4">
|
||
{# Layout principal : Informations élève + Appréciation + Moyenne #}
|
||
<div class="flex items-start space-x-6">
|
||
{# Colonne 1: Informations élève avec avatar #}
|
||
<div class="flex items-center space-x-4 cursor-pointer" data-toggle-student="{{ summary.student.id }}">
|
||
{# Avatar avec initiales #}
|
||
<div class="w-12 h-12 rounded-full flex items-center justify-center text-white font-bold text-sm
|
||
{% if summary.performance_status == 'excellent' %}bg-gradient-to-r from-green-500 to-green-600{% endif %}
|
||
{% if summary.performance_status == 'good' %}bg-gradient-to-r from-blue-500 to-blue-600{% endif %}
|
||
{% if summary.performance_status == 'average' %}bg-gradient-to-r from-yellow-500 to-yellow-600{% endif %}
|
||
{% if summary.performance_status == 'struggling' %}bg-gradient-to-r from-red-500 to-red-600{% endif %}
|
||
{% if summary.performance_status == 'no_data' %}bg-gradient-to-r from-gray-500 to-gray-600{% endif %}">
|
||
{{ summary.student.first_name[0] }}{{ summary.student.last_name[0] }}
|
||
</div>
|
||
|
||
{# Informations de base élève #}
|
||
<div class="min-w-0">
|
||
<h3 class="font-semibold text-gray-900 text-lg">{{ summary.student.last_name }}, {{ summary.student.first_name }}</h3>
|
||
|
||
{# Info de base avec chevron #}
|
||
<div class="flex items-center space-x-4 text-sm text-gray-600">
|
||
<span class="flex items-center">
|
||
<svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||
<path d="M2 11a1 1 0 011-1h2a1 1 0 011 1v5a1 1 0 01-1 1H3a1 1 0 01-1-1v-5zM8 7a1 1 0 011-1h2a1 1 0 011 1v9a1 1 0 01-1 1H9a1 1 0 01-1-1V7zM14 4a1 1 0 011-1h2a1 1 0 011 1v12a1 1 0 01-1 1h-2a1 1 0 01-1-1V4z"/>
|
||
</svg>
|
||
{{ summary.assessment_count }} évaluation(s)
|
||
</span>
|
||
{% if summary.performance_status == 'struggling' %}
|
||
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs bg-red-100 text-red-800 font-medium">
|
||
⚠️ Attention requise
|
||
</span>
|
||
{% endif %}
|
||
{# Chevron d'expansion #}
|
||
<svg class="w-4 h-4 text-gray-400 transform transition-transform duration-300"
|
||
data-toggle-icon fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
|
||
</svg>
|
||
</div>
|
||
|
||
{# Résumé compact des valeurs spéciales #}
|
||
{% if summary.special_values_summary and summary.special_values_summary.has_special_values %}
|
||
<div class="mt-2 flex items-center space-x-1 text-xs">
|
||
<span class="text-gray-500">Valeurs spéciales:</span>
|
||
{% for special_value, data in summary.special_values_summary.global.items() %}
|
||
{% if data.count > 0 %}
|
||
{% set tooltip_content = [] %}
|
||
{% for detail in data.details %}
|
||
{% if detail.comment %}
|
||
{% set _ = tooltip_content.append(detail.element_name + ': ' + detail.comment) %}
|
||
{% else %}
|
||
{% set _ = tooltip_content.append(detail.element_name) %}
|
||
{% endif %}
|
||
{% endfor %}
|
||
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium cursor-help"
|
||
style="background-color: {{ data.color }}20; color: {{ data.color }};"
|
||
title="{{ data.label }} ({{ data.count }}){% if tooltip_content|length > 0 %} {{ tooltip_content|join(' ') }}{% endif %}">
|
||
{{ special_value }} {{ data.count }}
|
||
</span>
|
||
{% endif %}
|
||
{% endfor %}
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
{# Colonne 2: Zone d'appréciation intégrée #}
|
||
<div class="flex-1 min-w-0">
|
||
<label class="block text-sm font-medium text-gray-700 mb-2 flex items-center">
|
||
<svg class="w-4 h-4 text-purple-500 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"/>
|
||
</svg>
|
||
Appréciation du conseil de classe
|
||
</label>
|
||
<textarea
|
||
data-appreciation-textarea
|
||
data-student-id="{{ summary.student.id }}"
|
||
class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-purple-500 focus:border-purple-500 resize-none transition-colors"
|
||
rows="2"
|
||
placeholder="Saisir l'appréciation générale pour le bulletin...">{% if summary.appreciation and summary.appreciation.general_appreciation %}{{ summary.appreciation.general_appreciation }}{% endif %}</textarea>
|
||
<div class="mt-1 flex justify-between items-center text-xs text-gray-500">
|
||
<div class="flex items-center space-x-3">
|
||
<span>Sauvegarde automatique</span>
|
||
<div class="hidden" data-save-indicator="{{ summary.student.id }}"></div>
|
||
{% if summary.appreciation %}
|
||
<span class="text-gray-400">•</span>
|
||
<span data-last-modified="{{ summary.student.id }}">{{ summary.appreciation.last_modified.strftime('%d/%m à %H:%M') }}</span>
|
||
{% endif %}
|
||
</div>
|
||
<span data-char-counter>0 caractères</span>
|
||
</div>
|
||
</div>
|
||
|
||
{# Colonne 3: Moyenne et statuts #}
|
||
<div class="flex flex-col items-end space-y-2 text-right min-w-max">
|
||
{# Moyenne principale #}
|
||
<div class="flex items-center space-x-2">
|
||
{% if summary.overall_average %}
|
||
<span class="text-xl font-bold px-4 py-2 rounded-lg
|
||
{% if summary.performance_status == 'excellent' %}bg-green-100 text-green-800{% endif %}
|
||
{% if summary.performance_status == 'good' %}bg-blue-100 text-blue-800{% endif %}
|
||
{% if summary.performance_status == 'average' %}bg-yellow-100 text-yellow-800{% endif %}
|
||
{% if summary.performance_status == 'struggling' %}bg-red-100 text-red-800{% endif %}">
|
||
{{ "%.1f"|format(summary.overall_average) }}/20
|
||
</span>
|
||
{% else %}
|
||
<span class="text-sm text-gray-500 px-3 py-1 bg-gray-100 rounded-lg">
|
||
Pas de données
|
||
</span>
|
||
{% endif %}
|
||
</div>
|
||
|
||
{# Indicateurs de statut compacts #}
|
||
<div class="flex items-center space-x-2">
|
||
{# Indicateur d'appréciation #}
|
||
{% if summary.has_appreciation %}
|
||
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs bg-green-100 text-green-800">
|
||
<span class="w-2 h-2 bg-green-400 rounded-full mr-1"></span>
|
||
Rédigée
|
||
</span>
|
||
{% else %}
|
||
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs bg-orange-100 text-orange-800">
|
||
<span class="w-2 h-2 bg-orange-400 rounded-full mr-1"></span>
|
||
À rédiger
|
||
</span>
|
||
{% endif %}
|
||
|
||
{# Indicateur de tendance condensé #}
|
||
{% if summary.overall_average and summary.grades_by_assessment | length > 1 %}
|
||
{% set recent_assessments = summary.grades_by_assessment.values() | list | sort(attribute='date') %}
|
||
{% set trend_recent = (recent_assessments[-1].score / recent_assessments[-1].max * 20) if recent_assessments | length > 0 else 0 %}
|
||
{% set trend_previous = (recent_assessments[-2].score / recent_assessments[-2].max * 20) if recent_assessments | length > 1 else trend_recent %}
|
||
{% if trend_recent > trend_previous + 1 %}
|
||
<span class="inline-flex items-center text-xs text-green-600" title="Tendance positive: +{{ '%.1f'|format(trend_recent - trend_previous) }}">
|
||
<svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M3.293 9.707a1 1 0 010-1.414l6-6a1 1 0 011.414 0l6 6a1 1 0 01-1.414 1.414L10 4.414 4.707 9.707a1 1 0 01-1.414 0z" clip-rule="evenodd"/>
|
||
</svg>
|
||
</span>
|
||
{% elif trend_recent < trend_previous - 1 %}
|
||
<span class="inline-flex items-center text-xs text-red-600" title="Tendance négative: {{ '%.1f'|format(trend_recent - trend_previous) }}">
|
||
<svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M16.707 10.293a1 1 0 010 1.414l-6 6a1 1 0 01-1.414 0l-6-6a1 1 0 111.414-1.414L10 15.586l5.293-5.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||
</svg>
|
||
</span>
|
||
{% endif %}
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{# Contenu expandable #}
|
||
<div class="hidden border-t border-gray-200" data-student-details="{{ summary.student.id }}">
|
||
<div class="px-6 py-6 space-y-6">
|
||
|
||
{# Section Compétences et Domaines - Layout horizontal #}
|
||
{% if summary.competence_domain_breakdown and (summary.competence_domain_breakdown.competences or summary.competence_domain_breakdown.domains) %}
|
||
<div class="competence-domain-section">
|
||
{# Layout horizontal: Résultats + Barres #}
|
||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||
|
||
{# Colonne gauche: Résultats par évaluation (si disponibles) #}
|
||
{% if summary.grades_by_assessment %}
|
||
<div class="evaluation-results">
|
||
<h5 class="text-sm font-medium text-blue-700 mb-3 flex items-center">
|
||
<svg class="w-4 h-4 text-blue-500 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||
<path d="M2 11a1 1 0 011-1h2a1 1 0 011 1v5a1 1 0 01-1 1H3a1 1 0 01-1-1v-5zM8 7a1 1 0 011-1h2a1 1 0 011 1v9a1 1 0 01-1 1H9a1 1 0 01-1-1V7zM14 4a1 1 0 011-1h2a1 1 0 011 1v12a1 1 0 01-1 1h-2a1 1 0 01-1-1V4z"/>
|
||
</svg>
|
||
Résultats par évaluation
|
||
</h5>
|
||
<div class="space-y-1.5">
|
||
{% for assessment_id, assessment_data in summary.grades_by_assessment.items() %}
|
||
<div class="flex items-center justify-between p-2 bg-blue-50 rounded-lg border border-blue-100">
|
||
<span class="text-sm font-medium text-blue-900 truncate">{{ assessment_data.title }}</span>
|
||
<div class="flex items-center space-x-2">
|
||
<span class="text-sm font-bold text-blue-700">{{ "%.1f"|format(assessment_data.score) }}/{{ assessment_data.max }}</span>
|
||
{% if assessment_data.coefficient != 1 %}
|
||
<span class="text-xs text-blue-600 bg-blue-200 px-1 rounded">×{{ assessment_data.coefficient }}</span>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
|
||
{# Section Valeurs spéciales par évaluation #}
|
||
{% if summary.special_values_summary and summary.special_values_summary.by_assessment %}
|
||
<div class="mt-4">
|
||
<h6 class="text-xs font-medium text-gray-600 mb-2 flex items-center">
|
||
<svg class="w-3 h-3 text-gray-500 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/>
|
||
</svg>
|
||
Valeurs spéciales
|
||
</h6>
|
||
<div class="space-y-1">
|
||
{% for assessment_id, assessment_data in summary.special_values_summary.by_assessment.items() %}
|
||
<div class="flex items-center justify-between p-1.5 bg-gray-50 rounded border border-gray-100">
|
||
<span class="text-xs text-gray-700 truncate">{{ assessment_data.title }}</span>
|
||
<div class="flex items-center space-x-1">
|
||
{% for special_value, data in assessment_data.special_values.items() %}
|
||
{% if data.count > 0 %}
|
||
{% set detail_tooltip = [] %}
|
||
{% for detail in data.details %}
|
||
{% if detail.comment %}
|
||
{% set _ = detail_tooltip.append(detail.element_name + ': ' + detail.comment) %}
|
||
{% else %}
|
||
{% set _ = detail_tooltip.append(detail.element_name) %}
|
||
{% endif %}
|
||
{% endfor %}
|
||
<span class="inline-flex items-center px-1 py-0.5 rounded text-xs font-medium cursor-help"
|
||
style="background-color: {{ data.color }}15; color: {{ data.color }}; border: 1px solid {{ data.color }}30;"
|
||
title="{{ data.label }} ({{ data.count }}){% if detail_tooltip|length > 0 %} {{ detail_tooltip|join(' ') }}{% endif %}">
|
||
{{ special_value }} {{ data.count }}
|
||
</span>
|
||
{% endif %}
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
|
||
{# Section Commentaires par évaluation #}
|
||
{% if summary.special_values_summary and summary.special_values_summary.comments_by_assessments and summary.special_values_summary.comments_by_assessments.has_comments %}
|
||
<div class="mt-4">
|
||
<h6 class="text-xs font-medium text-gray-600 mb-2 flex items-center">
|
||
<svg class="w-3 h-3 text-gray-500 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"/>
|
||
</svg>
|
||
Commentaires ({{ summary.special_values_summary.comments_by_assessments.total_comments }})
|
||
</h6>
|
||
<div class="space-y-2">
|
||
{% for assessment in summary.special_values_summary.comments_by_assessments.assessments %}
|
||
<div class="bg-amber-50 border border-amber-200 rounded p-2">
|
||
<div class="flex items-center justify-between mb-1">
|
||
<span class="text-xs font-medium text-amber-800">{{ assessment.title }}</span>
|
||
<span class="text-xs text-amber-600">{{ assessment.comments|length }} commentaire(s)</span>
|
||
</div>
|
||
<div class="space-y-1">
|
||
{% for comment in assessment.comments %}
|
||
<div class="bg-white border border-amber-100 rounded p-1.5">
|
||
<div class="flex-1 min-w-0">
|
||
{# Ligne 1: Label et description #}
|
||
<div class="text-xs font-medium text-gray-800">
|
||
{{ comment.element_label }}{% if comment.element_description %} • {{ comment.element_description }}{% endif %}
|
||
</div>
|
||
{# Ligne 2: Valeur et commentaire #}
|
||
<div class="text-xs text-amber-700 mt-0.5 flex items-center">
|
||
{% if comment.value %}
|
||
<span class="inline-flex items-center px-1 py-0.5 rounded text-xs font-medium mr-2 bg-orange-100 text-orange-800">
|
||
{{ comment.value }}
|
||
</span>
|
||
{% endif %}
|
||
<span class="flex-1">{{ comment.comment }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
{% endif %}
|
||
|
||
{# Colonne droite: Barres de progression #}
|
||
<div class="progress-bars">
|
||
{# Compétences #}
|
||
{% if summary.competence_domain_breakdown.competences %}
|
||
<div class="mb-4">
|
||
<h5 class="text-sm font-medium text-purple-700 mb-3 flex items-center">
|
||
<svg class="w-3 h-3 text-purple-500 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/>
|
||
</svg>
|
||
Compétences
|
||
</h5>
|
||
<div class="space-y-3">
|
||
{% for competence in summary.competence_domain_breakdown.competences %}
|
||
<div class="competence-progress-horizontal">
|
||
{# Nom et score à côté de la barre #}
|
||
<div class="flex items-center justify-between mb-1">
|
||
<span class="text-xs font-medium text-gray-700 truncate flex-1 mr-2">{{ competence.name }}</span>
|
||
<span class="text-xs font-bold whitespace-nowrap" style="color: {{ competence.color }}">
|
||
{{ competence.percentage }}%
|
||
</span>
|
||
</div>
|
||
{# Barre de progression compacte #}
|
||
<div class="progress-bar-container segmented-progress compact"
|
||
data-competence-name="{{ competence.name }}"
|
||
data-assessments="{{ competence.assessments | tojson | e }}"
|
||
role="progressbar"
|
||
aria-valuenow="{{ competence.percentage }}"
|
||
aria-valuemin="0"
|
||
aria-valuemax="100"
|
||
aria-label="Progression de la compétence {{ competence.name }}: {{ competence.percentage }}%"
|
||
tabindex="0">
|
||
<div class="segmented-progress-bar compact" data-expanded="true">
|
||
{% for assessment in competence.assessments %}
|
||
<div class="progress-segment"
|
||
style="width: {{ assessment.percentage_contribution }}%; background-color: {{ assessment.color }};"
|
||
data-assessment-id="{{ assessment.id }}"
|
||
data-assessment-title="{{ assessment.title }}"
|
||
data-assessment-performance="{{ assessment.performance }}"
|
||
data-earned-this="{{ assessment.earned_this }}"
|
||
data-max-this="{{ assessment.max_this }}"
|
||
data-earned-cumulative="{{ assessment.earned_cumulative }}"
|
||
data-max-cumulative="{{ assessment.max_cumulative }}"
|
||
data-contribution-percentage="{{ assessment.percentage_contribution }}"
|
||
title="{{ assessment.title }}: {{ assessment.earned_this }} pts ({{ assessment.performance }}%)"
|
||
role="button"
|
||
tabindex="0"
|
||
aria-label="Évaluation {{ assessment.title }}: {{ assessment.earned_this }} points sur {{ assessment.max_this }}">
|
||
<span class="segment-label">{{ assessment.title|truncate(6, true) }}</span>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
|
||
{# Domaines #}
|
||
{% if summary.competence_domain_breakdown.domains %}
|
||
<div>
|
||
<h5 class="text-sm font-medium text-orange-700 mb-3 flex items-center">
|
||
<svg class="w-3 h-3 text-orange-500 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||
<path fill-rule="evenodd" d="M3 4a1 1 0 011-1h4a1 1 0 010 2H6.414l2.293 2.293a1 1 0 01-1.414 1.414L5 6.414V8a1 1 0 01-2 0V4zm9 1a1 1 0 010-2h4a1 1 0 011 1v4a1 1 0 01-2 0V6.414l-2.293 2.293a1 1 0 11-1.414-1.414L13.586 5H12zm-9 7a1 1 0 012 0v1.586l2.293-2.293a1 1 0 111.414 1.414L6.414 15H8a1 1 0 010 2H4a1 1 0 01-1-1v-4zm13-1a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 010-2h1.586l-2.293-2.293a1 1 0 111.414-1.414L15 13.586V12a1 1 0 011-1z" clip-rule="evenodd"/>
|
||
</svg>
|
||
Domaines
|
||
</h5>
|
||
<div class="space-y-3">
|
||
{% for domain in summary.competence_domain_breakdown.domains %}
|
||
<div class="domain-progress-horizontal">
|
||
{# Nom et score à côté de la barre #}
|
||
<div class="flex items-center justify-between mb-1">
|
||
<span class="text-xs font-medium text-gray-700 truncate flex-1 mr-2">{{ domain.name }}</span>
|
||
<span class="text-xs font-bold whitespace-nowrap" style="color: {{ domain.color }}">
|
||
{{ domain.percentage }}%
|
||
</span>
|
||
</div>
|
||
{# Barre de progression compacte #}
|
||
<div class="progress-bar-container segmented-progress compact"
|
||
data-domain-name="{{ domain.name }}"
|
||
data-assessments="{{ domain.assessments | tojson | e }}"
|
||
role="progressbar"
|
||
aria-valuenow="{{ domain.percentage }}"
|
||
aria-valuemin="0"
|
||
aria-valuemax="100"
|
||
aria-label="Progression du domaine {{ domain.name }}: {{ domain.percentage }}%"
|
||
tabindex="0">
|
||
<div class="segmented-progress-bar compact" data-expanded="true">
|
||
{% for assessment in domain.assessments %}
|
||
<div class="progress-segment"
|
||
style="width: {{ assessment.percentage_contribution }}%; background-color: {{ assessment.color }};"
|
||
data-assessment-id="{{ assessment.id }}"
|
||
data-assessment-title="{{ assessment.title }}"
|
||
data-assessment-performance="{{ assessment.performance }}"
|
||
data-earned-this="{{ assessment.earned_this }}"
|
||
data-max-this="{{ assessment.max_this }}"
|
||
data-earned-cumulative="{{ assessment.earned_cumulative }}"
|
||
data-max-cumulative="{{ assessment.max_cumulative }}"
|
||
data-contribution-percentage="{{ assessment.percentage_contribution }}"
|
||
title="{{ assessment.title }}: {{ assessment.earned_this }} pts ({{ assessment.performance }}%)"
|
||
role="button"
|
||
tabindex="0"
|
||
aria-label="Évaluation {{ assessment.title }}: {{ assessment.earned_this }} points sur {{ assessment.max_this }}">
|
||
<span class="segment-label">{{ assessment.title|truncate(6, true) }}</span>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
|
||
{# Mode focus - un seul élève visible #}
|
||
<div class="focus-mode-display hidden" data-focus-container>
|
||
{# Le contenu sera géré dynamiquement par JavaScript #}
|
||
{# L'élève affiché sera cloné depuis la liste et affiché ici #}
|
||
</div>
|
||
</div>
|
||
|
||
{# Message si aucun élève #}
|
||
{% if not student_summaries %}
|
||
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-12 text-center">
|
||
<div class="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||
<svg class="w-8 h-8 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
|
||
<path d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"/>
|
||
</svg>
|
||
</div>
|
||
<h3 class="text-lg font-medium text-gray-900 mb-2">Aucun élève trouvé</h3>
|
||
<p class="text-gray-500">Aucune donnée disponible pour ce trimestre ou cette classe.</p>
|
||
</div>
|
||
{% endif %}
|
||
|
||
{# 4. Statistiques de classe (sidebar ou bottom) - masqué en mode focus #}
|
||
{% if class_statistics and class_statistics.mean %}
|
||
<div class="list-mode-stats bg-white rounded-xl shadow-sm border border-gray-200 p-6">
|
||
<h3 class="text-lg font-semibold text-gray-900 mb-4 flex items-center">
|
||
<svg class="w-5 h-5 text-orange-500 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||
<path d="M2 11a1 1 0 011-1h2a1 1 0 011 1v5a1 1 0 01-1 1H3a1 1 0 01-1-1v-5zM8 7a1 1 0 011-1h2a1 1 0 011 1v9a1 1 0 01-1 1H9a1 1 0 01-1-1V7zM14 4a1 1 0 011-1h2a1 1 0 011 1v12a1 1 0 01-1 1h-2a1 1 0 01-1-1V4z"/>
|
||
</svg>
|
||
Statistiques de la classe
|
||
</h3>
|
||
|
||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||
<div class="text-center">
|
||
<div class="text-2xl font-bold text-orange-900">{{ "%.1f"|format(class_statistics.mean) }}</div>
|
||
<div class="text-sm text-orange-700">Moyenne générale</div>
|
||
</div>
|
||
<div class="text-center">
|
||
<div class="text-lg font-semibold text-gray-700">{{ "%.1f"|format(class_statistics.min) }}</div>
|
||
<div class="text-xs text-gray-500">Minimum</div>
|
||
</div>
|
||
<div class="text-center">
|
||
<div class="text-lg font-semibold text-gray-700">{{ "%.1f"|format(class_statistics.max) }}</div>
|
||
<div class="text-xs text-gray-500">Maximum</div>
|
||
</div>
|
||
<div class="text-center">
|
||
<div class="text-lg font-semibold text-gray-700">{{ "%.1f"|format(class_statistics.median) }}</div>
|
||
<div class="text-xs text-gray-500">Médiane</div>
|
||
</div>
|
||
</div>
|
||
|
||
{# Distribution des performances #}
|
||
<div class="mt-6">
|
||
<h4 class="text-sm font-medium text-gray-700 mb-3">Répartition des performances</h4>
|
||
<div class="grid grid-cols-2 md:grid-cols-4 gap-2">
|
||
<div class="bg-green-50 p-2 rounded text-center">
|
||
<div class="text-lg font-bold text-green-800">{{ class_statistics.performance_distribution.excellent }}</div>
|
||
<div class="text-xs text-green-600">Excellent (≥16)</div>
|
||
</div>
|
||
<div class="bg-blue-50 p-2 rounded text-center">
|
||
<div class="text-lg font-bold text-blue-800">{{ class_statistics.performance_distribution.good }}</div>
|
||
<div class="text-xs text-blue-600">Bien (14-16)</div>
|
||
</div>
|
||
<div class="bg-yellow-50 p-2 rounded text-center">
|
||
<div class="text-lg font-bold text-yellow-800">{{ class_statistics.performance_distribution.average }}</div>
|
||
<div class="text-xs text-yellow-600">Moyen (10-14)</div>
|
||
</div>
|
||
<div class="bg-red-50 p-2 rounded text-center">
|
||
<div class="text-lg font-bold text-red-800">{{ class_statistics.performance_distribution.struggling }}</div>
|
||
<div class="text-xs text-red-600">Difficulté (<10)</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
|
||
</div>
|
||
</div> <!-- Fermeture max-w-7xl -->
|
||
|
||
</div> <!-- Fermeture council-preparation -->
|
||
|
||
{% endblock %}
|
||
|
||
{% block head %}
|
||
<script src="{{ url_for('static', filename='js/CouncilPreparation.js') }}"></script>
|
||
<style>
|
||
/* Styles spécifiques pour la page conseil */
|
||
.council-preparation {
|
||
overflow: visible !important;
|
||
}
|
||
|
||
.council-preparation .grid {
|
||
overflow: visible !important;
|
||
}
|
||
|
||
.council-preparation [class*="transform"][class*="hover:scale"] {
|
||
transform-origin: center;
|
||
}
|
||
|
||
/* Assurer que les conteneurs parents permettent l'overflow */
|
||
main {
|
||
overflow: visible !important;
|
||
}
|
||
|
||
/* Styles pour le mode focus */
|
||
.focus-mode-student {
|
||
animation: focusFadeIn 0.3s ease-out;
|
||
transform: scale(1);
|
||
}
|
||
|
||
@keyframes focusFadeIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(10px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
/* Mode focus - Carte élève élargie */
|
||
.focus-mode-display .focus-mode-student {
|
||
max-width: none !important;
|
||
width: 100%;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
/* Mode focus - Section appréciation toujours visible */
|
||
.focus-mode-student [data-student-details] {
|
||
display: block !important;
|
||
height: auto !important;
|
||
opacity: 1 !important;
|
||
}
|
||
|
||
/* Mode focus - Interface ultra-compacte */
|
||
body.focus-mode {
|
||
overflow: hidden; /* Empêcher le scroll global */
|
||
}
|
||
|
||
.focus-mode-header {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
z-index: 50;
|
||
background: white;
|
||
border-bottom: 1px solid #e5e7eb;
|
||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.focus-mode-display {
|
||
position: fixed;
|
||
top: 60px; /* Hauteur du header compact */
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
overflow: hidden;
|
||
background: #f9fafb;
|
||
padding: 1rem;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* Mode focus - Utilisation complète de la hauteur */
|
||
.focus-mode-student {
|
||
height: 100%;
|
||
min-height: 100%;
|
||
max-height: none;
|
||
overflow: hidden;
|
||
background: white;
|
||
border-radius: 0.5rem;
|
||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* Mode focus - Améliorer la lisibilité */
|
||
.focus-mode-student textarea {
|
||
min-height: 150px;
|
||
max-height: 50vh;
|
||
font-size: 14px;
|
||
line-height: 1.5;
|
||
resize: vertical;
|
||
flex: 1;
|
||
}
|
||
|
||
/* Mode focus - Conteneur de la carte élève s'étend sur toute la hauteur */
|
||
.focus-mode-student .px-6 {
|
||
padding-left: 1rem;
|
||
padding-right: 1rem;
|
||
/* Retirer flex: 1 car ce n'est que le header */
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* Mode focus - Section détails s'étend pour utiliser l'espace disponible */
|
||
.focus-mode-student [data-student-details] {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* Mode focus - Zone d'appréciation garde sa structure */
|
||
.focus-mode-student .flex-1.min-w-0 {
|
||
/* Garder la structure originale */
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
/* Mode focus - Garder le layout horizontal du header */
|
||
.focus-mode-student .flex.items-start.space-x-6 {
|
||
/* Conserver le layout horizontal original */
|
||
flex-direction: row;
|
||
gap: 1.5rem;
|
||
align-items: flex-start;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* Mode focus - Appréciation garde sa taille originale */
|
||
.focus-mode-student .flex-1.min-w-0 textarea {
|
||
/* Garder les propriétés originales, juste ajuster légèrement */
|
||
min-height: 80px;
|
||
max-height: 200px;
|
||
height: auto;
|
||
}
|
||
|
||
/* Mode focus - Assurer que les sections s'étendent correctement */
|
||
.focus-mode-student .space-y-6 {
|
||
display: flex;
|
||
flex-direction: column;
|
||
flex: 1;
|
||
gap: 1.5rem;
|
||
}
|
||
|
||
/* Mode focus - Section détails visible et prend tout l'espace restant */
|
||
.focus-mode-student [data-student-details] {
|
||
display: block !important;
|
||
opacity: 1 !important;
|
||
flex: 1 1 0;
|
||
overflow-y: auto;
|
||
min-height: 0;
|
||
height: 0; /* Force flexbox à utiliser flex: 1 */
|
||
}
|
||
|
||
/* Mode focus - Organisation du contenu des détails */
|
||
.focus-mode-student [data-student-details] > .px-6.py-6.space-y-6 {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 100%;
|
||
gap: 1.5rem;
|
||
}
|
||
|
||
/* Mode focus - Section compétences/domaines compacte mais visible */
|
||
.focus-mode-student .competence-domain-section {
|
||
flex-shrink: 0;
|
||
min-height: 200px;
|
||
}
|
||
|
||
|
||
/* Mode focus - Header garde son padding normal */
|
||
.focus-mode-student .px-6.py-4 {
|
||
padding: 1rem;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* Mode focus - Réduction des espacements */
|
||
.focus-mode-student .space-y-4 > * + * {
|
||
margin-top: 0.75rem;
|
||
}
|
||
|
||
.focus-mode-student .mb-2 {
|
||
margin-bottom: 0.5rem;
|
||
}
|
||
|
||
/* ========== BARRES DE PROGRESSION COMPÉTENCES/DOMAINES ========== */
|
||
|
||
/* ========== BARRES DE PROGRESSION SEGMENTÉES ========== */
|
||
|
||
/* Conteneur principal des barres de progression */
|
||
.competence-progress-bar,
|
||
.domain-progress-bar {
|
||
margin-bottom: 0.75rem;
|
||
}
|
||
|
||
.progress-bar-container {
|
||
position: relative;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
/* Conteneur segmenté avec apparence moderne et claire */
|
||
.segmented-progress {
|
||
border-radius: 10px;
|
||
background: rgba(255, 255, 255, 0.8);
|
||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||
padding: 6px;
|
||
min-height: 44px;
|
||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
.segmented-progress:hover {
|
||
border-color: rgba(0, 0, 0, 0.12);
|
||
background: rgba(255, 255, 255, 0.95);
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08), 0 1px 3px rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.segmented-progress:focus {
|
||
outline: none;
|
||
border-color: #3b82f6;
|
||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||
}
|
||
|
||
/* Barre segmentée - état expandé par défaut */
|
||
.segmented-progress-bar {
|
||
display: flex;
|
||
height: 36px;
|
||
gap: 3px;
|
||
padding: 3px;
|
||
border-radius: 6px;
|
||
overflow: visible;
|
||
position: relative;
|
||
background: transparent;
|
||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||
}
|
||
|
||
/* État contracté (optionnel, si besoin futur) */
|
||
.segmented-progress-bar[data-expanded="false"] {
|
||
height: 16px;
|
||
gap: 0;
|
||
padding: 0;
|
||
background: #e5e7eb;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* Segments individuels - état expandé par défaut */
|
||
.progress-segment {
|
||
height: 30px;
|
||
border-radius: 6px;
|
||
position: relative;
|
||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||
cursor: pointer;
|
||
min-width: 8px; /* Minimum pour les petites contributions */
|
||
border: 2px solid rgba(255, 255, 255, 0.5);
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||
animation: segmentAppear 0.6s ease-out forwards;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* État contracté des segments (optionnel) */
|
||
.segmented-progress-bar[data-expanded="false"] .progress-segment {
|
||
height: 100%;
|
||
border-radius: 4px;
|
||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||
box-shadow: none;
|
||
}
|
||
|
||
/* Séparateurs visuels entre segments (état contracté seulement) */
|
||
.segmented-progress-bar:not([data-expanded="true"]) .progress-segment:not(:last-child) {
|
||
border-right: 2px solid rgba(255, 255, 255, 0.8);
|
||
}
|
||
|
||
/* Hover effects pour les segments */
|
||
.progress-segment:hover {
|
||
filter: brightness(1.15);
|
||
transform: scaleY(1.05);
|
||
z-index: 10;
|
||
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15);
|
||
}
|
||
|
||
.segmented-progress-bar[data-expanded="true"] .progress-segment:hover {
|
||
transform: translateY(-2px) scale(1.02);
|
||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
|
||
}
|
||
|
||
/* Focus pour accessibilité clavier */
|
||
.progress-segment:focus {
|
||
outline: none;
|
||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3);
|
||
z-index: 15;
|
||
}
|
||
|
||
/* Labels des segments - visibles par défaut */
|
||
.segment-label {
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
font-size: 0.7rem;
|
||
font-weight: 600;
|
||
color: rgba(255, 255, 255, 0.95);
|
||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||
opacity: 1;
|
||
transition: opacity 0.3s ease;
|
||
pointer-events: none;
|
||
white-space: nowrap;
|
||
max-width: 90%;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
/* État contracté des labels (optionnel) */
|
||
.segmented-progress-bar[data-expanded="false"] .segment-label {
|
||
opacity: 0;
|
||
font-size: 0.65rem;
|
||
}
|
||
|
||
|
||
/* Tooltips améliorés avec fond clair */
|
||
.progress-segment:hover::after {
|
||
content: attr(data-assessment-title) ': ' attr(data-earned-this) ' pts (' attr(data-assessment-performance) '%)';
|
||
position: absolute;
|
||
bottom: calc(100% + 8px);
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
background: rgba(255, 255, 255, 0.98);
|
||
color: #374151;
|
||
padding: 8px 12px;
|
||
border-radius: 8px;
|
||
font-size: 0.75rem;
|
||
font-weight: 600;
|
||
white-space: nowrap;
|
||
z-index: 1001;
|
||
pointer-events: none;
|
||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.1);
|
||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||
animation: tooltipFadeIn 0.2s ease-out;
|
||
}
|
||
|
||
.progress-segment:hover::before {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: calc(100% + 2px);
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
border: 6px solid transparent;
|
||
border-top-color: rgba(255, 255, 255, 0.98);
|
||
z-index: 1001;
|
||
pointer-events: none;
|
||
}
|
||
|
||
/* Animation d'apparition des segments */
|
||
@keyframes segmentAppear {
|
||
0% {
|
||
opacity: 0;
|
||
transform: scaleX(0);
|
||
}
|
||
60% {
|
||
opacity: 0.9;
|
||
transform: scaleX(1.02);
|
||
}
|
||
100% {
|
||
opacity: 1;
|
||
transform: scaleX(1);
|
||
}
|
||
}
|
||
|
||
@keyframes tooltipFadeIn {
|
||
0% {
|
||
opacity: 0;
|
||
transform: translateX(-50%) translateY(4px);
|
||
}
|
||
100% {
|
||
opacity: 1;
|
||
transform: translateX(-50%) translateY(0);
|
||
}
|
||
}
|
||
|
||
/* Animation séquentielle des segments */
|
||
.progress-segment:nth-child(1) { animation-delay: 0.1s; }
|
||
.progress-segment:nth-child(2) { animation-delay: 0.2s; }
|
||
.progress-segment:nth-child(3) { animation-delay: 0.3s; }
|
||
.progress-segment:nth-child(4) { animation-delay: 0.4s; }
|
||
.progress-segment:nth-child(5) { animation-delay: 0.5s; }
|
||
.progress-segment:nth-child(6) { animation-delay: 0.6s; }
|
||
|
||
/* ========== RESPONSIVE ET ACCESSIBILITÉ ========== */
|
||
|
||
/* Responsive pour mobile */
|
||
@media (max-width: 640px) {
|
||
.segmented-progress {
|
||
padding: 3px;
|
||
min-height: 24px;
|
||
}
|
||
|
||
.segmented-progress-bar {
|
||
height: 20px;
|
||
}
|
||
|
||
.segmented-progress-bar[data-expanded="true"] {
|
||
height: 44px; /* Touch target minimum 44px */
|
||
gap: 2px;
|
||
padding: 2px;
|
||
}
|
||
|
||
.segmented-progress-bar[data-expanded="true"] .progress-segment {
|
||
height: 40px;
|
||
min-width: 44px; /* Touch target minimum */
|
||
}
|
||
|
||
.segment-label {
|
||
font-size: 0.6rem;
|
||
}
|
||
|
||
.segmented-progress-bar[data-expanded="true"] .segment-label {
|
||
font-size: 0.65rem;
|
||
}
|
||
|
||
.progress-segment:hover::after {
|
||
font-size: 0.7rem;
|
||
padding: 6px 10px;
|
||
bottom: calc(100% + 12px);
|
||
}
|
||
}
|
||
|
||
/* Responsive pour très petits écrans */
|
||
@media (max-width: 480px) {
|
||
.competence-progress-bar .flex.items-center.justify-between,
|
||
.domain-progress-bar .flex.items-center.justify-between {
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: 0.5rem;
|
||
}
|
||
|
||
.progress-segment:hover::after {
|
||
position: fixed;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
bottom: auto;
|
||
max-width: 280px;
|
||
text-align: center;
|
||
font-size: 0.75rem;
|
||
padding: 8px 12px;
|
||
}
|
||
}
|
||
|
||
/* Mode sombre - Réduction de mouvement pour accessibilité */
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.progress-segment,
|
||
.segmented-progress,
|
||
.segmented-progress-bar,
|
||
.segment-label,
|
||
.progress-summary {
|
||
animation: none !important;
|
||
transition: none !important;
|
||
}
|
||
|
||
.progress-segment:hover {
|
||
transform: none;
|
||
}
|
||
}
|
||
|
||
/* Contraste élevé pour accessibilité */
|
||
@media (prefers-contrast: high) {
|
||
.segmented-progress {
|
||
border: 3px solid #000000;
|
||
}
|
||
|
||
.progress-segment {
|
||
border: 2px solid #ffffff;
|
||
filter: contrast(1.2);
|
||
}
|
||
|
||
.segment-label {
|
||
text-shadow: 1px 1px 0 #000000;
|
||
font-weight: 700;
|
||
}
|
||
}
|
||
|
||
/* Mode focus amélioré pour les barres segmentées */
|
||
.focus-mode-student .segmented-progress {
|
||
padding: 2px;
|
||
min-height: 16px;
|
||
}
|
||
|
||
.focus-mode-student .segmented-progress-bar {
|
||
height: 12px;
|
||
}
|
||
|
||
.focus-mode-student .segmented-progress-bar[data-expanded="true"] {
|
||
height: 28px;
|
||
}
|
||
|
||
.focus-mode-student .segmented-progress-bar[data-expanded="true"] .progress-segment {
|
||
height: 24px;
|
||
}
|
||
|
||
/* ========== CLASSES UTILITAIRES D'ACCESSIBILITÉ ========== */
|
||
|
||
/* Screen reader only content */
|
||
.sr-only {
|
||
position: absolute;
|
||
width: 1px;
|
||
height: 1px;
|
||
padding: 0;
|
||
margin: -1px;
|
||
overflow: hidden;
|
||
clip: rect(0, 0, 0, 0);
|
||
white-space: nowrap;
|
||
border: 0;
|
||
}
|
||
|
||
/* Skip link pour navigation au clavier */
|
||
.skip-link {
|
||
position: absolute;
|
||
top: -40px;
|
||
left: 6px;
|
||
background: #000;
|
||
color: #fff;
|
||
padding: 8px;
|
||
text-decoration: none;
|
||
border-radius: 4px;
|
||
z-index: 9999;
|
||
transition: top 0.3s;
|
||
}
|
||
|
||
.skip-link:focus {
|
||
top: 6px;
|
||
}
|
||
|
||
/* Focus visible amélioré pour tous les éléments interactifs */
|
||
.progress-segment:focus-visible,
|
||
.segmented-progress:focus-visible {
|
||
outline: 3px solid #4f46e5;
|
||
outline-offset: 2px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
/* Indicateur de charge pour les animations */
|
||
.progress-segment[aria-busy="true"]::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 2px;
|
||
right: 2px;
|
||
width: 8px;
|
||
height: 8px;
|
||
border: 1px solid rgba(255,255,255,0.8);
|
||
border-top-color: transparent;
|
||
border-radius: 50%;
|
||
animation: spin 1s linear infinite;
|
||
}
|
||
|
||
@keyframes spin {
|
||
to { transform: rotate(360deg); }
|
||
}
|
||
|
||
/* Mode sombre - support système */
|
||
@media (prefers-color-scheme: dark) {
|
||
.segmented-progress {
|
||
background: rgba(31, 41, 55, 0.8);
|
||
border-color: rgba(75, 85, 99, 0.4);
|
||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||
}
|
||
|
||
.segmented-progress:hover {
|
||
background: rgba(31, 41, 55, 0.95);
|
||
border-color: rgba(75, 85, 99, 0.6);
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3);
|
||
}
|
||
|
||
.progress-segment {
|
||
border-color: rgba(255, 255, 255, 0.2);
|
||
}
|
||
|
||
.segment-label {
|
||
color: rgba(255, 255, 255, 0.9);
|
||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
|
||
}
|
||
|
||
.progress-segment:hover::after {
|
||
background: rgba(17, 24, 39, 0.95);
|
||
color: #f9fafb;
|
||
border-color: rgba(255, 255, 255, 0.1);
|
||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
||
}
|
||
|
||
.progress-segment:hover::before {
|
||
border-top-color: rgba(17, 24, 39, 0.95);
|
||
}
|
||
}
|
||
|
||
/* ========== CLASSES DE PERFORMANCE POUR LES NOUVEAUX SEGMENTS ========== */
|
||
|
||
/* Indicateurs visuels de performance pour les nouveaux segments */
|
||
.progress-segment.segment-excellent {
|
||
box-shadow: inset 0 0 0 2px rgba(34, 197, 94, 0.4);
|
||
}
|
||
|
||
.progress-segment.segment-good {
|
||
box-shadow: inset 0 0 0 2px rgba(59, 130, 246, 0.4);
|
||
}
|
||
|
||
.progress-segment.segment-average {
|
||
box-shadow: inset 0 0 0 2px rgba(245, 158, 11, 0.4);
|
||
}
|
||
|
||
.progress-segment.segment-struggling {
|
||
box-shadow: inset 0 0 0 2px rgba(239, 68, 68, 0.4);
|
||
}
|
||
|
||
/* Effet de pulsation pour les segments excellents */
|
||
.progress-segment.segment-excellent:hover {
|
||
animation: excellentPulse 0.6s ease-in-out;
|
||
}
|
||
|
||
@keyframes excellentPulse {
|
||
0%, 100% { filter: brightness(1.2); }
|
||
50% { filter: brightness(1.4); }
|
||
}
|
||
|
||
/* ========== ANIMATION D'APPARITION DE LA SECTION ========== */
|
||
|
||
/* Animation d'apparition pour toute la section */
|
||
.competence-domain-section {
|
||
animation: slideInUp 0.5s ease-out;
|
||
}
|
||
|
||
@keyframes slideInUp {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(10px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
/* Boutons de navigation désactivés */
|
||
button:disabled {
|
||
opacity: 0.5;
|
||
cursor: not-allowed;
|
||
}
|
||
|
||
/* Transitions fluides pour les changements de mode */
|
||
.list-mode-display,
|
||
.focus-mode-display {
|
||
transition: all 0.3s ease-out;
|
||
}
|
||
|
||
.hidden {
|
||
display: none !important;
|
||
}
|
||
|
||
/* Animations fluides pour l'expansion des cards */
|
||
[data-student-details] {
|
||
overflow: hidden;
|
||
transition: all 0.3s ease-out;
|
||
}
|
||
|
||
/* États des textareas */
|
||
[data-appreciation-textarea]:focus {
|
||
box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.1);
|
||
}
|
||
|
||
/* Indicateurs de sauvegarde */
|
||
[data-save-indicator] {
|
||
transition: all 0.2s ease-in-out;
|
||
}
|
||
|
||
/* Hover effects pour les cards */
|
||
[data-student-card]:hover {
|
||
transform: translateY(-1px);
|
||
}
|
||
|
||
/* Styles pour l'aperçu des évaluations */
|
||
.assessment-preview-pills {
|
||
transition: all 0.2s ease-in-out;
|
||
}
|
||
|
||
.assessment-preview-pills:hover {
|
||
transform: scale(1.05);
|
||
}
|
||
|
||
/* Responsive: masquer l'aperçu sur très petits écrans */
|
||
@media (max-width: 640px) {
|
||
.assessment-preview-mobile-hide {
|
||
display: none !important;
|
||
}
|
||
}
|
||
|
||
/* Animation pour les indicateurs de tendance */
|
||
[title*="Tendance"] svg {
|
||
animation: pulse 2s infinite;
|
||
}
|
||
|
||
@keyframes pulse {
|
||
0%, 100% { opacity: 1; }
|
||
50% { opacity: 0.7; }
|
||
}
|
||
|
||
/* Amélioration de la lisibilité sur mobile */
|
||
@media (max-width: 768px) {
|
||
[data-student-card] .flex.items-center.justify-between {
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
gap: 0.5rem;
|
||
}
|
||
|
||
[data-student-card] .flex.flex-col.items-end {
|
||
align-items: stretch;
|
||
text-align: center;
|
||
}
|
||
}
|
||
|
||
/* ========== STYLES POUR LE NOUVEAU LAYOUT HORIZONTAL ========== */
|
||
|
||
/* Header à trois colonnes */
|
||
[data-student-card] .flex.items-start.space-x-6 {
|
||
gap: 1.5rem;
|
||
}
|
||
|
||
/* Responsive du header : passage en vertical sur tablette */
|
||
@media (max-width: 1024px) {
|
||
[data-student-card] .flex.items-start.space-x-6 {
|
||
flex-direction: column;
|
||
gap: 1rem;
|
||
align-items: stretch;
|
||
}
|
||
|
||
/* Appréciation en pleine largeur sur tablette */
|
||
[data-student-card] .flex-1.min-w-0 textarea {
|
||
min-height: 60px;
|
||
}
|
||
|
||
/* Moyenne et statuts alignés à droite même en vertical */
|
||
[data-student-card] .flex.flex-col.items-end.space-y-2.text-right {
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
text-align: left;
|
||
}
|
||
}
|
||
|
||
/* Mobile : layout complètement vertical */
|
||
@media (max-width: 640px) {
|
||
[data-student-card] .flex.items-start.space-x-6 {
|
||
gap: 0.75rem;
|
||
}
|
||
|
||
/* Info élève en ligne sur mobile */
|
||
[data-student-card] .flex.items-center.space-x-4[data-toggle-student] {
|
||
flex-direction: row;
|
||
align-items: center;
|
||
}
|
||
|
||
/* Appréciation compacte sur mobile */
|
||
[data-student-card] .flex-1.min-w-0 textarea {
|
||
rows: 2;
|
||
font-size: 0.875rem;
|
||
}
|
||
|
||
/* Statuts empilés sur mobile */
|
||
[data-student-card] .flex.flex-col.items-end.space-y-2.text-right {
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
gap: 0.5rem;
|
||
}
|
||
}
|
||
|
||
/* ========== STYLES POUR LES BARRES DE PROGRESSION COMPACTES ========== */
|
||
|
||
/* Version compacte des barres de progression */
|
||
.segmented-progress.compact {
|
||
padding: 3px;
|
||
min-height: 24px;
|
||
border-radius: 6px;
|
||
}
|
||
|
||
.segmented-progress-bar.compact {
|
||
height: 18px;
|
||
gap: 1px;
|
||
padding: 1px;
|
||
}
|
||
|
||
.segmented-progress.compact .progress-segment {
|
||
height: 16px;
|
||
border-radius: 3px;
|
||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||
min-width: 4px;
|
||
}
|
||
|
||
/* Labels plus petits en mode compact */
|
||
.segmented-progress.compact .segment-label {
|
||
font-size: 0.6rem;
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* Hover effects compacts */
|
||
.segmented-progress.compact .progress-segment:hover {
|
||
transform: translateY(-1px);
|
||
filter: brightness(1.1);
|
||
}
|
||
|
||
/* ========== SECTION RÉSULTATS PAR ÉVALUATION ========== */
|
||
|
||
.evaluation-results {
|
||
background: rgba(239, 246, 255, 0.3);
|
||
border-radius: 8px;
|
||
padding: 1rem;
|
||
border: 1px solid rgba(59, 130, 246, 0.1);
|
||
}
|
||
|
||
.evaluation-results .space-y-1\.5 > * + * {
|
||
margin-top: 0.375rem;
|
||
}
|
||
|
||
/* Cards d'évaluation avec couleurs des évaluations */
|
||
.evaluation-results .flex.items-center.justify-between {
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.evaluation-results .flex.items-center.justify-between:hover {
|
||
transform: translateX(2px);
|
||
box-shadow: 0 2px 4px rgba(59, 130, 246, 0.1);
|
||
}
|
||
|
||
/* ========== BARRES DE PROGRESSION HORIZONTALES ========== */
|
||
|
||
.competence-progress-horizontal,
|
||
.domain-progress-horizontal {
|
||
background: rgba(255, 255, 255, 0.5);
|
||
border-radius: 6px;
|
||
padding: 0.5rem;
|
||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.competence-progress-horizontal:hover,
|
||
.domain-progress-horizontal:hover {
|
||
background: rgba(255, 255, 255, 0.8);
|
||
border-color: rgba(0, 0, 0, 0.1);
|
||
transform: translateY(-1px);
|
||
}
|
||
|
||
/* ========== RESPONSIVE POUR LE NOUVEAU LAYOUT ========== */
|
||
|
||
/* Sur grands écrans : layout côte à côte */
|
||
@media (min-width: 1024px) {
|
||
.grid.grid-cols-1.lg\\:grid-cols-2.gap-6 {
|
||
grid-template-columns: 1fr 1fr;
|
||
}
|
||
}
|
||
|
||
/* Sur moyens écrans : layout adaptatif */
|
||
@media (max-width: 1023px) {
|
||
.grid.grid-cols-1.lg\\:grid-cols-2.gap-6 {
|
||
grid-template-columns: 1fr;
|
||
gap: 1rem;
|
||
}
|
||
|
||
/* Barres plus visibles sur tablette */
|
||
.segmented-progress.compact {
|
||
min-height: 28px;
|
||
padding: 4px;
|
||
}
|
||
|
||
.segmented-progress-bar.compact {
|
||
height: 20px;
|
||
}
|
||
|
||
.segmented-progress.compact .progress-segment {
|
||
height: 18px;
|
||
min-width: 6px;
|
||
}
|
||
}
|
||
|
||
/* Sur petits écrans : layout ultra-compact */
|
||
@media (max-width: 640px) {
|
||
.competence-domain-section .grid.grid-cols-1.lg\\:grid-cols-2.gap-6 {
|
||
gap: 0.75rem;
|
||
}
|
||
|
||
/* Textes plus petits */
|
||
.evaluation-results h5,
|
||
.progress-bars h5 {
|
||
font-size: 0.8rem;
|
||
}
|
||
|
||
/* Espacement réduit */
|
||
.competence-progress-horizontal,
|
||
.domain-progress-horizontal {
|
||
padding: 0.375rem;
|
||
margin-bottom: 0.5rem;
|
||
}
|
||
|
||
/* Noms tronqués plus agressivement */
|
||
.competence-progress-horizontal .text-xs.font-medium.text-gray-700,
|
||
.domain-progress-horizontal .text-xs.font-medium.text-gray-700 {
|
||
max-width: 100px;
|
||
}
|
||
}
|
||
|
||
/* ========== MODE FOCUS ADAPTATIONS ========== */
|
||
|
||
/* Mode focus : maintenir le layout 2 colonnes */
|
||
.focus-mode-student .competence-domain-section .grid.grid-cols-1.lg\\:grid-cols-2 {
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 1rem;
|
||
}
|
||
|
||
/* Mode focus sur tablette : revenir à une colonne */
|
||
@media (max-width: 1023px) {
|
||
.focus-mode-student .competence-domain-section .grid.grid-cols-1.lg\\:grid-cols-2 {
|
||
grid-template-columns: 1fr;
|
||
gap: 0.75rem;
|
||
}
|
||
}
|
||
|
||
.focus-mode-student .evaluation-results,
|
||
.focus-mode-student .progress-bars {
|
||
padding: 0.75rem;
|
||
}
|
||
|
||
.focus-mode-student .segmented-progress.compact {
|
||
min-height: 20px;
|
||
padding: 2px;
|
||
}
|
||
|
||
.focus-mode-student .segmented-progress-bar.compact {
|
||
height: 16px;
|
||
}
|
||
|
||
.focus-mode-student .segmented-progress.compact .progress-segment {
|
||
height: 14px;
|
||
}
|
||
</style>
|
||
{% endblock %}
|