OUAREDAEK commited on
Commit
625dd0c
·
verified ·
1 Parent(s): 970c7aa

Upload templates/index-old5.html with huggingface_hub

Browse files
Files changed (1) hide show
  1. templates/index-old5.html +2958 -0
templates/index-old5.html ADDED
@@ -0,0 +1,2958 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Dashboard Réflexif – ReflAgent</title>
7
+
8
+ <style>
9
+ /* ================= STYLES DE BASE ================= */
10
+ body {
11
+ font-family: 'Segoe UI', Arial, sans-serif;
12
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
13
+ margin: 0;
14
+ padding: 20px;
15
+ color: #333;
16
+ min-height: 100vh;
17
+ }
18
+
19
+ h2, h3, h4 {
20
+ color: #1976D2;
21
+ margin-top: 0;
22
+ }
23
+
24
+ h2 {
25
+ background: linear-gradient(90deg, #1976D2, #2196F3);
26
+ -webkit-background-clip: text;
27
+ -webkit-text-fill-color: transparent;
28
+ padding: 10px 0;
29
+ border-bottom: 2px solid #e3f2fd;
30
+ margin-bottom: 25px;
31
+ }
32
+
33
+ h3 {
34
+ background: #e3f2fd;
35
+ padding: 12px 15px;
36
+ border-radius: 8px;
37
+ margin: 25px 0 15px;
38
+ display: flex;
39
+ align-items: center;
40
+ gap: 10px;
41
+ }
42
+
43
+ h3::before {
44
+ content: '';
45
+ display: inline-block;
46
+ width: 6px;
47
+ height: 24px;
48
+ background: #1976D2;
49
+ border-radius: 3px;
50
+ }
51
+
52
+ #reflection {
53
+ background: white;
54
+ padding: 30px;
55
+ border-radius: 20px;
56
+ max-width: 1400px;
57
+ margin: auto;
58
+ box-shadow: 0 10px 40px rgba(0,0,0,0.08);
59
+ border: 1px solid #e0e0e0;
60
+ }
61
+
62
+ /* ================= SYSTEME D'ONGLETS ================= */
63
+ .tabs-container {
64
+ margin-bottom: 30px;
65
+ }
66
+
67
+ .tabs {
68
+ display: flex;
69
+ background: #f8f9fa;
70
+ border-radius: 12px;
71
+ padding: 5px;
72
+ margin-bottom: 20px;
73
+ border: 1px solid #e0e0e0;
74
+ flex-wrap: wrap;
75
+ }
76
+
77
+ .tab-btn {
78
+ flex: 1;
79
+ padding: 15px 20px;
80
+ border: none;
81
+ background: transparent;
82
+ color: #666;
83
+ font-weight: 600;
84
+ font-size: 16px;
85
+ cursor: pointer;
86
+ border-radius: 8px;
87
+ transition: all 0.3s ease;
88
+ display: flex;
89
+ align-items: center;
90
+ justify-content: center;
91
+ gap: 10px;
92
+ min-width: 200px;
93
+ }
94
+
95
+ .tab-btn:hover {
96
+ background: rgba(25, 118, 210, 0.1);
97
+ color: #1976D2;
98
+ }
99
+
100
+ .tab-btn.active {
101
+ background: #1976D2;
102
+ color: white;
103
+ box-shadow: 0 3px 8px rgba(25, 118, 210, 0.2);
104
+ }
105
+
106
+ .tab-content {
107
+ display: none;
108
+ animation: fadeIn 0.5s ease;
109
+ }
110
+
111
+ .tab-content.active {
112
+ display: block;
113
+ }
114
+
115
+ /* ================= NAVIGATION ================= */
116
+ .nav {
117
+ display: flex;
118
+ justify-content: space-between;
119
+ align-items: center;
120
+ margin-bottom: 30px;
121
+ background: linear-gradient(90deg, #e3f2fd, #f3e5f5);
122
+ padding: 15px 25px;
123
+ border-radius: 12px;
124
+ border: 1px solid #bbdefb;
125
+ flex-wrap: wrap;
126
+ }
127
+
128
+ #scenarioTitle {
129
+ font-size: 1.4em;
130
+ color: #333;
131
+ text-align: center;
132
+ flex-grow: 1;
133
+ margin: 0 20px;
134
+ word-break: break-word;
135
+ }
136
+
137
+ button {
138
+ background: linear-gradient(135deg, #1976D2, #2196F3);
139
+ color: white;
140
+ border: none;
141
+ padding: 12px 25px;
142
+ border-radius: 10px;
143
+ cursor: pointer;
144
+ font-weight: 600;
145
+ font-size: 15px;
146
+ transition: all 0.3s ease;
147
+ box-shadow: 0 3px 8px rgba(25, 118, 210, 0.2);
148
+ display: flex;
149
+ align-items: center;
150
+ gap: 8px;
151
+ white-space: nowrap;
152
+ }
153
+
154
+ button:hover:not(:disabled) {
155
+ transform: translateY(-2px);
156
+ box-shadow: 0 5px 15px rgba(25, 118, 210, 0.3);
157
+ }
158
+
159
+ button:active:not(:disabled) {
160
+ transform: translateY(0);
161
+ }
162
+
163
+ button:disabled {
164
+ opacity: 0.5;
165
+ cursor: not-allowed;
166
+ background: #b0bec5;
167
+ }
168
+
169
+ /* ================= ONGLET 1: ÉVALUATEUR GDPR ================= */
170
+ #tab-evaluator .evaluator-info {
171
+ background: linear-gradient(135deg, #fff3e0, #ffe0b2);
172
+ padding: 25px;
173
+ border-radius: 15px;
174
+ border-left: 6px solid #ff9800;
175
+ margin: 20px 0;
176
+ }
177
+
178
+ #tab-evaluator .evaluator-info h4 {
179
+ color: #ff9800;
180
+ margin-top: 0;
181
+ margin-bottom: 20px;
182
+ display: flex;
183
+ align-items: center;
184
+ gap: 10px;
185
+ font-size: 20px;
186
+ }
187
+
188
+ .evaluator-field {
189
+ margin-bottom: 20px;
190
+ background: white;
191
+ padding: 20px;
192
+ border-radius: 10px;
193
+ border: 1px solid #FFE0B2;
194
+ }
195
+
196
+ .evaluator-field label {
197
+ display: block;
198
+ margin-bottom: 12px;
199
+ color: #333;
200
+ font-weight: 600;
201
+ font-size: 15px;
202
+ }
203
+
204
+ .evaluator-field input[type="text"],
205
+ .evaluator-field select {
206
+ width: 100%;
207
+ padding: 14px 18px;
208
+ border: 2px solid #e0e0e0;
209
+ border-radius: 8px;
210
+ font-size: 15px;
211
+ transition: all 0.3s;
212
+ box-sizing: border-box;
213
+ background: white;
214
+ }
215
+
216
+ .evaluator-field input[type="text"]:focus,
217
+ .evaluator-field select:focus {
218
+ outline: none;
219
+ border-color: #1976D2;
220
+ box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);
221
+ }
222
+
223
+ .evaluator-field input:disabled,
224
+ .evaluator-field select:disabled {
225
+ background: #f5f5f5;
226
+ color: #999;
227
+ cursor: not-allowed;
228
+ }
229
+
230
+ .evaluator-field small {
231
+ display: block;
232
+ margin-top: 8px;
233
+ color: #666;
234
+ font-size: 13px;
235
+ font-style: italic;
236
+ }
237
+
238
+ /* Style pour les boutons radio GDPR */
239
+ .gdpr-options {
240
+ display: flex;
241
+ gap: 30px;
242
+ margin-top: 10px;
243
+ flex-wrap: wrap;
244
+ }
245
+
246
+ .gdpr-option {
247
+ display: flex;
248
+ align-items: center;
249
+ gap: 10px;
250
+ cursor: pointer;
251
+ padding: 12px 20px;
252
+ border-radius: 8px;
253
+ background: white;
254
+ border: 2px solid #e0e0e0;
255
+ transition: all 0.3s;
256
+ flex: 1;
257
+ min-width: 250px;
258
+ }
259
+
260
+ .gdpr-option:hover {
261
+ border-color: #1976D2;
262
+ background: #f0f7ff;
263
+ }
264
+
265
+ .gdpr-option input[type="radio"] {
266
+ width: 20px;
267
+ height: 20px;
268
+ cursor: pointer;
269
+ }
270
+
271
+ .gdpr-option span {
272
+ font-size: 15px;
273
+ font-weight: 500;
274
+ color: #333;
275
+ }
276
+
277
+ #anonymousMessage {
278
+ background: #E3F2FD;
279
+ padding: 18px;
280
+ border-radius: 10px;
281
+ margin-top: 20px;
282
+ border-left: 4px solid #1976D2;
283
+ animation: fadeIn 0.5s ease;
284
+ }
285
+
286
+ #anonymousMessage p {
287
+ margin: 0;
288
+ color: #1976D2;
289
+ font-size: 14px;
290
+ line-height: 1.5;
291
+ }
292
+
293
+ /* ================= ONGLET 2: DASHBOARD ÉTUDIANT COMPACT ================= */
294
+ #tab-dashboard .manifest-item {
295
+ background: linear-gradient(135deg, #f9fbe7, #f0f4c3);
296
+ padding: 15px;
297
+ border-radius: 12px;
298
+ border-left: 6px solid #cddc39;
299
+ margin: 15px 0;
300
+ box-shadow: 0 3px 10px rgba(0,0,0,0.05);
301
+ font-size: 14px;
302
+ }
303
+
304
+ .manifest-item b {
305
+ color: #689f38;
306
+ }
307
+
308
+ /* ================= COMPÉTENCES COMPACTES ================= */
309
+ #competence-bars {
310
+ background: white;
311
+ padding: 15px;
312
+ border-radius: 12px;
313
+ border: 1px solid #e0e0e0;
314
+ margin: 15px 0;
315
+ }
316
+
317
+ .compact-competences-grid {
318
+ display: grid;
319
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
320
+ gap: 12px;
321
+ margin: 10px 0;
322
+ }
323
+
324
+ .compact-competence-item {
325
+ padding: 10px;
326
+ background: #f8f9fa;
327
+ border-radius: 8px;
328
+ border-left: 4px solid #1976D2;
329
+ transition: transform 0.2s;
330
+ }
331
+
332
+ .compact-competence-item:hover {
333
+ transform: translateY(-2px);
334
+ background: #e3f2fd;
335
+ }
336
+
337
+ .compact-competence-label {
338
+ font-size: 12px;
339
+ font-weight: 600;
340
+ color: #333;
341
+ margin-bottom: 8px;
342
+ display: flex;
343
+ justify-content: space-between;
344
+ }
345
+
346
+ .compact-competence-bar {
347
+ height: 10px;
348
+ background: #e0e0e0;
349
+ border-radius: 5px;
350
+ overflow: hidden;
351
+ margin: 5px 0;
352
+ }
353
+
354
+ .compact-competence-fill {
355
+ height: 100%;
356
+ border-radius: 5px;
357
+ color: white;
358
+ font-size: 9px;
359
+ text-align: right;
360
+ padding-right: 5px;
361
+ line-height: 10px;
362
+ font-weight: bold;
363
+ transition: width 0.5s ease;
364
+ }
365
+
366
+ /* ================= LÉGENDE RADAR COMPACTE ================= */
367
+ .compact-radar-legend {
368
+ display: flex;
369
+ justify-content: center;
370
+ gap: 15px;
371
+ margin: 15px 0;
372
+ flex-wrap: wrap;
373
+ padding: 10px;
374
+ background: white;
375
+ border-radius: 8px;
376
+ border: 1px solid #e0e0e0;
377
+ }
378
+
379
+ .compact-legend-item {
380
+ display: flex;
381
+ align-items: center;
382
+ gap: 8px;
383
+ padding: 6px 10px;
384
+ background: #f8f9fa;
385
+ border-radius: 6px;
386
+ font-size: 12px;
387
+ }
388
+
389
+ .compact-legend-color {
390
+ width: 16px;
391
+ height: 16px;
392
+ border-radius: 4px;
393
+ border: 2px solid white;
394
+ }
395
+
396
+ .compact-legend-low { background: linear-gradient(135deg, #e53935, #f44336); }
397
+ .compact-legend-medium { background: linear-gradient(135deg, #fb8c00, #ff9800); }
398
+ .compact-legend-high { background: linear-gradient(135deg, #43a047, #4caf50); }
399
+
400
+ /* ================= RADAR COMPACT ================= */
401
+ #radar-container {
402
+ background: white;
403
+ padding: 15px;
404
+ border-radius: 12px;
405
+ border: 1px solid #e0e0e0;
406
+ margin: 15px 0;
407
+ }
408
+
409
+ #radar {
410
+ max-width: 100%;
411
+ height: auto;
412
+ }
413
+
414
+ /* ================= MESSAGE BOT RADAR COMPACT ================= */
415
+ .compact-radar-bot-message {
416
+ background: linear-gradient(135deg, #E3F2FD, #BBDEFB);
417
+ padding: 15px;
418
+ border-radius: 10px;
419
+ border-left: 4px solid #1976D2;
420
+ margin: 15px 0;
421
+ }
422
+
423
+ .compact-radar-bot-header {
424
+ display: flex;
425
+ align-items: center;
426
+ gap: 10px;
427
+ margin-bottom: 10px;
428
+ }
429
+
430
+ .compact-radar-bot-icon {
431
+ font-size: 20px;
432
+ background: #1976D2;
433
+ color: white;
434
+ width: 40px;
435
+ height: 40px;
436
+ border-radius: 50%;
437
+ display: flex;
438
+ align-items: center;
439
+ justify-content: center;
440
+ }
441
+
442
+ .compact-radar-bot-title {
443
+ font-size: 16px;
444
+ font-weight: 600;
445
+ color: #1976D2;
446
+ margin: 0;
447
+ }
448
+
449
+ .compact-radar-bot-content {
450
+ font-size: 14px;
451
+ line-height: 1.5;
452
+ color: #333;
453
+ margin: 0;
454
+ }
455
+
456
+ .compact-radar-bot-insights {
457
+ background: white;
458
+ padding: 10px;
459
+ border-radius: 8px;
460
+ margin-top: 10px;
461
+ border: 1px solid #E3F2FD;
462
+ }
463
+
464
+ .compact-radar-insight-item {
465
+ display: flex;
466
+ align-items: center;
467
+ gap: 8px;
468
+ margin-bottom: 6px;
469
+ padding: 6px 10px;
470
+ border-radius: 6px;
471
+ background: #F5F5F5;
472
+ font-size: 12px;
473
+ }
474
+
475
+ /* ================= GRILLE DES MÉTRIQUES RADAR COMPACTE ================= */
476
+ .compact-radar-metrics-grid {
477
+ display: grid;
478
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
479
+ gap: 12px;
480
+ margin: 15px 0;
481
+ }
482
+
483
+ .compact-metric-card {
484
+ background: white;
485
+ border-radius: 10px;
486
+ padding: 15px;
487
+ box-shadow: 0 3px 8px rgba(0,0,0,0.08);
488
+ border-left: 4px solid #1976D2;
489
+ transition: transform 0.3s;
490
+ text-align: center;
491
+ }
492
+
493
+ .compact-metric-card:hover {
494
+ transform: translateY(-3px);
495
+ box-shadow: 0 5px 15px rgba(0,0,0,0.12);
496
+ }
497
+
498
+ .compact-metric-icon {
499
+ font-size: 24px;
500
+ margin-bottom: 8px;
501
+ }
502
+
503
+ .compact-metric-name {
504
+ font-weight: 600;
505
+ color: #333;
506
+ margin-bottom: 5px;
507
+ font-size: 14px;
508
+ }
509
+
510
+ .compact-metric-value {
511
+ font-size: 20px;
512
+ font-weight: bold;
513
+ color: #1976D2;
514
+ margin: 5px 0;
515
+ }
516
+
517
+ .compact-metric-value.high { color: #43A047; }
518
+ .compact-metric-value.medium { color: #FB8C00; }
519
+ .compact-metric-value.low { color: #E53935; }
520
+
521
+ .compact-metric-description {
522
+ font-size: 11px;
523
+ color: #666;
524
+ margin-top: 5px;
525
+ line-height: 1.3;
526
+ }
527
+
528
+ /* ================= HEATMAP COMPACT ================= */
529
+ .compact-heatmap-and-indicators {
530
+ background: white;
531
+ padding: 15px;
532
+ border-radius: 12px;
533
+ border: 1px solid #e0e0e0;
534
+ margin: 15px 0;
535
+ }
536
+
537
+ .compact-heatmap-analysis {
538
+ margin-bottom: 15px;
539
+ }
540
+
541
+ .compact-analysis-controls {
542
+ display: flex;
543
+ align-items: center;
544
+ gap: 10px;
545
+ margin-bottom: 15px;
546
+ padding: 10px;
547
+ background: #f8f9fa;
548
+ border-radius: 8px;
549
+ }
550
+
551
+ .compact-analysis-controls label {
552
+ font-weight: 600;
553
+ color: #1976D2;
554
+ font-size: 14px;
555
+ }
556
+
557
+ .compact-analysis-controls select {
558
+ padding: 8px 12px;
559
+ border-radius: 6px;
560
+ border: 2px solid #1976D2;
561
+ background: white;
562
+ color: #333;
563
+ font-weight: 500;
564
+ cursor: pointer;
565
+ flex-grow: 1;
566
+ font-size: 14px;
567
+ }
568
+
569
+ #heatmap {
570
+ max-width: 100%;
571
+ height: auto;
572
+ border-radius: 8px;
573
+ }
574
+
575
+ /* ================= LÉGENDE HEATMAP COMPACTE ================= */
576
+ .compact-enriched-legend {
577
+ background: white;
578
+ padding: 15px;
579
+ border-radius: 10px;
580
+ border: 1px solid #e0e0e0;
581
+ margin: 15px 0;
582
+ }
583
+
584
+ .compact-legend-section h5 {
585
+ color: #1976D2;
586
+ margin-bottom: 10px;
587
+ font-size: 14px;
588
+ display: flex;
589
+ align-items: center;
590
+ gap: 6px;
591
+ }
592
+
593
+ .compact-legend-grid {
594
+ display: grid;
595
+ grid-template-columns: repeat(3, 1fr);
596
+ gap: 8px;
597
+ }
598
+
599
+ .compact-legend-item-small {
600
+ display: flex;
601
+ align-items: center;
602
+ gap: 6px;
603
+ font-size: 11px;
604
+ }
605
+
606
+ .compact-legend-color-small {
607
+ width: 16px;
608
+ height: 16px;
609
+ border-radius: 4px;
610
+ border: 2px solid white;
611
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
612
+ }
613
+
614
+ /* ================= INDICATEURS DE PERSÉVÉRANCE COMPACTS ================= */
615
+ .compact-persistence-analysis {
616
+ background: linear-gradient(135deg, #e3f2fd, #f3e5f5);
617
+ padding: 15px;
618
+ border-radius: 10px;
619
+ border-left: 4px solid #1976D2;
620
+ margin: 15px 0;
621
+ }
622
+
623
+ .compact-persistence-indicators {
624
+ display: flex;
625
+ flex-direction: column;
626
+ gap: 8px;
627
+ margin-bottom: 10px;
628
+ }
629
+
630
+ .compact-indicator {
631
+ display: flex;
632
+ align-items: center;
633
+ gap: 8px;
634
+ padding: 8px 10px;
635
+ background: white;
636
+ border-radius: 6px;
637
+ font-size: 12px;
638
+ border-left: 3px solid #1976D2;
639
+ }
640
+
641
+ .compact-indicator-dot {
642
+ width: 10px;
643
+ height: 10px;
644
+ border-radius: 50%;
645
+ }
646
+
647
+ .compact-persistence-text {
648
+ font-size: 12px;
649
+ line-height: 1.4;
650
+ }
651
+
652
+ .compact-persistence-text > div {
653
+ margin-bottom: 6px;
654
+ padding: 8px;
655
+ background: white;
656
+ border-radius: 6px;
657
+ border-left: 3px solid #1976D2;
658
+ }
659
+
660
+ /* ================= ONGLET 3: MESSAGE RÉFLEXIF ET ÉVALUATION ================= */
661
+ #tab-evaluation #reflagent {
662
+ background: linear-gradient(135deg, #e8f5e9, #c8e6c9);
663
+ padding: 25px;
664
+ border-radius: 15px;
665
+ border-left: 8px solid #43a047;
666
+ margin: 25px 0;
667
+ font-size: 16px;
668
+ line-height: 1.6;
669
+ position: relative;
670
+ overflow: hidden;
671
+ min-height: 100px;
672
+ display: flex;
673
+ align-items: center;
674
+ }
675
+
676
+ #tab-evaluation #reflagent::before {
677
+ content: '🤖';
678
+ position: absolute;
679
+ top: 15px;
680
+ right: 15px;
681
+ font-size: 40px;
682
+ opacity: 0.2;
683
+ }
684
+
685
+ /* ================= MÉTRIQUES DE CONFIANCE ================= */
686
+ #tab-evaluation hr {
687
+ border: none;
688
+ height: 2px;
689
+ background: linear-gradient(90deg, #1976D2, transparent);
690
+ margin: 40px 0;
691
+ }
692
+
693
+ .trust-item {
694
+ margin-bottom: 20px;
695
+ padding: 15px;
696
+ background: #f8f9fa;
697
+ border-radius: 12px;
698
+ transition: transform 0.3s;
699
+ }
700
+
701
+ .trust-item:hover {
702
+ transform: translateX(5px);
703
+ background: #f1f3f4;
704
+ }
705
+
706
+ .trust-item b {
707
+ display: block;
708
+ margin-bottom: 10px;
709
+ color: #1976D2;
710
+ font-size: 15px;
711
+ }
712
+
713
+ .stars {
714
+ display: flex;
715
+ gap: 8px;
716
+ margin: 10px 0;
717
+ }
718
+
719
+ .stars span {
720
+ font-size: 32px;
721
+ cursor: pointer;
722
+ color: #e0e0e0;
723
+ transition: all 0.2s;
724
+ text-shadow: none;
725
+ }
726
+
727
+ .stars span.active {
728
+ color: #ffd54f;
729
+ text-shadow: 0 2px 4px rgba(255, 213, 79, 0.3);
730
+ }
731
+
732
+ .stars span:hover {
733
+ transform: scale(1.2);
734
+ }
735
+
736
+ .stars span.inactive {
737
+ color: #e0e0e0;
738
+ text-shadow: none;
739
+ }
740
+
741
+ .stars span.inactive:hover {
742
+ color: #ffd54f;
743
+ }
744
+
745
+ /* ================= CHAMP COMMENTAIRE ================= */
746
+ textarea {
747
+ width: 100%;
748
+ min-height: 120px;
749
+ border-radius: 12px;
750
+ padding: 15px;
751
+ border: 2px solid #e0e0e0;
752
+ font-family: inherit;
753
+ font-size: 14px;
754
+ resize: vertical;
755
+ transition: all 0.3s;
756
+ margin-bottom: 20px;
757
+ }
758
+
759
+ textarea:focus {
760
+ outline: none;
761
+ border-color: #1976D2;
762
+ box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);
763
+ }
764
+
765
+ /* ================= BARRE DE CONFIANCE ================= */
766
+ .progress-container {
767
+ width: 100%;
768
+ background: #f5f5f5;
769
+ border-radius: 12px;
770
+ height: 24px;
771
+ margin: 8px 0 20px;
772
+ overflow: hidden;
773
+ box-shadow: inset 0 2px 5px rgba(0,0,0,0.1);
774
+ }
775
+
776
+ #trustBar {
777
+ height: 100%;
778
+ border-radius: 10px;
779
+ color: white;
780
+ font-size: 14px;
781
+ text-align: center;
782
+ line-height: 24px;
783
+ font-weight: bold;
784
+ transition: width 0.5s ease, background 0.5s ease;
785
+ position: relative;
786
+ overflow: hidden;
787
+ width: 0%;
788
+ background: #e0e0e0;
789
+ display: flex;
790
+ align-items: center;
791
+ justify-content: center;
792
+ padding: 0 10px;
793
+ box-sizing: border-box;
794
+ }
795
+
796
+ #trustBar::after {
797
+ content: '';
798
+ position: absolute;
799
+ top: 0;
800
+ left: 0;
801
+ right: 0;
802
+ bottom: 0;
803
+ background: linear-gradient(90deg,
804
+ transparent,
805
+ rgba(255,255,255,0.4),
806
+ transparent
807
+ );
808
+ animation: shimmer 2s infinite;
809
+ }
810
+
811
+ /* ================= BOUTON LECTURE CROISÉE ================= */
812
+ #crossReadersBtn {
813
+ background: linear-gradient(135deg, #43A047, #4CAF50) !important;
814
+ color: white;
815
+ border: none;
816
+ padding: 12px 25px;
817
+ border-radius: 10px;
818
+ cursor: pointer;
819
+ font-weight: 600;
820
+ font-size: 15px;
821
+ transition: all 0.3s ease;
822
+ box-shadow: 0 3px 8px rgba(67, 160, 71, 0.2);
823
+ display: flex;
824
+ align-items: center;
825
+ justify-content: center;
826
+ gap: 8px;
827
+ width: 100%;
828
+ }
829
+
830
+ #crossReadersBtn:hover:not(:disabled) {
831
+ transform: translateY(-2px);
832
+ box-shadow: 0 5px 15px rgba(67, 160, 71, 0.3);
833
+ background: linear-gradient(135deg, #388E3C, #43A047) !important;
834
+ }
835
+
836
+ #crossReadersBtn:active:not(:disabled) {
837
+ transform: translateY(0);
838
+ }
839
+
840
+ #crossReadersBtn:disabled {
841
+ opacity: 0.5;
842
+ cursor: not-allowed;
843
+ background: #b0bec5 !important;
844
+ }
845
+
846
+ /* ================= MESSAGES ================= */
847
+ #saveTrustMsg {
848
+ padding: 10px 15px;
849
+ border-radius: 8px;
850
+ margin: 10px 0;
851
+ font-weight: 500;
852
+ text-align: center;
853
+ transition: all 0.3s;
854
+ min-height: 50px;
855
+ display: flex;
856
+ align-items: center;
857
+ justify-content: center;
858
+ }
859
+
860
+ /* ================= STATISTIQUES ================= */
861
+ .stats-grid {
862
+ display: grid;
863
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
864
+ gap: 15px;
865
+ margin: 20px 0;
866
+ }
867
+
868
+ .stat-item {
869
+ background: linear-gradient(135deg, #e3f2fd, #f3e5f5);
870
+ padding: 15px;
871
+ border-radius: 10px;
872
+ text-align: center;
873
+ transition: transform 0.3s;
874
+ }
875
+
876
+ .stat-item:hover {
877
+ transform: translateY(-3px);
878
+ box-shadow: 0 5px 15px rgba(0,0,0,0.1);
879
+ }
880
+
881
+ .stat-value {
882
+ font-size: 28px;
883
+ font-weight: bold;
884
+ color: #1976D2;
885
+ margin: 10px 0;
886
+ }
887
+
888
+ .stat-label {
889
+ font-size: 13px;
890
+ color: #666;
891
+ font-weight: 500;
892
+ }
893
+
894
+ /* ================= ANIMATIONS ================= */
895
+ @keyframes fadeIn {
896
+ from { opacity: 0; transform: translateY(20px); }
897
+ to { opacity: 1; transform: translateY(0); }
898
+ }
899
+
900
+ @keyframes slideIn {
901
+ from { transform: translateX(100%); opacity: 0; }
902
+ to { transform: translateX(0); opacity: 1; }
903
+ }
904
+
905
+ @keyframes slideOut {
906
+ from { transform: translateX(0); opacity: 1; }
907
+ to { transform: translateX(100%); opacity: 0; }
908
+ }
909
+
910
+ @keyframes pulse {
911
+ 0% { transform: scale(1); }
912
+ 50% { transform: scale(1.05); }
913
+ 100% { transform: scale(1); }
914
+ }
915
+
916
+ @keyframes spin {
917
+ 0% { transform: rotate(0deg); }
918
+ 100% { transform: rotate(360deg); }
919
+ }
920
+
921
+ @keyframes shimmer {
922
+ 0% { transform: translateX(-100%); }
923
+ 100% { transform: translateX(100%); }
924
+ }
925
+
926
+ /* ================= TOOLTIPS ================= */
927
+ .tooltip {
928
+ position: absolute;
929
+ background: rgba(25, 118, 210, 0.95);
930
+ color: white;
931
+ padding: 12px 18px;
932
+ border-radius: 10px;
933
+ font-size: 14px;
934
+ pointer-events: none;
935
+ opacity: 0;
936
+ transition: opacity 0.3s;
937
+ z-index: 1000;
938
+ max-width: 300px;
939
+ box-shadow: 0 6px 20px rgba(0,0,0,0.2);
940
+ border: 2px solid white;
941
+ backdrop-filter: blur(5px);
942
+ }
943
+
944
+ .tooltip::after {
945
+ content: '';
946
+ position: absolute;
947
+ top: 100%;
948
+ left: 50%;
949
+ margin-left: -10px;
950
+ border-width: 10px;
951
+ border-style: solid;
952
+ border-color: rgba(25, 118, 210, 0.95) transparent transparent transparent;
953
+ }
954
+
955
+ /* ================= SCROLLBAR ================= */
956
+ ::-webkit-scrollbar {
957
+ width: 10px;
958
+ }
959
+
960
+ ::-webkit-scrollbar-track {
961
+ background: #f1f1f1;
962
+ border-radius: 5px;
963
+ }
964
+
965
+ ::-webkit-scrollbar-thumb {
966
+ background: linear-gradient(135deg, #1976D2, #2196F3);
967
+ border-radius: 5px;
968
+ }
969
+
970
+ ::-webkit-scrollbar-thumb:hover {
971
+ background: linear-gradient(135deg, #1565c0, #1976D2);
972
+ }
973
+
974
+ /* ================= LOADING ================= */
975
+ .loading {
976
+ display: inline-block;
977
+ width: 20px;
978
+ height: 20px;
979
+ border: 3px solid #f3f3f3;
980
+ border-top: 3px solid #1976D2;
981
+ border-radius: 50%;
982
+ animation: spin 1s linear infinite;
983
+ }
984
+
985
+ /* ================= NOTIFICATIONS ================= */
986
+ .notification {
987
+ position: fixed;
988
+ top: 20px;
989
+ right: 20px;
990
+ background: white;
991
+ padding: 18px;
992
+ border-radius: 12px;
993
+ box-shadow: 0 8px 25px rgba(0,0,0,0.15);
994
+ border-left: 6px solid #1976D2;
995
+ z-index: 10000;
996
+ max-width: 320px;
997
+ animation: slideIn 0.4s ease-out;
998
+ display: flex;
999
+ align-items: flex-start;
1000
+ gap: 12px;
1001
+ }
1002
+
1003
+ .notification-icon {
1004
+ font-size: 28px;
1005
+ flex-shrink: 0;
1006
+ }
1007
+
1008
+ .notification-content {
1009
+ flex-grow: 1;
1010
+ }
1011
+
1012
+ .notification-title {
1013
+ font-weight: bold;
1014
+ color: #1976D2;
1015
+ margin-bottom: 5px;
1016
+ font-size: 15px;
1017
+ }
1018
+
1019
+ .notification-message {
1020
+ color: #555;
1021
+ font-size: 13px;
1022
+ line-height: 1.4;
1023
+ }
1024
+
1025
+ .notification-close {
1026
+ background: none;
1027
+ border: none;
1028
+ color: #999;
1029
+ cursor: pointer;
1030
+ padding: 0;
1031
+ font-size: 20px;
1032
+ line-height: 1;
1033
+ }
1034
+
1035
+ /* ================= RESPONSIVE ================= */
1036
+ @media (max-width: 1200px) {
1037
+ #reflection {
1038
+ padding: 20px;
1039
+ }
1040
+
1041
+ .tabs {
1042
+ flex-direction: column;
1043
+ }
1044
+
1045
+ .tab-btn {
1046
+ width: 100%;
1047
+ }
1048
+ }
1049
+
1050
+ @media (max-width: 768px) {
1051
+ body {
1052
+ padding: 10px;
1053
+ }
1054
+
1055
+ .nav {
1056
+ flex-direction: column;
1057
+ gap: 15px;
1058
+ text-align: center;
1059
+ }
1060
+
1061
+ #scenarioTitle {
1062
+ margin: 10px 0;
1063
+ font-size: 1.2em;
1064
+ }
1065
+
1066
+ button {
1067
+ width: 100%;
1068
+ justify-content: center;
1069
+ }
1070
+
1071
+ .gdpr-options {
1072
+ flex-direction: column;
1073
+ gap: 10px;
1074
+ }
1075
+
1076
+ .gdpr-option {
1077
+ min-width: 100%;
1078
+ }
1079
+
1080
+ .compact-competences-grid {
1081
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
1082
+ }
1083
+
1084
+ .compact-radar-metrics-grid {
1085
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
1086
+ }
1087
+
1088
+ .compact-radar-legend {
1089
+ flex-direction: column;
1090
+ align-items: center;
1091
+ gap: 8px;
1092
+ }
1093
+
1094
+ .compact-legend-grid {
1095
+ grid-template-columns: repeat(2, 1fr);
1096
+ }
1097
+
1098
+ .compact-analysis-controls {
1099
+ flex-direction: column;
1100
+ align-items: stretch;
1101
+ }
1102
+
1103
+ .compact-persistence-indicators {
1104
+ flex-direction: column;
1105
+ }
1106
+
1107
+ .stats-grid {
1108
+ grid-template-columns: repeat(2, 1fr);
1109
+ }
1110
+
1111
+ .tab-btn {
1112
+ min-width: 100%;
1113
+ }
1114
+ }
1115
+
1116
+ @media (max-width: 480px) {
1117
+ .stats-grid {
1118
+ grid-template-columns: 1fr;
1119
+ }
1120
+
1121
+ .compact-radar-metrics-grid {
1122
+ grid-template-columns: 1fr;
1123
+ }
1124
+
1125
+ .compact-competences-grid {
1126
+ grid-template-columns: 1fr;
1127
+ }
1128
+ }
1129
+ </style>
1130
+ </head>
1131
+
1132
+ <body>
1133
+
1134
+ <div id="reflection">
1135
+
1136
+ <!-- NAVIGATION SCÉNARIOS -->
1137
+ <div class="nav">
1138
+ <button id="prevScenario">⬅️ Scénario précédent</button>
1139
+ <h3 id="scenarioTitle">Chargement...</h3>
1140
+ <button id="nextScenario">Scénario suivant ➡️</button>
1141
+ </div>
1142
+
1143
+ <!-- SYSTEME D'ONGLETS -->
1144
+ <div class="tabs-container">
1145
+ <div class="tabs">
1146
+ <button class="tab-btn active" data-tab="tab-evaluator">
1147
+ <span>👤</span> Évaluateur (RGPD)
1148
+ </button>
1149
+ <button class="tab-btn" data-tab="tab-dashboard">
1150
+ <span>📊</span> Dashboard Étudiant
1151
+ </button>
1152
+ <button class="tab-btn" data-tab="tab-evaluation">
1153
+ <span>🤖</span> Message Réflexif & Évaluation
1154
+ </button>
1155
+ </div>
1156
+
1157
+ <!-- ONGLET 1: INFORMATIONS ÉVALUATEUR GDPR -->
1158
+ <div id="tab-evaluator" class="tab-content active">
1159
+ <h3>👤 Informations de l'évaluateur (RGPD)</h3>
1160
+
1161
+ <div class="evaluator-info">
1162
+ <!-- Consentement RGPD -->
1163
+ <div class="evaluator-field">
1164
+ <label for="gdprConsent">
1165
+ <strong><span style="color: #1976D2; margin-right: 5px;">🔒</span> Consentement RGPD <span style="color: #e53935;">*</span></strong>
1166
+ </label>
1167
+ <div class="gdpr-options">
1168
+ <label class="gdpr-option">
1169
+ <input type="radio" name="gdprConsent" value="accept" id="gdprAccept" required>
1170
+ <span>J'accepte de partager mes informations pour l'évaluation</span>
1171
+ </label>
1172
+ <label class="gdpr-option">
1173
+ <input type="radio" name="gdprConsent" value="decline" id="gdprDecline">
1174
+ <span>Je préfère rester anonyme</span>
1175
+ </label>
1176
+ </div>
1177
+ <small>Veuillez accepter le consentement RGPD pour pouvoir remplir les champs d'identification</small>
1178
+ </div>
1179
+
1180
+ <!-- Champs conditionnels (masqués par défaut) -->
1181
+ <div id="evaluatorFields" style="display: none;">
1182
+ <!-- Nom et prénom -->
1183
+ <div class="evaluator-field">
1184
+ <label for="evaluatorName">
1185
+ <strong><span style="color: #1976D2; margin-right: 5px;">📝</span> Nom et prénom <span style="color: #e53935;">*</span></strong>
1186
+ </label>
1187
+ <input type="text"
1188
+ id="evaluatorName"
1189
+ placeholder="Ex: Dupont Jean ou Marie Curie"
1190
+ maxlength="100"
1191
+ disabled>
1192
+ <small>Veuillez saisir votre nom et prénom</small>
1193
+ </div>
1194
+
1195
+ <!-- Rôle -->
1196
+ <div class="evaluator-field">
1197
+ <label for="evaluatorRole"><strong><span style="color: #1976D2; margin-right: 5px;">👔</span> Rôle principal <span style="color: #e53935;">*</span></strong></label>
1198
+ <select id="evaluatorRole" disabled>
1199
+ <option value="">Sélectionnez votre rôle...</option>
1200
+ <option value="enseignant">Enseignant / Formateur</option>
1201
+ <option value="chercheur">Chercheur / Scientifique</option>
1202
+ <option value="expert_pedago">Expert pédagogique</option>
1203
+ <option value="etudiant_avance">Étudiant avancé / Doctorant</option>
1204
+ <option value="conseiller">Conseiller pédagogique</option>
1205
+ <option value="responsable">Responsable de formation</option>
1206
+ <option value="autre">Autre professionnel de l'éducation</option>
1207
+ </select>
1208
+ <small>Sélectionnez votre rôle principal dans le domaine éducatif</small>
1209
+ </div>
1210
+
1211
+ <!-- Niveau d'expertise en réflexivité -->
1212
+ <div class="evaluator-field">
1213
+ <label for="expertiseLevel"><strong><span style="color: #1976D2; margin-right: 5px;">🎓</span> Niveau d'expertise en réflexivité <span style="color: #e53935;">*</span></strong></label>
1214
+ <select id="expertiseLevel" disabled>
1215
+ <option value="">Sélectionnez votre niveau...</option>
1216
+ <option value="debutant">Débutant - Je découvre la réflexivité</option>
1217
+ <option value="intermediaire">Intermédiaire - J'utilise régulièrement des outils réflexifs</option>
1218
+ <option value="avance">Avancé - Je conçois des dispositifs réflexifs</option>
1219
+ <option value="expert">Expert - Je forme à la réflexivité pédagogique</option>
1220
+ <option value="chercheur_reflex">Chercheur en réflexivité</option>
1221
+ </select>
1222
+ <small>Indiquez votre niveau de maîtrise des concepts et outils de réflexivité</small>
1223
+ </div>
1224
+
1225
+ <!-- Niveau de maîtrise des messages réflexifs -->
1226
+ <div class="evaluator-field">
1227
+ <label for="messageMastery"><strong><span style="color: #1976D2; margin-right: 5px;">💬</span> Niveau de maîtrise des messages réflexifs <span style="color: #e53935;">*</span></strong></label>
1228
+ <select id="messageMastery" disabled>
1229
+ <option value="">Sélectionnez votre niveau...</option>
1230
+ <option value="novice">Novice - Je commence à analyser des messages réflexifs</option>
1231
+ <option value="intermediaire_msg">Intermédiaire - J'évalue régulièrement des feedbacks réflexifs</option>
1232
+ <option value="avance_msg">Avancé - Je rédige des messages réflexifs pour autrui</option>
1233
+ <option value="expert_msg">Expert - Je forme à la conception de messages réflexifs</option>
1234
+ </select>
1235
+ <small>Indiquez votre expérience avec l'analyse et la création de messages réflexifs</small>
1236
+ </div>
1237
+ </div>
1238
+
1239
+ <!-- Message pour utilisateurs anonymes -->
1240
+ <div id="anonymousMessage" style="display: none;">
1241
+ <p>
1242
+ <strong><span style="margin-right: 5px;">🕵️</span> Évaluation anonyme :</strong> Vos évaluations seront enregistrées sans information personnelle.
1243
+ Seules vos réponses aux métriques de confiance seront conservées.
1244
+ </p>
1245
+ </div>
1246
+
1247
+ <!-- Boutons d'action -->
1248
+ <div style="display: flex; gap: 10px; margin-top: 20px; flex-wrap: wrap;">
1249
+ <button onclick="fillSampleEvaluator()" type="button" style="background: #666; flex: 1;" id="fillExampleBtn">
1250
+ <span style="margin-right: 5px;">📋</span> Remplir exemple
1251
+ </button>
1252
+ <button onclick="clearEvaluatorFields()" type="button" style="background: #9e9e9e; flex: 1;" id="clearFieldsBtn">
1253
+ <span style="margin-right: 5px;">🗑️</span> Effacer
1254
+ </button>
1255
+ </div>
1256
+ </div>
1257
+ </div>
1258
+
1259
+ <!-- ONGLET 2: DASHBOARD ÉTUDIANT COMPACT -->
1260
+ <div id="tab-dashboard" class="tab-content">
1261
+ <h3>📝 Manifeste étudiant</h3>
1262
+ <div id="manifest-list">
1263
+ <div class="manifest-item">
1264
+ <em>Chargement des données...</em>
1265
+ </div>
1266
+ </div>
1267
+
1268
+ <h3>📊 Progression par compétence</h3>
1269
+ <div id="competence-bars">
1270
+ <div id="compact-competences">
1271
+ <em>Chargement des compétences...</em>
1272
+ </div>
1273
+ </div>
1274
+
1275
+ <!-- LÉGENDE RADAR COMPACTE -->
1276
+ <div class="compact-radar-legend">
1277
+ <div class="compact-legend-item">
1278
+ <div class="compact-legend-color compact-legend-low"></div>
1279
+ <span>Faible (0-50%)</span>
1280
+ </div>
1281
+ <div class="compact-legend-item">
1282
+ <div class="compact-legend-color compact-legend-medium"></div>
1283
+ <span>Moyen (50-70%)</span>
1284
+ </div>
1285
+ <div class="compact-legend-item">
1286
+ <div class="compact-legend-color compact-legend-high"></div>
1287
+ <span>Élevé (70-100%)</span>
1288
+ </div>
1289
+ </div>
1290
+
1291
+ <h3>🕸️ Radar – Learning Analytics</h3>
1292
+
1293
+ <!-- Grille des métriques radar compacte -->
1294
+ <div class="compact-radar-metrics-grid" id="compact-radar-metrics-grid">
1295
+ <!-- Les métriques seront ajoutées dynamiquement -->
1296
+ </div>
1297
+
1298
+ <!-- Container Radar et Bot Message -->
1299
+ <div id="radar-container">
1300
+ <div style="display: flex; gap: 20px; flex-wrap: wrap;">
1301
+ <!-- Message Bot Radar Compact -->
1302
+ <div class="compact-radar-bot-message" style="flex: 1; min-width: 300px;">
1303
+ <div class="compact-radar-bot-header">
1304
+ <div class="compact-radar-bot-icon">🎯</div>
1305
+ <h4 class="compact-radar-bot-title">Analyse de Profil</h4>
1306
+ </div>
1307
+ <p class="compact-radar-bot-content" id="compact-radar-bot-content">Analyse en cours...</p>
1308
+ <div class="compact-radar-bot-insights">
1309
+ <div id="compact-radar-bot-insights">
1310
+ <!-- Les insights seront ajoutés dynamiquement -->
1311
+ </div>
1312
+ </div>
1313
+ </div>
1314
+
1315
+ <!-- Canvas Radar Compact -->
1316
+ <div style="flex: 1; min-width: 300px; text-align: center;">
1317
+ <canvas id="radar" width="500" height="500" style="max-width: 100%; height: auto;"></canvas>
1318
+ </div>
1319
+ </div>
1320
+ </div>
1321
+
1322
+ <!-- HEATMAP COMPACTE -->
1323
+ <div class="compact-heatmap-and-indicators">
1324
+ <h3>🔥 Heatmap d'activité - Analyse de Persévérance</h3>
1325
+
1326
+ <div class="compact-heatmap-analysis">
1327
+ <div class="compact-analysis-controls">
1328
+ <label for="persistenceMode">Mode d'analyse :</label>
1329
+ <select id="persistenceMode" onchange="changePersistenceAnalysis()">
1330
+ <option value="regularity">📊 Régularité du travail</option>
1331
+ <option value="effortPattern">🔄 Schéma d'effort</option>
1332
+ <option value="deadline">⏰ Gestion des échéances</option>
1333
+ <option value="combined">🎯 Vue combinée</option>
1334
+ </select>
1335
+ </div>
1336
+
1337
+ <!-- Canvas pour le heatmap -->
1338
+ <canvas id="heatmap" width="800" height="250" style="max-width: 100%; height: auto;"></canvas>
1339
+ </div>
1340
+
1341
+ <!-- Légende des niveaux d'activité compacte -->
1342
+ <div class="compact-enriched-legend">
1343
+ <div class="compact-legend-section">
1344
+ <h5>📈 Niveaux d'activité</h5>
1345
+ <div class="compact-legend-grid">
1346
+ <div class="compact-legend-item-small">
1347
+ <div class="compact-legend-color-small" style="background:#EBEDF0;"></div>
1348
+ <span>Aucune activité</span>
1349
+ </div>
1350
+ <div class="compact-legend-item-small">
1351
+ <div class="compact-legend-color-small" style="background:#C6E48B;"></div>
1352
+ <span>Faible activité</span>
1353
+ </div>
1354
+ <div class="compact-legend-item-small">
1355
+ <div class="compact-legend-color-small" style="background:#7BC96F;"></div>
1356
+ <span>Activité modérée</span>
1357
+ </div>
1358
+ <div class="compact-legend-item-small">
1359
+ <div class="compact-legend-color-small" style="background:#239A3B;"></div>
1360
+ <span>Activité élevée</span>
1361
+ </div>
1362
+ <div class="compact-legend-item-small">
1363
+ <div class="compact-legend-color-small" style="background:#196127;"></div>
1364
+ <span>Activité intense</span>
1365
+ </div>
1366
+ </div>
1367
+ </div>
1368
+ </div>
1369
+
1370
+ <!-- Analyse de persévérance compacte -->
1371
+ <div class="compact-persistence-analysis" id="compact-persistenceAnalysis">
1372
+ <h5>🎯 Indicateurs de Persévérance</h5>
1373
+ <div class="compact-persistence-indicators">
1374
+ <div class="compact-indicator">
1375
+ <span class="compact-indicator-dot" style="background:#FF6B6B;"></span>
1376
+ <span>Régularité calculée : <strong id="compact-regularityScore">-</strong></span>
1377
+ </div>
1378
+ <div class="compact-indicator">
1379
+ <span class="compact-indicator-dot" style="background:#4ECDC4;"></span>
1380
+ <span>Schéma d'effort : <strong id="compact-effortPattern">-</strong></span>
1381
+ </div>
1382
+ <div class="compact-indicator">
1383
+ <span class="compact-indicator-dot" style="background:#FFD166;"></span>
1384
+ <span>Gestion échéances : <strong id="compact-deadlineScore">-</strong></span>
1385
+ </div>
1386
+ </div>
1387
+
1388
+ <div class="compact-persistence-text" style="margin-top: 10px;">
1389
+ <div style="margin-bottom: 10px;">
1390
+ <strong>Schéma d'effort :</strong>
1391
+ <div style="margin-top: 5px; padding: 8px; background: #F5F5F5; border-radius: 6px; font-size: 13px;">
1392
+ <span id="compact-patternText">Analyse en cours...</span>
1393
+ </div>
1394
+ </div>
1395
+ <div>
1396
+ <strong>Persévérance et gestion des efforts :</strong>
1397
+ <div style="margin-top: 5px; padding: 10px; background: #F8F9FA; border-radius: 6px; border-left: 3px solid #1976D2;">
1398
+ <span id="compact-regularityText">Analyse en cours...</span>
1399
+ </div>
1400
+ </div>
1401
+ </div>
1402
+ </div>
1403
+ </div>
1404
+ </div>
1405
+
1406
+ <!-- ONGLET 3: MESSAGE RÉFLEXIF ET ÉVALUATION -->
1407
+ <div id="tab-evaluation" class="tab-content">
1408
+ <h3>🤖 ReflAgent – Analyse & accompagnement</h3>
1409
+ <div id="reflagent">
1410
+ <em>Le message d'analyse apparaîtra ici après chargement...</em>
1411
+ </div>
1412
+
1413
+ <hr>
1414
+
1415
+ <h3>🧑‍⚖️ Volet Expert – Métriques de Confiance</h3>
1416
+ <p style="color: #666; margin-bottom: 20px; font-style: italic;">
1417
+ Évaluez votre confiance dans l'analyse de ReflAgent pour ce scénario :
1418
+ </p>
1419
+
1420
+ <!-- MÉTRIQUES TRADUITES EN FRANÇAIS -->
1421
+ <div class="trust-item">
1422
+ <b>Authenticité Réflexive (AR)</b>
1423
+ <div class="stars" data-metric="AR">
1424
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1425
+ </div>
1426
+ <small style="color: #666; display: block; margin-top: 5px;">
1427
+ L'analyse reflète-t-elle fidèlement la situation réelle de l'étudiant ?
1428
+ </small>
1429
+ </div>
1430
+
1431
+ <div class="trust-item">
1432
+ <b>Alignement Empathique (AE)</b>
1433
+ <div class="stars" data-metric="AE">
1434
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1435
+ </div>
1436
+ <small style="color: #666; display: block; margin-top: 5px;">
1437
+ L'agent comprend-il les émotions, motivations et difficultés de l'étudiant ?
1438
+ </small>
1439
+ </div>
1440
+
1441
+ <div class="trust-item">
1442
+ <b>Encouragement Sensible au Risque (ESR)</b>
1443
+ <div class="stars" data-metric="ESR">
1444
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1445
+ </div>
1446
+ <small style="color: #666; display: block; margin-top: 5px;">
1447
+ Les encouragements tiennent-ils compte des risques et difficultés identifiés ?
1448
+ </small>
1449
+ </div>
1450
+
1451
+ <div class="trust-item">
1452
+ <b>Support aux Défis Mentaux (SDM)</b>
1453
+ <div class="stars" data-metric="SDM">
1454
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1455
+ </div>
1456
+ <small style="color: #666; display: block; margin-top: 5px;">
1457
+ L'agent aide-t-il l'étudiant à développer sa pensée critique et ses compétences cognitives ?
1458
+ </small>
1459
+ </div>
1460
+
1461
+ <div class="trust-item">
1462
+ <b>Support Métacognitif (SM)</b>
1463
+ <div class="stars" data-metric="SM">
1464
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1465
+ </div>
1466
+ <small style="color: #666; display: block; margin-top: 5px;">
1467
+ L'agent aide-t-il l'étudiant à réfléchir sur ses propres stratégies d'apprentissage ?
1468
+ </small>
1469
+ </div>
1470
+
1471
+ <h4>💬 Commentaire expert</h4>
1472
+ <textarea id="trustComment" placeholder="Ajoutez vos observations, suggestions ou critiques concernant l'analyse de ReflAgent..."></textarea>
1473
+
1474
+ <div style="display: flex; justify-content: space-between; align-items: center; margin: 25px 0; flex-wrap: wrap; gap: 20px;">
1475
+ <div style="flex-grow: 1; min-width: 300px;">
1476
+ <h4 style="margin-bottom: 10px;">🔒 Indice global de confiance</h4>
1477
+ <div class="progress-container">
1478
+ <div id="trustBar">0%</div>
1479
+ </div>
1480
+ <div style="display: flex; justify-content: space-between; margin-top: 5px; font-size: 12px; color: #666;">
1481
+ <span>Faible confiance</span>
1482
+ <span>Confidence moyenne</span>
1483
+ <span>Forte confiance</span>
1484
+ </div>
1485
+ </div>
1486
+ <div style="display: flex; flex-direction: column; gap: 10px; align-items: flex-end; min-width: 200px;">
1487
+ <button id="saveTrustBtn" style="height: fit-content; width: 100%;">💾 Sauvegarder l'évaluation</button>
1488
+ <button id="crossReadersBtn" style="height: fit-content; width: 100%;">
1489
+ 📊 Lecture croisée
1490
+ </button>
1491
+ </div>
1492
+ </div>
1493
+
1494
+ <div id="saveTrustMsg"></div>
1495
+
1496
+ <!-- Statistiques rapides -->
1497
+ <div class="stats-grid">
1498
+ <div class="stat-item">
1499
+ <div class="stat-label">Scénario actuel</div>
1500
+ <div class="stat-value" id="currentScenarioNum">-</div>
1501
+ </div>
1502
+ <div class="stat-item">
1503
+ <div class="stat-label">Confiance moyenne</div>
1504
+ <div class="stat-value" id="avgTrustScore">0%</div>
1505
+ </div>
1506
+ <div class="stat-item">
1507
+ <div class="stat-label">Niveau de risque</div>
1508
+ <div class="stat-value" id="riskLevel">-</div>
1509
+ </div>
1510
+ <div class="stat-item">
1511
+ <div class="stat-label">Activité moyenne</div>
1512
+ <div class="stat-value" id="avgActivity">-</div>
1513
+ </div>
1514
+ </div>
1515
+ </div>
1516
+ </div>
1517
+ </div>
1518
+
1519
+ <!-- Script principal -->
1520
+ <script>
1521
+ // ================= VARIABLES =================
1522
+ let scenarios = [];
1523
+ let currentScenarioIndex = 0;
1524
+ let radarMetrics = [];
1525
+
1526
+ // Métriques de radar par défaut (sans abréviations)
1527
+ const DEFAULT_RADAR_METRICS = [
1528
+ { label: "Démarrage des activités", value: 85 },
1529
+ { label: "Connaissances validées", value: 72 },
1530
+ { label: "Niveau moyen de compétence", value: 68 },
1531
+ { label: "Taux d'erreur (inversé)", value: 35 },
1532
+ { label: "Achèvement des activités", value: 74 },
1533
+ { label: "Interactions avec les ressources", value: 80 },
1534
+ { label: "Domaines de compétence", value: 78 }
1535
+ ];
1536
+
1537
+ // Noms des métriques traduits en français
1538
+ const trustMetrics = {
1539
+ "AR": 0, // Authenticité Réflexive
1540
+ "AE": 0, // Alignement Empathique
1541
+ "ESR": 0, // Encouragement Sensible au Risque
1542
+ "SDM": 0, // Support aux Défis Mentaux
1543
+ "SM": 0 // Support Métacognitif
1544
+ };
1545
+
1546
+ const trustWeights = {
1547
+ "AR": 0.30,
1548
+ "AE": 0.20,
1549
+ "ESR": 0.20,
1550
+ "SDM": 0.10,
1551
+ "SM": 0.20
1552
+ };
1553
+
1554
+ // MAPPING PERSÉVÉRANCE PAR PROFIL
1555
+ const perseveranceProfiles = {
1556
+ "Étudiant engagé": {
1557
+ level: "Très élevée",
1558
+ interpretation: "Efforts constants et durables, persévère même face aux difficultés",
1559
+ color: "#43A047"
1560
+ },
1561
+ "Étudiant actif mais inefficace": {
1562
+ level: "Moyenne",
1563
+ interpretation: "Efforts importants mais mal régulés, persévérance peu productive",
1564
+ color: "#FB8C00"
1565
+ },
1566
+ "Étudiant orienté vers le succès": {
1567
+ level: "Élevée",
1568
+ interpretation: "Persévérance principalement guidée par l'atteinte des objectifs",
1569
+ color: "#4CAF50"
1570
+ },
1571
+ "Étudiant motivé": {
1572
+ level: "Élevée",
1573
+ interpretation: "Engagement soutenu et continuité stable de l'effort",
1574
+ color: "#4CAF50"
1575
+ },
1576
+ "Étudiant surmotivé": {
1577
+ level: "Très élevée",
1578
+ interpretation: "Effort intense, parfois excessif, avec risque de surcharge",
1579
+ color: "#43A047"
1580
+ },
1581
+ "Étudiant stratégique": {
1582
+ level: "Élevée",
1583
+ interpretation: "Effort bien dosé, persévérance optimisée selon le rendement attendu",
1584
+ color: "#4CAF50"
1585
+ },
1586
+ "Étudiant en amélioration": {
1587
+ level: "Moyenne à élevée",
1588
+ interpretation: "Efforts croissants, persévérance en cours de structuration",
1589
+ color: "#FF9800"
1590
+ },
1591
+ "Étudiant en difficulté": {
1592
+ level: "Faible",
1593
+ interpretation: "Découragement fréquent et difficulté à maintenir l'effort",
1594
+ color: "#E53935"
1595
+ },
1596
+ "Étudiant évitant l'échec": {
1597
+ level: "Moyenne",
1598
+ interpretation: "Persévérance motivée par la peur de l'échec plutôt que par l'apprentissage",
1599
+ color: "#FB8C00"
1600
+ },
1601
+ "Étudiant à risque": {
1602
+ level: "Très faible",
1603
+ interpretation: "Abandon rapide et très faible tolérance à l'effort",
1604
+ color: "#C62828"
1605
+ },
1606
+ "Étudiant en progression": {
1607
+ level: "Élevée",
1608
+ interpretation: "Efforts réguliers et de mieux en mieux maîtrisés",
1609
+ color: "#4CAF50"
1610
+ },
1611
+ "Étudiant acceptant l'échec": {
1612
+ level: "Élevée",
1613
+ interpretation: "Bonne résilience, persévère malgré les erreurs et les échecs",
1614
+ color: "#4CAF50"
1615
+ },
1616
+ "Étudiant inactif": {
1617
+ level: "Très faible",
1618
+ interpretation: "Manque d'engagement, difficulté à initier et maintenir l'effort",
1619
+ color: "#C62828"
1620
+ },
1621
+ "Étudiant non engagé": {
1622
+ level: "Faible",
1623
+ interpretation: "Manque de motivation, efforts sporadiques et peu soutenus",
1624
+ color: "#E53935"
1625
+ },
1626
+ "Étudiant persévérant": {
1627
+ level: "Élevée",
1628
+ interpretation: "Constance dans l'effort malgré les doutes et difficultés",
1629
+ color: "#4CAF50"
1630
+ },
1631
+ "Étudiant actif": {
1632
+ level: "Moyenne",
1633
+ interpretation: "Efforts soutenus mais parfois désorganisés ou mal canalisés",
1634
+ color: "#FB8C00"
1635
+ }
1636
+ };
1637
+
1638
+ // ================= INIT =================
1639
+ document.addEventListener("DOMContentLoaded", () => {
1640
+ console.log("✅ DOM chargé, initialisation...");
1641
+ loadScenarios();
1642
+ initTrustStars();
1643
+ initTrustSave();
1644
+ initTabs();
1645
+ initGDPR();
1646
+
1647
+ // Initialiser la barre de confiance à 0%
1648
+ updateTrustBar();
1649
+
1650
+ // Ajouter les écouteurs d'événements pour la navigation
1651
+ document.getElementById("prevScenario").onclick = () => loadScenario(currentScenarioIndex - 1);
1652
+ document.getElementById("nextScenario").onclick = () => loadScenario(currentScenarioIndex + 1);
1653
+ document.getElementById("crossReadersBtn").onclick = navigateToCrossReading;
1654
+ });
1655
+
1656
+ // ================= SYSTEME D'ONGLETS =================
1657
+ function initTabs() {
1658
+ const tabBtns = document.querySelectorAll('.tab-btn');
1659
+ const tabContents = document.querySelectorAll('.tab-content');
1660
+
1661
+ tabBtns.forEach(btn => {
1662
+ btn.addEventListener('click', () => {
1663
+ const tabId = btn.getAttribute('data-tab');
1664
+
1665
+ // Retirer la classe active de tous les boutons et contenus
1666
+ tabBtns.forEach(b => b.classList.remove('active'));
1667
+ tabContents.forEach(c => c.classList.remove('active'));
1668
+
1669
+ // Ajouter la classe active au bouton et au contenu correspondant
1670
+ btn.classList.add('active');
1671
+ document.getElementById(tabId).classList.add('active');
1672
+ });
1673
+ });
1674
+ }
1675
+
1676
+ // ================= GDPR =================
1677
+ function initGDPR() {
1678
+ const gdprAccept = document.getElementById('gdprAccept');
1679
+ const gdprDecline = document.getElementById('gdprDecline');
1680
+ const evaluatorFields = document.getElementById('evaluatorFields');
1681
+ const anonymousMessage = document.getElementById('anonymousMessage');
1682
+
1683
+ // Activer/désactiver les champs selon le choix GDPR
1684
+ function updateGDPRFields() {
1685
+ if (gdprAccept.checked) {
1686
+ // Afficher les champs et les activer
1687
+ evaluatorFields.style.display = 'block';
1688
+ anonymousMessage.style.display = 'none';
1689
+
1690
+ // Activer les champs
1691
+ document.getElementById('evaluatorName').disabled = false;
1692
+ document.getElementById('evaluatorRole').disabled = false;
1693
+ document.getElementById('expertiseLevel').disabled = false;
1694
+ document.getElementById('messageMastery').disabled = false;
1695
+ } else if (gdprDecline.checked) {
1696
+ // Cacher les champs et afficher le message anonyme
1697
+ evaluatorFields.style.display = 'none';
1698
+ anonymousMessage.style.display = 'block';
1699
+
1700
+ // Désactiver et vider les champs
1701
+ document.getElementById('evaluatorName').disabled = true;
1702
+ document.getElementById('evaluatorName').value = '';
1703
+ document.getElementById('evaluatorRole').disabled = true;
1704
+ document.getElementById('evaluatorRole').value = '';
1705
+ document.getElementById('expertiseLevel').disabled = true;
1706
+ document.getElementById('expertiseLevel').value = '';
1707
+ document.getElementById('messageMastery').disabled = true;
1708
+ document.getElementById('messageMastery').value = '';
1709
+ }
1710
+ }
1711
+
1712
+ // Écouter les changements
1713
+ gdprAccept.addEventListener('change', updateGDPRFields);
1714
+ gdprDecline.addEventListener('change', updateGDPRFields);
1715
+
1716
+ // Initialiser
1717
+ updateGDPRFields();
1718
+ }
1719
+
1720
+ // ================= CHARGEMENT JSON =================
1721
+ function loadScenarios() {
1722
+ console.log("Chargement des scénarios...");
1723
+ // Tentative de chargement depuis différents chemins
1724
+ const possiblePaths = [
1725
+ "/static/scenarios.json",
1726
+ "scenarios.json",
1727
+ "./scenarios.json",
1728
+ "../scenarios.json"
1729
+ ];
1730
+
1731
+ let loadAttempts = 0;
1732
+
1733
+ function tryLoad(pathIndex) {
1734
+ if (pathIndex >= possiblePaths.length) {
1735
+ console.error("❌ Impossible de charger les scénarios depuis aucun chemin");
1736
+ showError("Impossible de charger les scénarios. Vérifiez que le fichier scenarios.json existe.");
1737
+ return;
1738
+ }
1739
+
1740
+ const path = possiblePaths[pathIndex];
1741
+ console.log(`Tentative de chargement depuis: ${path}`);
1742
+
1743
+ fetch(path)
1744
+ .then(r => {
1745
+ if (!r.ok) throw new Error(`Erreur HTTP ${r.status}`);
1746
+ return r.json();
1747
+ })
1748
+ .then(data => {
1749
+ console.log("✅ Scénarios chargés:", data.scenarios?.length || 0);
1750
+ scenarios = data.scenarios || [];
1751
+
1752
+ if (scenarios.length === 0) {
1753
+ console.warn("Aucun scénario trouvé dans le fichier");
1754
+ showError("Aucun scénario trouvé dans le fichier JSON");
1755
+ return;
1756
+ }
1757
+
1758
+ loadScenario(0);
1759
+ })
1760
+ .catch(error => {
1761
+ console.warn(`Échec pour ${path}:`, error.message);
1762
+ loadAttempts++;
1763
+ tryLoad(pathIndex + 1);
1764
+ });
1765
+ }
1766
+
1767
+ tryLoad(0);
1768
+ }
1769
+
1770
+ function showError(message) {
1771
+ const manifestList = document.getElementById("manifest-list");
1772
+ if (manifestList) {
1773
+ manifestList.innerHTML =
1774
+ `<div class="manifest-item" style="background:#FFEBEE;color:#C62828;">
1775
+ ${message}<br>
1776
+ <small>Veuillez vérifier que le fichier scenarios.json est présent.</small>
1777
+ </div>`;
1778
+ }
1779
+
1780
+ // Afficher un message dans la console et éventuellement une alerte
1781
+ console.error(message);
1782
+
1783
+ // Désactiver la navigation
1784
+ document.getElementById("prevScenario").disabled = true;
1785
+ document.getElementById("nextScenario").disabled = true;
1786
+ }
1787
+
1788
+ // ================= CHARGER SCÉNARIO =================
1789
+ function loadScenario(index) {
1790
+ console.log("Chargement scénario", index);
1791
+ if (!scenarios || scenarios.length === 0) {
1792
+ console.error("Aucun scénario disponible");
1793
+ return;
1794
+ }
1795
+
1796
+ if (index < 0 || index >= scenarios.length) {
1797
+ console.warn(`Index ${index} hors limites (0-${scenarios.length-1})`);
1798
+ return;
1799
+ }
1800
+
1801
+ currentScenarioIndex = index;
1802
+ const s = scenarios[index];
1803
+
1804
+ // Mettre à jour le titre
1805
+ const titleElement = document.getElementById("scenarioTitle");
1806
+ if (titleElement) {
1807
+ titleElement.textContent = `Scénario ${s.id} – ${s.title}`;
1808
+ }
1809
+
1810
+ // Mettre à jour le manifeste
1811
+ const manifestList = document.getElementById("manifest-list");
1812
+ if (manifestList) {
1813
+ manifestList.innerHTML = `
1814
+ <div class="manifest-item">
1815
+ <b>Type de Manifest :</b> ${s.manifest?.type || "Non spécifié"}<br>
1816
+ <b>Manifeste (écrit par l'étudiant) :</b> ${s.manifest?.manifeste || "Non disponible"}<br>
1817
+ <b>Description du Profil :</b> ${s.manifest?.description || "Non disponible"}
1818
+ </div>`;
1819
+ }
1820
+
1821
+ // Mettre à jour les compétences compactes
1822
+ if (s.competences) {
1823
+ updateCompactCompetences(s.competences);
1824
+ }
1825
+
1826
+ // Mettre à jour le radar avec les nouvelles métriques
1827
+ if (s.radar && s.radar.length > 0) {
1828
+ radarMetrics = s.radar;
1829
+ } else {
1830
+ // Utiliser les métriques par défaut avec variation pour chaque scénario
1831
+ radarMetrics = DEFAULT_RADAR_METRICS.map(metric => {
1832
+ // Variation de ±15% selon l'index du scénario pour rendre les données plus réalistes
1833
+ const variation = (index % 7) * 5 - 15; // -15 à +15
1834
+ const newValue = Math.max(10, Math.min(95, metric.value + variation));
1835
+ return {
1836
+ label: metric.label,
1837
+ value: newValue
1838
+ };
1839
+ });
1840
+ }
1841
+
1842
+ // Mettre à jour la grille des métriques radar compacte
1843
+ updateCompactRadarMetricsGrid();
1844
+
1845
+ // Mettre à jour le graphique radar
1846
+ drawRadar();
1847
+
1848
+ // Mettre à jour le message bot radar compact
1849
+ updateCompactRadarBotMessage(s);
1850
+
1851
+ // Mettre à jour la heatmap enrichie compacte
1852
+ drawCompactEnrichedHeatmap(s);
1853
+
1854
+ // Mettre à jour la persévérance spécifique au profil
1855
+ updatePerseveranceProfile(s.title);
1856
+
1857
+ // Mettre à jour le message ReflAgent
1858
+ const reflagentElement = document.getElementById("reflagent");
1859
+ if (reflagentElement) {
1860
+ reflagentElement.textContent = s.reflAgent || "Message d'analyse non disponible pour ce scénario.";
1861
+ }
1862
+
1863
+ // Mettre à jour les boutons de navigation
1864
+ updateNavButtons();
1865
+
1866
+ // Mettre à jour les statistiques
1867
+ updateStats(s);
1868
+
1869
+ // Réinitialiser l'évaluation de confiance
1870
+ resetTrustEvaluation();
1871
+ }
1872
+
1873
+ // ================= FONCTIONS POUR LA VERSION COMPACTE =================
1874
+
1875
+ // Mettre à jour les compétences compactes
1876
+ function updateCompactCompetences(competences) {
1877
+ const container = document.getElementById("compact-competences");
1878
+ if (!container) return;
1879
+
1880
+ container.innerHTML = '';
1881
+
1882
+ if (!competences || competences.length === 0) {
1883
+ container.innerHTML = '<em>Aucune donnée de compétence disponible</em>';
1884
+ return;
1885
+ }
1886
+
1887
+ competences.forEach(comp => {
1888
+ // Déterminer la couleur selon la valeur
1889
+ let color;
1890
+ if (comp.value < 50) color = '#E53935';
1891
+ else if (comp.value < 70) color = '#FB8C00';
1892
+ else color = '#43A047';
1893
+
1894
+ // Créer l'élément de compétence
1895
+ const compItem = document.createElement('div');
1896
+ compItem.className = 'compact-competence-item';
1897
+ compItem.innerHTML = `
1898
+ <div class="compact-competence-label">
1899
+ <span>${comp.label}</span>
1900
+ <span>${comp.value}%</span>
1901
+ </div>
1902
+ <div class="compact-competence-bar">
1903
+ <div class="compact-competence-fill" style="width: ${comp.value}%; background: ${color};">
1904
+ ${comp.value >= 10 ? comp.value + '%' : ''}
1905
+ </div>
1906
+ </div>
1907
+ `;
1908
+
1909
+ container.appendChild(compItem);
1910
+ });
1911
+ }
1912
+
1913
+ // Mettre à jour la grille des métriques radar compacte
1914
+ function updateCompactRadarMetricsGrid() {
1915
+ const grid = document.getElementById("compact-radar-metrics-grid");
1916
+ if (!grid) return;
1917
+
1918
+ grid.innerHTML = '';
1919
+
1920
+ if (!radarMetrics || radarMetrics.length === 0) {
1921
+ grid.innerHTML = '<em>Aucune métrique radar disponible</em>';
1922
+ return;
1923
+ }
1924
+
1925
+ radarMetrics.forEach(metric => {
1926
+ // Déterminer la classe de couleur selon la valeur
1927
+ let colorClass = "";
1928
+ if (metric.value >= 70) colorClass = "high";
1929
+ else if (metric.value >= 40) colorClass = "medium";
1930
+ else colorClass = "low";
1931
+
1932
+ // Déterminer l'icône selon le type de métrique
1933
+ let icon = "📊";
1934
+ if (metric.label.includes("Démarrage")) icon = "🚀";
1935
+ else if (metric.label.includes("Connaissances")) icon = "🎓";
1936
+ else if (metric.label.includes("Niveau moyen")) icon = "📈";
1937
+ else if (metric.label.includes("Taux d'erreur")) icon = "🎯";
1938
+ else if (metric.label.includes("Achèvement")) icon = "🏁";
1939
+ else if (metric.label.includes("Interactions")) icon = "📚";
1940
+ else if (metric.label.includes("Domaines")) icon = "🔧";
1941
+
1942
+ // Déterminer la description
1943
+ let description = "";
1944
+ if (metric.label.includes("Démarrage")) description = "Rapidité d'initiation";
1945
+ else if (metric.label.includes("Connaissances")) description = "Acquis démontrés";
1946
+ else if (metric.label.includes("Niveau moyen")) description = "Moyenne des compétences";
1947
+ else if (metric.label.includes("Taux d'erreur")) description = "Précision et attention";
1948
+ else if (metric.label.includes("Achèvement")) description = "Terminaison des tâches";
1949
+ else if (metric.label.includes("Interactions")) description = "Utilisation supports";
1950
+ else if (metric.label.includes("Domaines")) description = "Maîtrise des domaines de compétences";
1951
+
1952
+ const metricCard = document.createElement("div");
1953
+ metricCard.className = "compact-metric-card";
1954
+ metricCard.innerHTML = `
1955
+ <div class="compact-metric-icon">${icon}</div>
1956
+ <div class="compact-metric-name">${metric.label}</div>
1957
+ <div class="compact-metric-value ${colorClass}">${metric.value}%</div>
1958
+ <div class="compact-metric-description">${description}</div>
1959
+ `;
1960
+
1961
+ grid.appendChild(metricCard);
1962
+ });
1963
+ }
1964
+
1965
+ // Mettre à jour le message bot radar compact
1966
+ function updateCompactRadarBotMessage(scenario) {
1967
+ const radarBotContent = document.getElementById("compact-radar-bot-content");
1968
+ const radarBotInsights = document.getElementById("compact-radar-bot-insights");
1969
+
1970
+ if (!radarBotContent || !radarBotInsights) return;
1971
+
1972
+ // Messages pour chaque profil basé sur le titre du scénario
1973
+ const profileMessages = {
1974
+ "Étudiant engagé": {
1975
+ title: "Étudiant Engagé et Motivé",
1976
+ message: "Ton engagement est impressionnant ! Tu démontres une forte volonté d'apprendre.",
1977
+ insights: [
1978
+ { icon: "🔥", text: "Motivation élevée" },
1979
+ { icon: "🎯", text: "Objectifs bien définis" },
1980
+ { icon: "📚", text: "Implication active" }
1981
+ ]
1982
+ },
1983
+ "Étudiant actif mais inefficace": {
1984
+ title: "Actif mais Peu Efficace",
1985
+ message: "Tu es très actif mais ton taux d'erreur est élevé. Concentre-toi sur une compétence à la fois.",
1986
+ insights: [
1987
+ { icon: "⚡", text: "Activité élevée" },
1988
+ { icon: "⚠️", text: "Erreurs fréquentes" },
1989
+ { icon: "🎯", text: "Focus nécessaire" }
1990
+ ]
1991
+ },
1992
+ "Étudiant orienté vers le succès": {
1993
+ title: "Orientation Réussite",
1994
+ message: "Tu vises l'excellence avec détermination. Ta rigueur est exemplaire.",
1995
+ insights: [
1996
+ { icon: "⭐", text: "Excellence visée" },
1997
+ { icon: "🎯", text: "Objectifs ambitieux" },
1998
+ { icon: "📈", text: "Performance supérieure" }
1999
+ ]
2000
+ },
2001
+ "Étudiant motivé": {
2002
+ title: "Nouvellement Motivé",
2003
+ message: "Ta motivation est un excellent point de départ ! Progresse étape par étape.",
2004
+ insights: [
2005
+ { icon: "🌟", text: "Motivation récente" },
2006
+ { icon: "🧱", text: "Construction des bases" },
2007
+ { icon: "📖", text: "Curiosité ouverte" }
2008
+ ]
2009
+ },
2010
+ "Étudiant surmotivé": {
2011
+ title: "Surmotivé - Attention",
2012
+ message: "Ton niveau d'investissement est exceptionnel, attention au risque de surmenage.",
2013
+ insights: [
2014
+ { icon: "⚡", text: "Investissement maximal" },
2015
+ { icon: "⚠️", text: "Risque de burnout" },
2016
+ { icon: "⚖️", text: "Équilibre nécessaire" }
2017
+ ]
2018
+ },
2019
+ "Étudiant stratégique": {
2020
+ title: "Stratégique et Efficient",
2021
+ message: "Tu abordes l'apprentissage avec intelligence et planification.",
2022
+ insights: [
2023
+ { icon: "🧠", text: "Approche réfléchie" },
2024
+ { icon: "🎯", text: "Optimisation efforts" },
2025
+ { icon: "📊", text: "Analyse des retours" }
2026
+ ]
2027
+ }
2028
+ };
2029
+
2030
+ // Récupérer le message pour le profil ou utiliser un message par défaut
2031
+ const profileMessage = profileMessages[scenario.title] || {
2032
+ title: "Profil d'Apprentissage",
2033
+ message: "Analyse de votre profil d'apprentissage en cours...",
2034
+ insights: [
2035
+ { icon: "📊", text: "Évaluation indicateurs" },
2036
+ { icon: "🎯", text: "Forces et améliorations" },
2037
+ { icon: "🚀", text: "Recommandations" }
2038
+ ]
2039
+ };
2040
+
2041
+ // Mettre à jour l'interface
2042
+ radarBotContent.innerHTML = `<strong>${profileMessage.title}</strong><br>${profileMessage.message}`;
2043
+
2044
+ // Mettre à jour les insights
2045
+ radarBotInsights.innerHTML = '';
2046
+ profileMessage.insights.forEach(insight => {
2047
+ const insightElement = document.createElement('div');
2048
+ insightElement.className = 'compact-radar-insight-item';
2049
+ insightElement.innerHTML = `
2050
+ <div class="radar-insight-icon">${insight.icon}</div>
2051
+ <div class="radar-insight-text">${insight.text}</div>
2052
+ `;
2053
+ radarBotInsights.appendChild(insightElement);
2054
+ });
2055
+ }
2056
+
2057
+ // Dessiner la heatmap enrichie compacte
2058
+ function drawCompactEnrichedHeatmap(scenario) {
2059
+ const canvas = document.getElementById("heatmap");
2060
+ if (!canvas) return;
2061
+
2062
+ const ctx = canvas.getContext("2d");
2063
+ const cellSize = 15;
2064
+ const padding = 1;
2065
+ const days = ["L", "M", "M", "J", "V", "S", "D"];
2066
+ const weeks = 4;
2067
+ const totalDays = weeks * 7;
2068
+
2069
+ // Effacer le canvas
2070
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
2071
+
2072
+ // Titre enrichi
2073
+ const scenarioTitles = {
2074
+ 1: {
2075
+ title: "Engagé mais désorganisé",
2076
+ emoji: "😅",
2077
+ pattern: "Effort concentré avant échéances"
2078
+ },
2079
+ 2: {
2080
+ title: "Actif mais peu efficace",
2081
+ emoji: "😰",
2082
+ pattern: "Démarrage lent, accélération tardive"
2083
+ },
2084
+ 3: {
2085
+ title: "Autonome et stratégique",
2086
+ emoji: "😊",
2087
+ pattern: "Travail régulier et équilibré"
2088
+ }
2089
+ };
2090
+
2091
+ const scenarioInfo = scenarioTitles[scenario.id] || {
2092
+ title: "Votre activité",
2093
+ emoji: "📊",
2094
+ pattern: "Schéma à analyser"
2095
+ };
2096
+
2097
+ ctx.font = "bold 14px Arial";
2098
+ ctx.fillStyle = "#1976D2";
2099
+ ctx.textAlign = "center";
2100
+ ctx.fillText(`${scenarioInfo.emoji} ${scenarioInfo.title}`, canvas.width / 2, 20);
2101
+
2102
+ ctx.font = "12px Arial";
2103
+ ctx.fillStyle = "#666";
2104
+ ctx.fillText(`${scenarioInfo.pattern}`, canvas.width / 2, 40);
2105
+
2106
+ // Générer les données d'activité selon le scénario
2107
+ const activityData = generateCompactPersistenceData(scenario.id, totalDays);
2108
+
2109
+ // Dessiner la heatmap
2110
+ const colors = ["#EBEDF0", "#C6E48B", "#7BC96F", "#239A3B", "#196127"];
2111
+
2112
+ for (let day = 0; day < totalDays; day++) {
2113
+ const week = Math.floor(day / 7);
2114
+ const weekday = day % 7;
2115
+
2116
+ const x = 30 + week * (cellSize * 7 + padding * 7) + weekday * (cellSize + padding);
2117
+ const y = 60 + weekday * (cellSize + padding);
2118
+
2119
+ const intensity = activityData[day];
2120
+
2121
+ // Dessiner la cellule
2122
+ ctx.fillStyle = colors[intensity];
2123
+ ctx.fillRect(x, y, cellSize, cellSize);
2124
+
2125
+ // Bordure avec indication des échéances (vendredi = jour important)
2126
+ if (weekday === 4) { // Vendredi
2127
+ ctx.strokeStyle = "#FF6B6B";
2128
+ ctx.lineWidth = 1.5;
2129
+ } else {
2130
+ ctx.strokeStyle = intensity > 0 ? "#239A3B" : "#eee";
2131
+ ctx.lineWidth = 0.5;
2132
+ }
2133
+ ctx.strokeRect(x, y, cellSize, cellSize);
2134
+ }
2135
+
2136
+ // Analyser et afficher les métriques de persévérance compactes
2137
+ analyzeCompactPersistenceMetrics(activityData, scenario.id);
2138
+ }
2139
+
2140
+ // Mettre à jour la persévérance spécifique au profil
2141
+ function updatePerseveranceProfile(scenarioTitle) {
2142
+ const profile = perseveranceProfiles[scenarioTitle];
2143
+
2144
+ if (!profile) {
2145
+ console.warn(`Aucun profil de persévérance trouvé pour: ${scenarioTitle}`);
2146
+
2147
+ // Valeurs par défaut
2148
+ const regularityText = document.getElementById("compact-regularityText");
2149
+ if (regularityText) {
2150
+ regularityText.innerHTML = `
2151
+ <div style="font-size: 12px; color: #555; line-height: 1.4;">
2152
+ Analyse de persévérance non disponible pour ce profil.
2153
+ </div>
2154
+ `;
2155
+ }
2156
+ return;
2157
+ }
2158
+
2159
+ // Mettre à jour l'interface
2160
+ const regularityText = document.getElementById("compact-regularityText");
2161
+ if (regularityText) {
2162
+ regularityText.innerHTML = `
2163
+ <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 5px;">
2164
+ <div style="width: 12px; height: 12px; border-radius: 50%; background: ${profile.color};"></div>
2165
+ <strong style="color: ${profile.color};">${profile.level}</strong>
2166
+ </div>
2167
+ <div style="font-size: 12px; color: #555; line-height: 1.4;">
2168
+ ${profile.interpretation}
2169
+ </div>
2170
+ `;
2171
+ }
2172
+
2173
+ // Mettre à jour le score de régularité dans les indicateurs
2174
+ const regularityScore = document.getElementById("compact-regularityScore");
2175
+ if (regularityScore) {
2176
+ // Convertir le niveau textuel en pourcentage approximatif
2177
+ let scorePercent;
2178
+ if (profile.level.includes("Très élevée")) scorePercent = "90%";
2179
+ else if (profile.level.includes("Élevée")) scorePercent = "75%";
2180
+ else if (profile.level.includes("Moyenne")) scorePercent = "55%";
2181
+ else if (profile.level.includes("Faible")) scorePercent = "35%";
2182
+ else if (profile.level.includes("Tr��s faible")) scorePercent = "20%";
2183
+ else scorePercent = "50%";
2184
+
2185
+ regularityScore.textContent = scorePercent;
2186
+ regularityScore.style.color = profile.color;
2187
+ }
2188
+ }
2189
+
2190
+ // Générer des données de persévérance compactes
2191
+ function generateCompactPersistenceData(scenarioId, totalDays) {
2192
+ const data = new Array(totalDays).fill(0);
2193
+
2194
+ switch(scenarioId) {
2195
+ case 1: // Scénario désorganisé - Effort concentré avant échéances
2196
+ for (let i = 0; i < totalDays; i++) {
2197
+ const weekday = i % 7;
2198
+ if (weekday === 3 || weekday === 4) { // Jeudi et vendredi
2199
+ data[i] = Math.floor(Math.random() * 2) + 3; // 3-4
2200
+ } else if (weekday === 5 || weekday === 6) { // Weekend
2201
+ data[i] = Math.floor(Math.random() * 2); // 0-1
2202
+ } else {
2203
+ data[i] = Math.floor(Math.random() * 2) + 1; // 1-2
2204
+ }
2205
+ }
2206
+ break;
2207
+
2208
+ case 2: // Scénario peu efficace - Démarrage lent, accélération tardive
2209
+ for (let i = 0; i < totalDays; i++) {
2210
+ const progress = i / totalDays;
2211
+ if (progress < 0.3) {
2212
+ data[i] = Math.floor(Math.random() * 2); // 0-1
2213
+ } else if (progress > 0.7) {
2214
+ data[i] = Math.floor(Math.random() * 2) + 3; // 3-4
2215
+ } else {
2216
+ data[i] = Math.floor(Math.random() * 2) + 1; // 1-2
2217
+ }
2218
+ }
2219
+ break;
2220
+
2221
+ case 3: // Scénario stratégique - Travail régulier
2222
+ for (let i = 0; i < totalDays; i++) {
2223
+ const weekday = i % 7;
2224
+ if (weekday === 5 || weekday === 6) { // Weekend léger
2225
+ data[i] = Math.floor(Math.random() * 2); // 0-1
2226
+ } else {
2227
+ data[i] = Math.floor(Math.random() * 2) + 2; // 2-3
2228
+ }
2229
+ }
2230
+ break;
2231
+
2232
+ default:
2233
+ for (let i = 0; i < totalDays; i++) {
2234
+ data[i] = Math.floor(Math.random() * 5); // 0-4 aléatoire
2235
+ }
2236
+ }
2237
+
2238
+ return data;
2239
+ }
2240
+
2241
+ // Analyser les métriques de persévérance compactes
2242
+ function analyzeCompactPersistenceMetrics(activityData, scenarioId) {
2243
+ const totalDays = activityData.length;
2244
+
2245
+ // 1. Calculer la régularité (écart-type)
2246
+ const avgActivity = activityData.reduce((a, b) => a + b, 0) / totalDays;
2247
+ const variance = activityData.reduce((a, b) => a + Math.pow(b - avgActivity, 2), 0) / totalDays;
2248
+ const stdDev = Math.sqrt(variance);
2249
+ const regularity = Math.max(0, 100 - stdDev * 25);
2250
+
2251
+ // 2. Identifier le schéma d'effort
2252
+ let pattern = "Régulier";
2253
+ let patternDescription = "Effort équilibré toute la semaine";
2254
+
2255
+ // Analyser la distribution
2256
+ const weeklyPatterns = [];
2257
+ for (let w = 0; w < 4; w++) {
2258
+ const weekData = activityData.slice(w * 7, Math.min((w + 1) * 7, totalDays));
2259
+ if (weekData.length < 5) continue;
2260
+
2261
+ const weekAvg = weekData.reduce((a, b) => a + b, 0) / weekData.length;
2262
+
2263
+ if (weekData[4] > weekAvg * 1.5 && weekData[3] > weekAvg * 1.3) {
2264
+ pattern = "Effort concentré";
2265
+ patternDescription = "Pic d'activité jeudi/vendredi";
2266
+ } else if (weekData[0] < weekAvg * 0.7 && weekData[4] > weekAvg * 1.2) {
2267
+ pattern = "Accélération progressive";
2268
+ patternDescription = "Démarrage lent, fin forte";
2269
+ }
2270
+ }
2271
+
2272
+ // 3. Calculer la gestion des échéances
2273
+ const deadlineDays = activityData.filter((_, index) => index % 7 === 3 || index % 7 === 4);
2274
+ const nonDeadlineDays = activityData.filter((_, index) => index % 7 !== 3 && index % 7 !== 4);
2275
+
2276
+ let deadlineScore = 50;
2277
+ if (deadlineDays.length > 0 && nonDeadlineDays.length > 0) {
2278
+ const deadlineAvg = deadlineDays.reduce((a, b) => a + b, 0) / deadlineDays.length;
2279
+ const nonDeadlineAvg = nonDeadlineDays.reduce((a, b) => a + b, 0) / nonDeadlineDays.length;
2280
+ deadlineScore = Math.min(100, Math.max(0, (deadlineAvg / 4) * 100));
2281
+ }
2282
+
2283
+ // Mettre à jour l'interface compacte
2284
+ const regularityScoreElem = document.getElementById("compact-regularityScore");
2285
+ const effortPatternElem = document.getElementById("compact-effortPattern");
2286
+ const deadlineScoreElem = document.getElementById("compact-deadlineScore");
2287
+ const patternTextElem = document.getElementById("compact-patternText");
2288
+
2289
+ if (regularityScoreElem) regularityScoreElem.textContent = Math.round(regularity) + "%";
2290
+ if (effortPatternElem) effortPatternElem.textContent = pattern;
2291
+ if (deadlineScoreElem) deadlineScoreElem.textContent = Math.round(deadlineScore) + "%";
2292
+ if (patternTextElem) patternTextElem.textContent = patternDescription;
2293
+ }
2294
+
2295
+ // ================= RADAR =================
2296
+ function drawRadar() {
2297
+ const canvas = document.getElementById("radar");
2298
+ if (!canvas) {
2299
+ console.error("Canvas radar non trouvé!");
2300
+ return;
2301
+ }
2302
+
2303
+ const ctx = canvas.getContext("2d");
2304
+ const cx = canvas.width / 2;
2305
+ const cy = canvas.height / 2;
2306
+ const radius = Math.min(cx, cy) - 40; // Ajuster selon la taille
2307
+ const n = radarMetrics.length;
2308
+
2309
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
2310
+
2311
+ // Dessiner le radar
2312
+ for (let i = 1; i <= 5; i++) {
2313
+ ctx.beginPath();
2314
+ ctx.arc(cx, cy, (radius / 5) * i, 0, 2 * Math.PI);
2315
+ ctx.strokeStyle = "#e0e0e0";
2316
+ ctx.stroke();
2317
+ }
2318
+
2319
+ // Dessiner les axes
2320
+ radarMetrics.forEach((m, i) => {
2321
+ const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2322
+
2323
+ ctx.beginPath();
2324
+ ctx.moveTo(cx, cy);
2325
+ ctx.lineTo(cx + radius * Math.cos(angle), cy + radius * Math.sin(angle));
2326
+ ctx.strokeStyle = "#b0bec5";
2327
+ ctx.stroke();
2328
+
2329
+ // Labels
2330
+ const tx = cx + (radius + 25) * Math.cos(angle);
2331
+ const ty = cy + (radius + 25) * Math.sin(angle);
2332
+
2333
+ ctx.font = "10px Arial";
2334
+ ctx.fillStyle = "#000";
2335
+ ctx.textAlign = angle > Math.PI / 2 || angle < -Math.PI / 2 ? "right" : "left";
2336
+ ctx.textBaseline = "middle";
2337
+
2338
+ // Raccourcir les labels longs
2339
+ let label = m.label;
2340
+ if (label.length > 15) {
2341
+ label = label.substring(0, 12) + "...";
2342
+ }
2343
+ ctx.fillText(label, tx, ty);
2344
+ });
2345
+
2346
+ // Dessiner le polygone
2347
+ ctx.beginPath();
2348
+ radarMetrics.forEach((m, i) => {
2349
+ const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2350
+ const r = radius * (m.value / 100);
2351
+ const x = cx + r * Math.cos(angle);
2352
+ const y = cy + r * Math.sin(angle);
2353
+ i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
2354
+ });
2355
+ ctx.closePath();
2356
+
2357
+ ctx.fillStyle = "rgba(25,118,210,0.25)";
2358
+ ctx.fill();
2359
+ ctx.strokeStyle = "#1976D2";
2360
+ ctx.lineWidth = 2;
2361
+ ctx.stroke();
2362
+
2363
+ // Dessiner les points
2364
+ radarMetrics.forEach((m, i) => {
2365
+ const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2366
+ const r = radius * (m.value / 100);
2367
+ const x = cx + r * Math.cos(angle);
2368
+ const y = cy + r * Math.sin(angle);
2369
+
2370
+ ctx.beginPath();
2371
+ ctx.arc(x, y, 4, 0, 2 * Math.PI);
2372
+ ctx.fillStyle = "#1976D2";
2373
+ ctx.fill();
2374
+ });
2375
+ }
2376
+
2377
+ // ================= NAVIGATION =================
2378
+ function updateNavButtons() {
2379
+ if (!scenarios || scenarios.length === 0) {
2380
+ document.getElementById("prevScenario").disabled = true;
2381
+ document.getElementById("nextScenario").disabled = true;
2382
+ return;
2383
+ }
2384
+
2385
+ document.getElementById("prevScenario").disabled = currentScenarioIndex === 0;
2386
+ document.getElementById("nextScenario").disabled = currentScenarioIndex === scenarios.length - 1;
2387
+ }
2388
+
2389
+ // ================= BOUTON LECTURE CROISÉE =================
2390
+ function navigateToCrossReading() {
2391
+ console.log('Navigation vers la page de lecture croisée...');
2392
+
2393
+ // Animation de transition
2394
+ const reflectionDiv = document.getElementById('reflection');
2395
+ if (reflectionDiv) {
2396
+ reflectionDiv.style.opacity = '0.7';
2397
+ reflectionDiv.style.transition = 'opacity 0.3s ease';
2398
+ }
2399
+
2400
+ // Redirection
2401
+ setTimeout(() => {
2402
+ // Essayer différents chemins pour la page de lecture croisée
2403
+ const possiblePaths = [
2404
+ 'cross_reading/cross_readers.html',
2405
+ './cross_reading/cross_readers.html',
2406
+ '../cross_reading/cross_readers.html',
2407
+ 'cross_readers.html',
2408
+ './cross_readers.html'
2409
+ ];
2410
+
2411
+ // Vérifier si le fichier existe avant la redirection
2412
+ function tryRedirect(index) {
2413
+ if (index >= possiblePaths.length) {
2414
+ console.error('Page de lecture croisée introuvable');
2415
+ showNotification('Erreur', 'Page de lecture croisée introuvable', 'error');
2416
+
2417
+ // Restaurer l'opacité
2418
+ if (reflectionDiv) {
2419
+ reflectionDiv.style.opacity = '1';
2420
+ }
2421
+ return;
2422
+ }
2423
+
2424
+ const path = possiblePaths[index];
2425
+
2426
+ // Vérifier si le fichier existe (approximation)
2427
+ fetch(path, { method: 'HEAD' })
2428
+ .then(response => {
2429
+ if (response.ok) {
2430
+ window.location.href = path;
2431
+ } else {
2432
+ tryRedirect(index + 1);
2433
+ }
2434
+ })
2435
+ .catch(() => {
2436
+ tryRedirect(index + 1);
2437
+ });
2438
+ }
2439
+
2440
+ tryRedirect(0);
2441
+ }, 300);
2442
+ }
2443
+
2444
+ // ================= MÉTRIQUES DE CONFIANCE =================
2445
+ function initTrustStars(){
2446
+ console.log("Initialisation des étoiles...");
2447
+
2448
+ // Réinitialiser toutes les métriques
2449
+ for (const key in trustMetrics) {
2450
+ trustMetrics[key] = 0;
2451
+ }
2452
+
2453
+ let starsCreated = 0;
2454
+
2455
+ document.querySelectorAll(".stars").forEach(div => {
2456
+ const metric = div.dataset.metric;
2457
+ console.log(`Création des étoiles pour: ${metric}`);
2458
+
2459
+ // Vérifier que la métrique existe
2460
+ if (!trustMetrics.hasOwnProperty(metric)) {
2461
+ console.error(`Métrique inconnue: ${metric}`);
2462
+ return;
2463
+ }
2464
+
2465
+ // Vider le conteneur
2466
+ div.innerHTML = '';
2467
+
2468
+ // Créer 5 étoiles
2469
+ for (let i = 1; i <= 5; i++) {
2470
+ const star = document.createElement("span");
2471
+ star.textContent = "★";
2472
+ star.classList.add("inactive");
2473
+ star.style.cursor = "pointer";
2474
+ star.title = `${i} étoile${i > 1 ? 's' : ''}`;
2475
+
2476
+ // Stocker la valeur dans un attribut data
2477
+ star.dataset.value = i;
2478
+ star.dataset.metric = metric;
2479
+
2480
+ star.onclick = function() {
2481
+ const value = parseInt(this.dataset.value);
2482
+ const metric = this.dataset.metric;
2483
+ console.log(`Clic sur ${metric}: ${value} étoiles`);
2484
+
2485
+ // Mettre à jour la valeur de la métrique
2486
+ trustMetrics[metric] = value;
2487
+
2488
+ // Mettre à jour l'affichage des étoiles dans ce groupe
2489
+ const allStarsInGroup = this.parentElement.children;
2490
+ for (let j = 0; j < allStarsInGroup.length; j++) {
2491
+ const starElem = allStarsInGroup[j];
2492
+ const starValue = parseInt(starElem.dataset.value);
2493
+
2494
+ if (starValue <= value) {
2495
+ starElem.classList.remove("inactive");
2496
+ starElem.classList.add("active");
2497
+ } else {
2498
+ starElem.classList.add("inactive");
2499
+ starElem.classList.remove("active");
2500
+ }
2501
+ }
2502
+
2503
+ // Mettre à jour la barre de progression
2504
+ updateTrustBar();
2505
+ };
2506
+
2507
+ div.appendChild(star);
2508
+ starsCreated++;
2509
+ }
2510
+ });
2511
+
2512
+ console.log(`${starsCreated} étoiles créées pour ${Object.keys(trustMetrics).length} métriques`);
2513
+ console.log("Métriques initialisées:", trustMetrics);
2514
+ }
2515
+
2516
+ function updateTrustBar(){
2517
+ console.log("=== MISE À JOUR BARRE DE CONFIANCE ===");
2518
+
2519
+ let scoreTotal = 0;
2520
+ let scoreMaxPossible = 0;
2521
+ let details = [];
2522
+
2523
+ // Calcul détaillé
2524
+ for (const metric in trustMetrics) {
2525
+ const valeur = trustMetrics[metric];
2526
+ const poids = trustWeights[metric];
2527
+ const contribution = valeur * poids;
2528
+ const maxContribution = 5 * poids;
2529
+
2530
+ scoreTotal += contribution;
2531
+ scoreMaxPossible += maxContribution;
2532
+
2533
+ details.push({
2534
+ métrique: metric,
2535
+ valeur: valeur,
2536
+ poids: poids,
2537
+ contribution: contribution.toFixed(2),
2538
+ max: maxContribution.toFixed(2)
2539
+ });
2540
+ }
2541
+
2542
+ console.log("Détails du calcul:");
2543
+ details.forEach(d => {
2544
+ console.log(`${d.métrique}: ${d.valeur}/5 × ${d.poids} = ${d.contribution} / ${d.max}`);
2545
+ });
2546
+
2547
+ console.log(`Total: ${scoreTotal.toFixed(2)} / ${scoreMaxPossible.toFixed(2)}`);
2548
+
2549
+ // Calcul du pourcentage
2550
+ let pourcentage = 0;
2551
+ if (scoreMaxPossible > 0) {
2552
+ pourcentage = Math.round((scoreTotal / scoreMaxPossible) * 100);
2553
+ }
2554
+
2555
+ console.log(`Pourcentage calculé: ${pourcentage}%`);
2556
+
2557
+ // Mettre à jour la barre de progression
2558
+ const barre = document.getElementById("trustBar");
2559
+ if (barre) {
2560
+ barre.style.width = pourcentage + "%";
2561
+ barre.textContent = pourcentage + "%";
2562
+
2563
+ // Changer la couleur selon le niveau
2564
+ if (pourcentage < 40) {
2565
+ barre.style.background = "#E53935"; // Rouge - Faible
2566
+ barre.title = `Faible confiance (${pourcentage}%)`;
2567
+ } else if (pourcentage < 70) {
2568
+ barre.style.background = "#FB8C00"; // Orange - Moyen
2569
+ barre.title = `Confiance moyenne (${pourcentage}%)`;
2570
+ } else {
2571
+ barre.style.background = "#43A047"; // Vert - Fort
2572
+ barre.title = `Forte confiance (${pourcentage}%)`;
2573
+ }
2574
+
2575
+ console.log(`Barre mise à jour: ${pourcentage}% (width: ${pourcentage}%)`);
2576
+ } else {
2577
+ console.error("Élément #trustBar non trouvé!");
2578
+ }
2579
+
2580
+ // Mettre à jour la statistique de confiance moyenne
2581
+ const avgTrustElem = document.getElementById("avgTrustScore");
2582
+ if (avgTrustElem) {
2583
+ avgTrustElem.textContent = pourcentage + "%";
2584
+ console.log(`Statistique moyenne mise à jour: ${pourcentage}%`);
2585
+ }
2586
+
2587
+ // Afficher un résumé dans la console
2588
+ console.log("=== RÉSUMÉ FINAL ===");
2589
+ console.log(`Indice global de confiance: ${pourcentage}%`);
2590
+ console.log("Valeurs des métriques:", JSON.stringify(trustMetrics, null, 2));
2591
+ console.log("====================");
2592
+
2593
+ return pourcentage;
2594
+ }
2595
+
2596
+ function initTrustSave(){
2597
+ const saveBtn = document.getElementById("saveTrustBtn");
2598
+ if (!saveBtn) {
2599
+ console.error("Bouton de sauvegarde non trouvé!");
2600
+ return;
2601
+ }
2602
+
2603
+ saveBtn.onclick = () => {
2604
+ console.log("=== DÉBUT SAUVEGARDE ===");
2605
+
2606
+ // Récupérer les informations GDPR
2607
+ const gdprAccept = document.getElementById('gdprAccept').checked;
2608
+ const gdprDecline = document.getElementById('gdprDecline').checked;
2609
+
2610
+ // Récupérer les informations conditionnelles
2611
+ let evaluatorName = "";
2612
+ let evaluatorRole = "";
2613
+ let expertiseLevel = "";
2614
+ let messageMastery = "";
2615
+
2616
+ if (gdprAccept) {
2617
+ evaluatorName = document.getElementById("evaluatorName").value.trim();
2618
+ evaluatorRole = document.getElementById("evaluatorRole").value;
2619
+ expertiseLevel = document.getElementById("expertiseLevel").value;
2620
+ messageMastery = document.getElementById("messageMastery").value;
2621
+ }
2622
+
2623
+ const comment = document.getElementById("trustComment").value;
2624
+ const msgDiv = document.getElementById("saveTrustMsg");
2625
+
2626
+ // Validation : consentement GDPR obligatoire
2627
+ if (!gdprAccept && !gdprDecline) {
2628
+ const message = "❌ Veuillez sélectionner une option de consentement RGPD.";
2629
+ console.error(message);
2630
+
2631
+ if (msgDiv) {
2632
+ msgDiv.textContent = message;
2633
+ msgDiv.style.background = "#FFEBEE";
2634
+ msgDiv.style.color = "#C62828";
2635
+ }
2636
+ return;
2637
+ }
2638
+
2639
+ // Validation : si GDPR accepté, vérifier les champs obligatoires
2640
+ if (gdprAccept) {
2641
+ if (!evaluatorName) {
2642
+ const message = "❌ Veuillez saisir votre nom et prénom.";
2643
+ console.error(message);
2644
+
2645
+ if (msgDiv) {
2646
+ msgDiv.textContent = message;
2647
+ msgDiv.style.background = "#FFEBEE";
2648
+ msgDiv.style.color = "#C62828";
2649
+ }
2650
+
2651
+ const nameField = document.getElementById("evaluatorName");
2652
+ nameField.style.borderColor = "#E53935";
2653
+ nameField.style.boxShadow = "0 0 0 3px rgba(229, 57, 53, 0.1)";
2654
+ nameField.focus();
2655
+
2656
+ setTimeout(() => {
2657
+ nameField.style.borderColor = "#e0e0e0";
2658
+ nameField.style.boxShadow = "none";
2659
+ }, 3000);
2660
+
2661
+ return;
2662
+ }
2663
+
2664
+ if (!evaluatorRole) {
2665
+ const message = "❌ Veuillez sélectionner votre rôle.";
2666
+ console.error(message);
2667
+
2668
+ if (msgDiv) {
2669
+ msgDiv.textContent = message;
2670
+ msgDiv.style.background = "#FFEBEE";
2671
+ msgDiv.style.color = "#C62828";
2672
+ }
2673
+ return;
2674
+ }
2675
+
2676
+ if (!expertiseLevel) {
2677
+ const message = "❌ Veuillez sélectionner votre niveau d'expertise en réflexivité.";
2678
+ console.error(message);
2679
+
2680
+ if (msgDiv) {
2681
+ msgDiv.textContent = message;
2682
+ msgDiv.style.background = "#FFEBEE";
2683
+ msgDiv.style.color = "#C62828";
2684
+ }
2685
+ return;
2686
+ }
2687
+
2688
+ if (!messageMastery) {
2689
+ const message = "❌ Veuillez sélectionner votre niveau de maîtrise des messages réflexifs.";
2690
+ console.error(message);
2691
+
2692
+ if (msgDiv) {
2693
+ msgDiv.textContent = message;
2694
+ msgDiv.style.background = "#FFEBEE";
2695
+ msgDiv.style.color = "#C62828";
2696
+ }
2697
+ return;
2698
+ }
2699
+ }
2700
+
2701
+ // Vérifier si au moins une évaluation
2702
+ let hasEvaluation = false;
2703
+ for (const metric in trustMetrics) {
2704
+ if (trustMetrics[metric] > 0) {
2705
+ hasEvaluation = true;
2706
+ break;
2707
+ }
2708
+ }
2709
+
2710
+ if (!hasEvaluation) {
2711
+ const message = "⚠️ Veuillez évaluer au moins une métrique avant de sauvegarder.";
2712
+ console.warn(message);
2713
+
2714
+ if (msgDiv) {
2715
+ msgDiv.textContent = message;
2716
+ msgDiv.style.background = "#FFF3E0";
2717
+ msgDiv.style.color = "#EF6C00";
2718
+ }
2719
+ return;
2720
+ }
2721
+
2722
+ // Calculer l'indice de confiance
2723
+ const trustScore = updateTrustBar(); // Cette fonction retourne le pourcentage
2724
+
2725
+ console.log(`Indice calculé pour sauvegarde: ${trustScore}%`);
2726
+
2727
+ // Préparer les données
2728
+ const data = {
2729
+ scenario_id: scenarios[currentScenarioIndex].id,
2730
+ scenario_title: scenarios[currentScenarioIndex].title,
2731
+ trust_metrics: {...trustMetrics},
2732
+ trust_score: trustScore,
2733
+ gdpr_consent: gdprAccept ? "accept" : "decline",
2734
+ evaluator_name: gdprAccept ? evaluatorName : null,
2735
+ evaluator_role: gdprAccept ? evaluatorRole : null,
2736
+ expertise_level: gdprAccept ? expertiseLevel : null,
2737
+ message_mastery: gdprAccept ? messageMastery : null,
2738
+ comment: comment || null,
2739
+ timestamp: new Date().toISOString(),
2740
+ trust_weights: {...trustWeights}
2741
+ };
2742
+
2743
+ console.log("Données à envoyer:", JSON.stringify(data, null, 2));
2744
+
2745
+ // Envoyer au serveur (simulation)
2746
+ simulateServerSave(data, msgDiv, trustScore, evaluatorName, gdprAccept);
2747
+ };
2748
+
2749
+ console.log("✅ Bouton de sauvegarde initialisé");
2750
+ }
2751
+
2752
+ // Simulation de sauvegarde serveur
2753
+ function simulateServerSave(data, msgDiv, trustScore, evaluatorName, gdprAccept) {
2754
+ // Simuler un délai réseau
2755
+ setTimeout(() => {
2756
+ console.log("✅ Simulation de sauvegarde réussie:", data);
2757
+
2758
+ if (msgDiv) {
2759
+ const nameDisplay = gdprAccept ? evaluatorName : "Évaluateur anonyme";
2760
+ msgDiv.innerHTML = `
2761
+ <div style="display: flex; align-items: center; gap: 10px;">
2762
+ <div style="font-size: 24px;">✅</div>
2763
+ <div>
2764
+ <strong>Évaluation sauvegardée avec succès !</strong><br>
2765
+ <small>Merci ${nameDisplay} pour votre contribution.</small><br>
2766
+ <small><em>Indice global: ${trustScore}%</em></small>
2767
+ </div>
2768
+ </div>
2769
+ `;
2770
+ msgDiv.style.background = "#E8F5E9";
2771
+ msgDiv.style.color = "#2E7D32";
2772
+ msgDiv.style.padding = "15px";
2773
+ }
2774
+
2775
+ // Réinitialiser après succès (optionnel)
2776
+ setTimeout(() => {
2777
+ if (msgDiv) {
2778
+ msgDiv.innerHTML = "";
2779
+ msgDiv.style.background = "";
2780
+ msgDiv.style.color = "";
2781
+ msgDiv.style.padding = "";
2782
+ }
2783
+ }, 5000);
2784
+ }, 1000);
2785
+ }
2786
+
2787
+ // Fonction pour réinitialiser l'évaluation
2788
+ function resetTrustEvaluation() {
2789
+ console.log("Réinitialisation de l'évaluation...");
2790
+
2791
+ // Réinitialiser les métriques
2792
+ for (const key in trustMetrics) {
2793
+ trustMetrics[key] = 0;
2794
+ }
2795
+
2796
+ // Réinitialiser les étoiles
2797
+ document.querySelectorAll(".stars").forEach(div => {
2798
+ Array.from(div.children).forEach(star => {
2799
+ star.classList.add("inactive");
2800
+ star.classList.remove("active");
2801
+ });
2802
+ });
2803
+
2804
+ // Réinitialiser la barre
2805
+ updateTrustBar();
2806
+
2807
+ // Vider le commentaire
2808
+ const commentField = document.getElementById("trustComment");
2809
+ if (commentField) {
2810
+ commentField.value = "";
2811
+ }
2812
+
2813
+ console.log("Évaluation réinitialisée");
2814
+ }
2815
+
2816
+ // ================= FONCTIONS UTILITAIRES =================
2817
+
2818
+ // Mettre à jour les statistiques
2819
+ function updateStats(scenario) {
2820
+ if (!scenario) return;
2821
+
2822
+ const currentScenarioNum = document.getElementById("currentScenarioNum");
2823
+ const riskLevelElem = document.getElementById("riskLevel");
2824
+ const avgActivityElem = document.getElementById("avgActivity");
2825
+
2826
+ if (currentScenarioNum) {
2827
+ currentScenarioNum.textContent = scenario.id || "-";
2828
+ }
2829
+
2830
+ // Niveau de risque
2831
+ if (riskLevelElem) {
2832
+ const risk = scenario.risk || 50;
2833
+ let riskLevel = "Moyen";
2834
+ let riskColor = "#FB8C00";
2835
+
2836
+ if (risk < 40) {
2837
+ riskLevel = "Faible";
2838
+ riskColor = "#43A047";
2839
+ } else if (risk > 70) {
2840
+ riskLevel = "Élevé";
2841
+ riskColor = "#E53935";
2842
+ }
2843
+
2844
+ riskLevelElem.textContent = riskLevel;
2845
+ riskLevelElem.style.color = riskColor;
2846
+ }
2847
+
2848
+ // Activité moyenne à partir des données radar
2849
+ if (avgActivityElem && scenario.radar && scenario.radar.length > 0) {
2850
+ const avgRadar = scenario.radar.reduce((sum, item) => sum + item.value, 0) / scenario.radar.length;
2851
+ avgActivityElem.textContent = Math.round(avgRadar) + "%";
2852
+ }
2853
+ }
2854
+
2855
+ // Fonction pour remplir un exemple d'évaluateur
2856
+ function fillSampleEvaluator() {
2857
+ // Sélectionner l'option GDPR "accept"
2858
+ document.getElementById('gdprAccept').checked = true;
2859
+ document.getElementById('gdprDecline').checked = false;
2860
+
2861
+ // Mettre à jour les champs
2862
+ initGDPR();
2863
+
2864
+ // Remplir les champs
2865
+ document.getElementById("evaluatorName").value = "Martin Sophie";
2866
+ document.getElementById("evaluatorRole").value = "enseignant";
2867
+ document.getElementById("expertiseLevel").value = "avance";
2868
+ document.getElementById("messageMastery").value = "intermediaire_msg";
2869
+
2870
+ showNotification("Exemple", "Champs d'évaluateur remplis avec un exemple", "info");
2871
+ }
2872
+
2873
+ // Fonction pour effacer les champs évaluateur
2874
+ function clearEvaluatorFields() {
2875
+ // Sélectionner l'option GDPR "decline" par défaut
2876
+ document.getElementById('gdprDecline').checked = true;
2877
+ document.getElementById('gdprAccept').checked = false;
2878
+
2879
+ // Mettre à jour les champs
2880
+ initGDPR();
2881
+
2882
+ showNotification("Champs effacés", "Les informations d'évaluateur ont été effacées", "info");
2883
+ }
2884
+
2885
+ // Fonction pour afficher une notification
2886
+ function showNotification(title, message, type = "info") {
2887
+ console.log(`[${type}] ${title}: ${message}`);
2888
+
2889
+ const msgDiv = document.getElementById("saveTrustMsg");
2890
+ if (msgDiv) {
2891
+ msgDiv.textContent = `${title}: ${message}`;
2892
+ msgDiv.style.background = type === "success" ? "#E8F5E9" :
2893
+ type === "error" ? "#FFEBEE" : "#E3F2FD";
2894
+ msgDiv.style.color = type === "success" ? "#2E7D32" :
2895
+ type === "error" ? "#C62828" : "#1565C0";
2896
+
2897
+ // Effacer après 5 secondes
2898
+ setTimeout(() => {
2899
+ msgDiv.textContent = "";
2900
+ msgDiv.style.background = "";
2901
+ msgDiv.style.color = "";
2902
+ }, 5000);
2903
+ }
2904
+ }
2905
+
2906
+ // Changer le mode d'analyse de persévérance
2907
+ function changePersistenceAnalysis() {
2908
+ const modeSelect = document.getElementById("persistenceMode");
2909
+ if (!modeSelect) return;
2910
+
2911
+ const mode = modeSelect.value;
2912
+ const currentScenario = scenarios[currentScenarioIndex];
2913
+
2914
+ if (!currentScenario) return;
2915
+
2916
+ // Redessiner la heatmap avec le mode sélectionné
2917
+ drawCompactEnrichedHeatmap(currentScenario);
2918
+
2919
+ // Ajouter une annotation selon le mode
2920
+ const canvas = document.getElementById("heatmap");
2921
+ if (!canvas) return;
2922
+
2923
+ const ctx = canvas.getContext("2d");
2924
+
2925
+ // Effacer l'annotation précédente
2926
+ ctx.clearRect(0, canvas.height - 30, canvas.width, 30);
2927
+
2928
+ ctx.font = "12px Arial";
2929
+ ctx.fillStyle = "#1976D2";
2930
+ ctx.textAlign = "center";
2931
+
2932
+ switch(mode) {
2933
+ case "regularity":
2934
+ ctx.fillText("📊 Analyse de la régularité", canvas.width / 2, canvas.height - 10);
2935
+ break;
2936
+ case "effortPattern":
2937
+ ctx.fillText("🔄 Schéma d'effort", canvas.width / 2, canvas.height - 10);
2938
+ break;
2939
+ case "deadline":
2940
+ ctx.fillText("⏰ Gestion des échéances", canvas.width / 2, canvas.height - 10);
2941
+ break;
2942
+ case "combined":
2943
+ ctx.fillText("🎯 Vue combinée", canvas.width / 2, canvas.height - 10);
2944
+ break;
2945
+ }
2946
+ }
2947
+
2948
+ // Exposer les fonctions globales
2949
+ window.changePersistenceAnalysis = changePersistenceAnalysis;
2950
+ window.updateStats = updateStats;
2951
+ window.showNotification = showNotification;
2952
+ window.fillSampleEvaluator = fillSampleEvaluator;
2953
+ window.clearEvaluatorFields = clearEvaluatorFields;
2954
+ window.loadScenario = loadScenario;
2955
+ </script>
2956
+
2957
+ </body>
2958
+ </html>