entrainement-mercredi-3/entrainement_certification_C3.html

2262 lines
79 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Entraînement certification C3</title>
<!-- Tabler Icons CSS & Google Fonts CDN -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@latest/tabler-icons.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&family=DM+Sans:ital,wght@0,400;0,500;0,700;1,400&display=swap');
:root {
/* Theme core colors (Indigo/Violet) */
--primary-hsl: 247, 80%, 62%;
--primary: hsl(var(--primary-hsl));
--primary-light: hsl(247, 85%, 96%);
--primary-dark: hsl(247, 80%, 35%);
/* Neutral colors - Clean & Premium Cool Grays */
--bg-primary: #f8fafc;
--bg-secondary: #ffffff;
--bg-tertiary: #f1f5f9;
--color-text-primary: #0f172a;
--color-text-secondary: #475569;
--color-text-tertiary: #94a3b8;
--color-border-primary: #f1f5f9;
--color-border-secondary: #e2e8f0;
--color-border-tertiary: #e2e8f0;
--border-radius-sm: 8px;
--border-radius-md: 14px;
--border-radius-lg: 18px;
--shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.05), 0 1px 2px 0 rgba(0, 0, 0, 0.03);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.04), 0 2px 4px -2px rgba(0, 0, 0, 0.04);
--shadow-lg: 0 12px 20px -3px rgba(0, 0, 0, 0.05), 0 4px 8px -4px rgba(0, 0, 0, 0.05);
/* Warning Accent (Amber) */
--color-a-bg: hsl(36, 85%, 96%);
--color-a-border: hsl(36, 80%, 88%);
--color-a-accent: hsl(36, 90%, 45%);
--color-a-dark: hsl(36, 95%, 22%);
/* Success Green (Emerald) */
--color-g-bg: hsl(162, 85%, 96%);
--color-g-border: hsl(162, 80%, 90%);
--color-g-accent: hsl(162, 75%, 34%);
--color-g-dark: hsl(162, 80%, 20%);
/* Danger Red */
--color-danger-bg: hsl(0, 85%, 96%);
--color-danger-border: hsl(0, 80%, 88%);
--color-danger-accent: hsl(0, 75%, 45%);
--color-danger-dark: hsl(0, 95%, 22%);
/* Typography */
--font-sans: 'DM Sans', sans-serif;
--font-heading: 'Nunito', sans-serif;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-primary);
color: var(--color-text-primary);
font-family: var(--font-sans);
transition: background-color 0.3s ease, color 0.3s ease;
min-height: 100vh;
display: flex;
flex-direction: column;
background-image:
radial-gradient(at 0% 0%, hsla(247, 80%, 62%, 0.04) 0px, transparent 50%),
radial-gradient(at 100% 0%, hsla(162, 75%, 34%, 0.01) 0px, transparent 50%),
radial-gradient(at 50% 100%, hsla(36, 90%, 45%, 0.02) 0px, transparent 50%);
background-attachment: fixed;
}
.w {
max-width: 960px;
width: 100%;
margin: 0 auto;
padding: 2.5rem 24px;
flex-grow: 1;
display: flex;
flex-direction: column;
}
/* Header */
.dh {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1.5rem;
border-bottom: 1px solid var(--color-border-secondary);
padding-bottom: 1.5rem;
margin-bottom: 2rem;
}
.dk {
font-size: 0.75rem;
font-weight: 800;
letter-spacing: .2em;
text-transform: uppercase;
color: var(--primary);
margin-bottom: 8px;
}
.dt {
font-size: 2rem;
font-weight: 900;
color: var(--color-text-primary);
line-height: 1.2;
letter-spacing: -0.02em;
font-family: var(--font-heading);
}
/* Identity input cards */
.identity-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-bottom: 2rem;
}
.id-field {
display: flex;
flex-direction: column;
gap: 6px;
background: var(--bg-secondary);
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
padding: 10px 14px;
box-shadow: var(--shadow-sm);
transition: all 0.25s ease;
}
.id-field:focus-within {
border-color: var(--primary);
box-shadow: 0 0 0 3px hsla(247, 80%, 62%, 0.12), var(--shadow-md);
}
.field-label {
font-size: 0.65rem;
font-weight: 800;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--color-text-secondary);
font-family: var(--font-heading);
}
.field-line {
border: none;
background: transparent;
font-family: var(--font-sans);
font-size: 0.9rem;
color: var(--color-text-primary);
padding: 2px 0 0 0;
width: 100%;
outline: none;
}
.field-line::placeholder {
color: var(--color-text-tertiary);
opacity: 0.7;
}
/* Badge */
.hbadge {
background: var(--primary-light);
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
padding: 8px 18px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
box-shadow: var(--shadow-md);
transition: all 0.3s ease;
flex-shrink: 0;
text-align: center;
}
.hbadge:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.hbt {
font-size: 0.65rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--primary-dark);
opacity: 0.8;
}
.hbv {
font-size: 1.2rem;
font-weight: 900;
color: var(--primary-dark);
line-height: 1.1;
font-family: var(--font-heading);
}
/* Score Strip */
.score-strip {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 12px;
margin-bottom: 2rem;
}
.sc {
background: var(--bg-secondary);
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
padding: 12px;
text-align: center;
box-shadow: var(--shadow-sm);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 4px;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.sc:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-md);
}
.sc-l {
font-size: 0.7rem;
font-weight: 800;
text-transform: uppercase;
letter-spacing: .05em;
color: var(--color-text-secondary);
}
.sc-v {
font-size: 1.5rem;
font-weight: 900;
color: var(--color-text-primary);
font-family: var(--font-heading);
}
.sc-v.ok {
color: var(--color-g-accent);
}
.sc-v.ko {
color: var(--color-danger-accent);
}
/* Notice Block */
.notice {
background: var(--primary-light);
border-left: 4px solid var(--primary);
border-radius: 0 var(--border-radius-md) var(--border-radius-md) 0;
padding: 14px 20px;
margin-bottom: 2rem;
display: flex;
gap: 12px;
align-items: flex-start;
box-shadow: var(--shadow-sm);
}
.notice i {
color: var(--primary);
font-size: 1.3rem;
flex-shrink: 0;
margin-top: 1px;
}
.notice p {
font-size: 0.9rem;
color: var(--color-text-secondary);
line-height: 1.6;
font-family: var(--font-sans);
}
.notice strong {
font-weight: 800;
color: var(--primary-dark);
}
/* Exercise Blocks */
.ex-block {
margin-bottom: 2.5rem;
background: var(--bg-secondary);
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-lg);
overflow: hidden;
box-shadow: var(--shadow-sm);
transition: box-shadow 0.25s ease;
}
.ex-block:hover {
box-shadow: var(--shadow-md);
}
.ex-head {
display: flex;
align-items: center;
gap: 16px;
padding: 16px 20px;
border-bottom: 1px solid var(--color-border-secondary);
}
.ex-icon {
width: 40px;
height: 40px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.3rem;
flex-shrink: 0;
box-shadow: var(--shadow-sm);
}
.ex-meta {
flex: 1;
display: flex;
flex-direction: column;
}
.ex-num {
font-size: 0.65rem;
font-weight: 800;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--color-text-tertiary);
margin-bottom: 2px;
}
.ex-title {
font-size: 1.15rem;
font-weight: 900;
font-family: var(--font-heading);
}
.ex-pts {
font-family: var(--font-heading);
font-size: 0.75rem;
font-weight: 800;
letter-spacing: .05em;
text-transform: uppercase;
border-radius: 8px;
padding: 6px 12px;
white-space: nowrap;
box-shadow: var(--shadow-sm);
}
/* Dynamic styling per exercise theme */
.ex-block:has(.ei1) .ex-head {
background: var(--primary-light);
border-bottom-color: var(--color-border-secondary);
}
.ex-block:has(.ei1) .ex-icon {
background: hsl(247, 85%, 90%);
color: var(--primary);
}
.ex-block:has(.ei1) .ex-title {
color: var(--primary-dark);
}
.ex-block:has(.ei1) .ex-pts {
background: var(--primary-light);
color: var(--primary);
border: 1px solid hsl(247, 85%, 90%);
}
.ex-block:has(.ei2) .ex-head {
background: var(--color-a-bg);
border-bottom-color: var(--color-a-border);
}
.ex-block:has(.ei2) .ex-icon {
background: hsl(36, 85%, 90%);
color: var(--color-a-accent);
}
.ex-block:has(.ei2) .ex-title {
color: var(--color-a-dark);
}
.ex-block:has(.ei2) .ex-pts {
background: var(--color-a-bg);
color: var(--color-a-accent);
border: 1px solid var(--color-a-border);
}
.ex-block:has(.ei3) .ex-head {
background: var(--color-g-bg);
border-bottom-color: var(--color-g-border);
}
.ex-block:has(.ei3) .ex-icon {
background: hsl(162, 85%, 90%);
color: var(--color-g-accent);
}
.ex-block:has(.ei3) .ex-title {
color: var(--color-g-dark);
}
.ex-block:has(.ei3) .ex-pts {
background: var(--color-g-bg);
color: var(--color-g-accent);
border: 1px solid var(--color-g-border);
}
.ex-block:has(.ti-arrows-sort) .ex-head {
background: var(--primary-light);
border-bottom-color: var(--color-border-secondary);
}
.ex-block:has(.ti-arrows-sort) .ex-icon {
background: hsl(247, 85%, 90%);
color: var(--primary);
}
.ex-block:has(.ti-arrows-sort) .ex-title {
color: var(--primary-dark);
}
.ex-block:has(.ti-arrows-sort) .ex-pts {
background: var(--primary-light);
color: var(--primary);
border: 1px solid hsl(247, 85%, 90%);
}
.ex-body {
padding: 20px;
}
/* Case Description Block */
.cas-box {
background: var(--bg-tertiary);
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
padding: 14px 18px;
margin-bottom: 1.5rem;
box-shadow: var(--shadow-sm);
}
.cas-lbl {
font-size: 0.7rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--color-text-secondary);
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 8px;
}
.cas-lbl i {
font-size: 1.1rem;
color: var(--primary);
}
.ex-block:has(.ei2) .cas-lbl i {
color: var(--color-a-accent);
}
.ex-block:has(.ei3) .cas-lbl i {
color: var(--color-g-accent);
}
.cas-text {
font-size: 0.9rem;
color: var(--color-text-primary);
line-height: 1.6;
font-family: var(--font-sans);
}
.cas-text strong {
font-weight: 800;
color: var(--primary-dark);
}
.ex-block:has(.ei2) .cas-text strong {
color: var(--color-a-dark);
}
.ex-block:has(.ei3) .cas-text strong {
color: var(--color-g-dark);
}
/* Instructions */
.consigne {
font-size: 0.85rem;
color: var(--color-text-secondary);
line-height: 1.6;
margin-bottom: 1.5rem;
font-style: italic;
opacity: 0.9;
}
/* Questions and MCQ */
.qrow {
margin-bottom: 1.5rem;
}
.qlbl {
font-size: 0.95rem;
font-weight: 800;
color: var(--color-text-primary);
margin-bottom: 10px;
display: flex;
align-items: flex-start;
gap: 10px;
line-height: 1.5;
}
.qnum {
width: 24px;
height: 24px;
border-radius: 50%;
background: var(--primary-light);
border: 1px solid hsl(247, 85%, 90%);
display: flex;
align-items: center;
justify-content: center;
font-size: 0.75rem;
font-weight: 800;
color: var(--primary);
flex-shrink: 0;
margin-top: 2px;
font-family: var(--font-heading);
}
.ex-block:has(.ei2) .qnum {
background: var(--color-a-bg);
border-color: var(--color-a-border);
color: var(--color-a-accent);
}
.ex-block:has(.ei3) .qnum {
background: var(--color-g-bg);
border-color: var(--color-g-border);
color: var(--color-g-accent);
}
.opts {
display: flex;
flex-direction: column;
gap: 8px;
margin-left: 34px;
}
.opt {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 10px 16px;
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
cursor: pointer;
background: var(--bg-secondary);
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: var(--shadow-sm);
}
.opt:hover {
border-color: var(--primary);
background: var(--primary-light);
transform: translateY(-1px);
box-shadow: var(--shadow-md);
}
.ex-block:has(.ei2) .opt:hover {
border-color: var(--color-a-accent);
background: var(--color-a-bg);
}
.ex-block:has(.ei3) .opt:hover {
border-color: var(--color-g-accent);
background: var(--color-g-bg);
}
/* MCQ Option States */
.opt.selected {
background: var(--primary-light);
border-color: var(--primary);
box-shadow: var(--shadow-md);
}
.ex-block:has(.ei2) .opt.selected {
background: var(--color-a-bg);
border-color: var(--color-a-accent);
}
.ex-block:has(.ei3) .opt.selected {
background: var(--color-g-bg);
border-color: var(--color-g-accent);
}
.opt.correct {
background: var(--color-g-bg) !important;
border-color: var(--color-g-accent) !important;
box-shadow: var(--shadow-md) !important;
}
.opt.wrong {
background: var(--color-danger-bg) !important;
border-color: var(--color-danger-border) !important;
box-shadow: var(--shadow-md) !important;
}
/* Custom Radio styling */
.opt-radio {
width: 18px;
height: 18px;
border-radius: 50%;
border: 2px solid var(--color-text-tertiary);
flex-shrink: 0;
margin-top: 2px;
display: flex;
align-items: center;
justify-content: center;
background: var(--bg-secondary);
transition: all 0.2s ease;
}
.opt.selected .opt-radio {
border-color: var(--primary);
}
.ex-block:has(.ei2) .opt.selected .opt-radio {
border-color: var(--color-a-accent);
}
.ex-block:has(.ei3) .opt.selected .opt-radio {
border-color: var(--color-g-accent);
}
.opt.correct .opt-radio {
border-color: var(--color-g-accent) !important;
background: var(--color-g-accent) !important;
}
.opt.wrong .opt-radio {
border-color: var(--color-danger-accent) !important;
background: var(--color-danger-accent) !important;
}
.opt-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: transparent;
transition: background 0.2s ease;
}
.opt.selected .opt-dot {
background: var(--primary);
}
.ex-block:has(.ei2) .opt.selected .opt-dot {
background: var(--color-a-accent);
}
.ex-block:has(.ei3) .opt.selected .opt-dot {
background: var(--color-g-accent);
}
.opt.correct .opt-dot,
.opt.wrong .opt-dot {
background: #ffffff !important;
}
/* Custom Checkbox styling for multi-select (Q5) */
.opt-checkbox {
width: 18px;
height: 18px;
border-radius: 4px;
border: 2px solid var(--color-text-tertiary);
flex-shrink: 0;
margin-top: 2px;
display: flex;
align-items: center;
justify-content: center;
background: var(--bg-secondary);
transition: all 0.2s ease;
}
.opt.selected .opt-checkbox {
border-color: var(--color-a-accent);
}
.opt.correct .opt-checkbox {
border-color: var(--color-g-accent) !important;
background: var(--color-g-accent) !important;
}
.opt.wrong .opt-checkbox {
border-color: var(--color-danger-accent) !important;
background: var(--color-danger-accent) !important;
}
.opt-check {
width: 8px;
height: 8px;
background: transparent;
border-radius: 1px;
transition: background 0.2s ease;
}
.opt.selected .opt-check {
background: var(--color-a-accent);
}
.opt.correct .opt-check,
.opt.wrong .opt-check {
background: #ffffff !important;
}
.opt-text {
font-size: 0.9rem;
color: var(--color-text-primary);
line-height: 1.5;
font-family: var(--font-sans);
}
.opt.correct .opt-text {
color: var(--color-g-dark);
font-weight: 700;
}
.opt.wrong .opt-text {
color: var(--color-danger-dark);
}
/* Textarea styling */
.ta {
width: 100%;
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
background: var(--bg-primary);
font-family: var(--font-sans);
font-size: 0.9rem;
color: var(--color-text-primary);
padding: 10px 14px;
resize: vertical;
outline: none;
line-height: 1.55;
transition: all 0.25s ease;
}
.ta:focus {
border-color: var(--primary);
background: var(--bg-secondary);
box-shadow: 0 0 0 3px hsla(247, 80%, 62%, 0.12);
}
.ta::placeholder {
color: var(--color-text-tertiary);
font-style: italic;
opacity: 0.7;
}
.ta-ml {
margin-left: 34px;
width: calc(100% - 34px);
}
.prompt-box {
background: var(--bg-secondary);
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
padding: 14px;
margin-bottom: 1.5rem;
font-family: var(--font-mono);
font-size: 0.85rem;
color: var(--color-text-primary);
line-height: 1.7;
box-shadow: var(--shadow-sm);
}
.prompt-lbl {
font-size: 0.7rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--color-text-secondary);
margin-bottom: 8px;
font-family: var(--font-sans);
}
.pb-tag {
display: inline-block;
font-size: 0.65rem;
font-weight: 800;
letter-spacing: .05em;
text-transform: uppercase;
padding: 2px 8px;
border-radius: 12px;
margin-left: 6px;
font-family: var(--font-sans);
}
.tag-ko {
background: var(--color-danger-bg);
color: var(--color-danger-accent);
border: 1px solid var(--color-danger-border);
}
/* Buttons & Actions */
.ex-actions {
display: flex;
align-items: center;
gap: 12px;
margin-top: 1.5rem;
}
.act-btn {
font-family: var(--font-heading);
font-size: 0.75rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
border-radius: 10px;
padding: 8px 16px;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: var(--shadow-sm);
}
.ab-check {
background: var(--primary);
border: 1px solid var(--primary);
color: white;
}
.ab-check:hover {
background: var(--primary-dark);
border-color: var(--primary-dark);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(117, 95, 236, 0.25);
}
.ex-block:has(.ei2) .ab-check {
background: var(--color-a-accent);
border-color: var(--color-a-accent);
}
.ex-block:has(.ei2) .ab-check:hover {
background: var(--color-a-dark);
border-color: var(--color-a-dark);
box-shadow: 0 4px 8px rgba(217, 119, 6, 0.25);
}
.ex-block:has(.ei3) .ab-check {
background: var(--color-g-accent);
border-color: var(--color-g-accent);
}
.ex-block:has(.ei3) .ab-check:hover {
background: var(--color-g-dark);
border-color: var(--color-g-dark);
box-shadow: 0 4px 8px rgba(16, 185, 129, 0.25);
}
.ex-block:has(.ti-arrows-sort) .ab-check {
background: var(--primary);
border-color: var(--primary);
}
.ex-block:has(.ti-arrows-sort) .ab-check:hover {
background: var(--primary-dark);
border-color: var(--primary-dark);
box-shadow: 0 4px 8px rgba(117, 95, 236, 0.25);
}
.ab-reset {
background: var(--bg-secondary);
border: 1px solid var(--color-border-secondary);
color: var(--color-text-secondary);
}
.ab-reset:hover {
background: var(--bg-tertiary);
color: var(--color-text-primary);
transform: translateY(-2px);
}
/* Result Badges */
.result-badge {
display: none;
align-items: center;
gap: 8px;
font-family: var(--font-heading);
font-size: 0.8rem;
font-weight: 800;
padding: 8px 16px;
border-radius: var(--border-radius-md);
margin-left: auto;
box-shadow: var(--shadow-sm);
}
.rb-ok {
background: var(--color-g-bg);
border: 1px solid var(--color-g-border);
color: var(--color-g-dark);
}
.rb-ko {
background: var(--color-danger-bg);
border: 1px solid var(--color-danger-border);
color: var(--color-danger-dark);
}
/* Debrief / Corrective Panel */
.corrige-btn {
font-family: var(--font-heading);
font-size: 0.75rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
background: var(--bg-secondary);
border: 1px solid var(--color-border-secondary);
border-radius: 10px;
padding: 8px 16px;
cursor: pointer;
color: var(--color-text-secondary);
margin-top: 1.5rem;
display: inline-flex;
align-items: center;
gap: 8px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: var(--shadow-sm);
}
.corrige-btn:hover {
background: var(--bg-tertiary);
color: var(--color-text-primary);
transform: translateY(-2px);
}
.corrige-btn.revealed {
background: var(--color-g-bg);
border-color: var(--color-g-accent);
color: var(--color-g-dark);
}
.corrige-panel {
display: none;
margin-top: 1rem;
background: var(--color-g-bg);
border: 1px solid var(--color-g-border);
border-radius: var(--border-radius-md);
padding: 16px 20px;
box-shadow: var(--shadow-sm);
}
.corrige-panel.visible {
display: block;
animation: slideDown 0.3s ease-out;
}
@keyframes slideDown {
from { opacity: 0; transform: translateY(-8px); }
to { opacity: 1; transform: translateY(0); }
}
.cp-title {
font-size: 0.75rem;
font-weight: 800;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--color-g-dark);
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 8px;
}
.cp-item {
font-size: 0.85rem;
color: var(--color-g-dark);
display: flex;
align-items: flex-start;
gap: 10px;
line-height: 1.6;
margin-bottom: 8px;
font-family: var(--font-sans);
}
.cp-item:last-child {
margin-bottom: 0;
}
.cp-item::before {
content: '✓';
color: var(--color-g-accent);
font-weight: 800;
flex-shrink: 0;
}
.cp-item.alert {
background: hsl(36, 85%, 93%);
border-radius: 6px;
padding: 8px 12px;
color: var(--color-a-dark);
}
.cp-item.alert::before {
content: '!';
color: var(--color-a-accent);
}
/* Print & Bottom Layout */
.print-row {
display: flex;
justify-content: flex-end;
margin-top: 2rem;
}
.pbtn {
font-family: var(--font-heading);
font-size: 0.75rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
background: var(--primary);
border: 1px solid var(--primary);
color: white;
border-radius: 10px;
padding: 10px 18px;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: var(--shadow-sm);
}
.pbtn:hover {
background: var(--primary-dark);
border-color: var(--primary-dark);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(117, 95, 236, 0.25);
}
/* Drag and Drop Exercise 4 Styles */
.legend {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
margin-bottom: 1.5rem;
}
.leg-item {
border-radius: var(--border-radius-md);
padding: 12px 14px;
text-align: center;
box-shadow: var(--shadow-sm);
transition: all 0.2s ease;
}
.leg-r {
background: var(--color-danger-bg);
border: 1px solid var(--color-danger-border);
}
.leg-h {
background: var(--color-a-bg);
border: 1px solid var(--color-a-border);
}
.leg-l {
background: var(--primary-light);
border: 1px solid hsl(247, 85%, 90%);
}
.leg-m {
background: var(--color-g-bg);
border: 1px solid var(--color-g-border);
}
.leg-lbl {
font-size: 0.75rem;
font-weight: 800;
letter-spacing: .05em;
text-transform: uppercase;
margin-bottom: 4px;
font-family: var(--font-heading);
}
.leg-r .leg-lbl { color: var(--color-danger-accent); }
.leg-h .leg-lbl { color: var(--color-a-accent); }
.leg-l .leg-lbl { color: var(--primary); }
.leg-m .leg-lbl { color: var(--color-g-accent); }
.leg-desc {
font-size: 0.8rem;
line-height: 1.4;
font-family: var(--font-sans);
}
.leg-r .leg-desc { color: var(--color-danger-dark); }
.leg-h .leg-desc { color: var(--color-a-dark); }
.leg-l .leg-desc { color: var(--primary-dark); }
.leg-m .leg-desc { color: var(--color-g-dark); }
.pool-label {
font-size: 0.7rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--color-text-secondary);
margin-bottom: 8px;
}
.pool {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 14px;
background: var(--bg-tertiary);
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
min-height: 56px;
margin-bottom: 1.5rem;
box-shadow: var(--shadow-sm) inset;
}
.card {
padding: 8px 14px;
border-radius: 20px;
font-size: 0.85rem;
font-weight: 700;
cursor: grab;
user-select: none;
border: 1px solid var(--color-border-secondary);
background: var(--bg-secondary);
color: var(--color-text-primary);
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: var(--shadow-sm);
}
.card:active {
cursor: grabbing;
}
.card.dragging {
opacity: .35;
}
.card.placed {
opacity: .3;
cursor: default;
pointer-events: none;
box-shadow: none;
}
.zones {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-bottom: 1.5rem;
}
.zone {
border-radius: var(--border-radius-lg);
overflow: hidden;
border: 1px solid var(--color-border-secondary);
box-shadow: var(--shadow-sm);
transition: box-shadow 0.2s ease;
}
.zone:hover {
box-shadow: var(--shadow-md);
}
.zone-head {
padding: 10px 14px;
display: flex;
align-items: center;
gap: 8px;
}
.zh-r {
background: var(--color-danger-bg);
border-bottom: 1px solid var(--color-danger-border);
}
.zh-h {
background: var(--color-a-bg);
border-bottom: 1px solid var(--color-a-border);
}
.zh-l {
background: var(--primary-light);
border-bottom: 1px solid hsl(247, 85%, 90%);
}
.zh-m {
background: var(--color-g-bg);
border-bottom: 1px solid var(--color-g-border);
}
.zone-icon {
font-size: 1.1rem;
}
.zi-r { color: var(--color-danger-accent); }
.zi-h { color: var(--color-a-accent); }
.zi-l { color: var(--primary); }
.zi-m { color: var(--color-g-accent); }
.zone-name {
font-size: 0.8rem;
font-weight: 800;
letter-spacing: .05em;
text-transform: uppercase;
font-family: var(--font-heading);
}
.zn-r { color: var(--color-danger-dark); }
.zn-h { color: var(--color-a-dark); }
.zn-l { color: var(--primary-dark); }
.zn-m { color: var(--color-g-dark); }
.zone-body {
min-height: 80px;
padding: 12px;
display: flex;
flex-wrap: wrap;
gap: 8px;
background: var(--bg-secondary);
transition: background 0.25s ease;
}
.zone-body.over {
background: var(--bg-tertiary);
}
.zone-ph {
font-size: 0.8rem;
color: var(--color-text-tertiary);
font-style: italic;
align-self: center;
padding: 2px 4px;
}
.placed-tag {
font-size: 0.8rem;
font-weight: 700;
padding: 5px 12px;
border-radius: 20px;
cursor: pointer;
border: 1px solid;
box-shadow: var(--shadow-sm);
transition: all 0.2s ease;
}
.placed-tag:hover {
background: #fee2e2 !important;
color: #ef4444 !important;
border-color: #fca5a5 !important;
box-shadow: 0 2px 4px rgba(239, 68, 68, 0.1);
}
.pt-r {
background: var(--color-danger-bg);
color: var(--color-danger-dark);
border-color: var(--color-danger-border);
}
.pt-h {
background: var(--color-a-bg);
color: var(--color-a-dark);
border-color: var(--color-a-border);
}
.pt-l {
background: var(--primary-light);
color: var(--primary-dark);
border-color: hsl(247, 85%, 90%);
}
.pt-m {
background: var(--color-g-bg);
color: var(--color-g-dark);
border-color: var(--color-g-border);
}
.pt-ok {
outline: 2px solid var(--color-g-accent) !important;
background: var(--color-g-bg) !important;
color: var(--color-g-dark) !important;
border-color: var(--color-g-accent) !important;
}
.pt-ko {
outline: 2px solid var(--color-danger-accent) !important;
background: var(--color-danger-bg) !important;
color: var(--color-danger-dark) !important;
border-color: var(--color-danger-border) !important;
}
/* Corrigé Panel for drag and drop */
.cp-head {
font-size: 0.75rem;
font-weight: 800;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--color-g-dark);
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 8px;
}
.cp-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-bottom: 1rem;
}
.cp-col {
display: flex;
flex-direction: column;
gap: 8px;
background: var(--bg-secondary);
padding: 14px;
border-radius: var(--border-radius-md);
border: 1px solid var(--color-g-border);
box-shadow: var(--shadow-sm);
}
.cp-col-lbl {
font-size: 0.75rem;
font-weight: 800;
letter-spacing: .05em;
text-transform: uppercase;
margin-bottom: 4px;
font-family: var(--font-heading);
}
.cpl-r { color: var(--color-danger-accent); }
.cpl-h { color: var(--color-a-accent); }
.cpl-l { color: var(--primary); }
.cpl-m { color: var(--color-g-accent); }
.cpr .cp-item::before { color: var(--color-danger-accent); }
.cph .cp-item::before { color: var(--color-a-accent); }
.cpl .cp-item::before { color: var(--primary); }
.cpm .cp-item::before { color: var(--color-g-accent); }
.cp-note {
font-size: 0.85rem;
color: var(--color-g-dark);
font-style: italic;
line-height: 1.5;
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid var(--color-g-border);
}
/* Responsive CSS Overrides */
@media (max-width: 860px) {
.w {
padding: 1.5rem 16px;
}
.dh {
flex-direction: column;
align-items: stretch;
gap: 1rem;
}
.identity-row {
grid-template-columns: 1fr;
gap: 12px;
}
.dt {
font-size: 1.6rem;
}
.score-strip {
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
gap: 8px;
}
.opts {
margin-left: 0;
}
.ta-ml {
margin-left: 0;
width: 100%;
}
.ex-actions {
flex-wrap: wrap;
}
.result-badge {
margin-left: 0;
width: 100%;
justify-content: center;
}
.legend {
grid-template-columns: 1fr 1fr;
gap: 8px;
}
.zones {
grid-template-columns: 1fr;
}
.cp-grid {
grid-template-columns: 1fr;
}
}
/* Print Styles Overrides */
@media print {
body {
background: white !important;
color: black !important;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.id-field {
border: 1px solid #94a3b8 !important;
background: white !important;
box-shadow: none !important;
}
.pbtn, .act-btn, .corrige-btn {
display: none !important;
}
.ex-block, .corrige-panel {
page-break-inside: avoid;
border: 1px solid #94a3b8 !important;
background: white !important;
box-shadow: none !important;
}
.opt {
border: 1px solid #94a3b8 !important;
background: white !important;
box-shadow: none !important;
}
.pool {
display: none !important;
}
}
</style>
</head>
<body>
<div class="w">
<!-- Accessibility Hidden Title -->
<h2 class="sr-only">Exercice M3 - sécuriser l'usage de l'IA : RGPD, IA Act, shadow AI, 3 exercices progressifs avec corrigés détaillés</h2>
<div class="dh">
<div>
<div class="dt">Sécuriser l'usage de l'IA en contexte professionnel</div>
</div>
<div class="hbadge">
<div class="hbt">Durée</div>
<div class="hbv">~35 min</div>
</div>
</div>
<!-- Identity Fields -->
<div class="identity-row">
<div class="id-field">
<span class="field-label">Nom</span>
<input class="field-line" type="text" placeholder="Entrez votre nom" id="student-lastname-c3" />
</div>
<div class="id-field">
<span class="field-label">Prénom</span>
<input class="field-line" type="text" placeholder="Entrez votre prénom" id="student-firstname-c3" />
</div>
</div>
<div class="score-strip">
<div class="sc">
<div class="sc-l">Exercice 1</div>
<div class="sc-v" id="sc1">-/4</div>
</div>
<div class="sc">
<div class="sc-l">Exercice 2</div>
<div class="sc-v" id="sc2">-/4</div>
</div>
<div class="sc">
<div class="sc-l">Exercice 3</div>
<div class="sc-v" id="sc3">-/4</div>
</div>
<div class="sc">
<div class="sc-l">Exercice 4</div>
<div class="sc-v" id="sc4">-/5</div>
</div>
<div class="sc">
<div class="sc-l">Total</div>
<div class="sc-v" id="sct">-/17</div>
</div>
</div>
<div class="notice">
<i class="ti ti-info-circle" aria-hidden="true"></i>
<p><strong>Important avant de commencer :</strong> C3 ne teste pas des connaissances juridiques. Il teste votre capacité à identifier un risque, à adopter le bon réflexe professionnel, et à reformuler les enjeux de façon accessible. Vous n'avez pas besoin de citer des articles de loi - vous devez savoir quand s'arrêter et qui solliciter.</p>
</div>
<!-- EXERCISE 1 -->
<div class="ex-block">
<div class="ex-head">
<div class="ex-icon ei1"><i class="ti ti-shield-x" aria-hidden="true"></i></div>
<div class="ex-meta">
<div class="ex-num">Exercice 1 · UF3 Ch.1 · 8 min</div>
<div class="ex-title">Identifier les risques RGPD dans des usages IA réels</div>
</div>
<span class="ex-pts">4 pts</span>
</div>
<div class="ex-body">
<div class="consigne">Pour chaque situation, choisissez l'évaluation correcte du risque RGPD. Une seule bonne réponse.</div>
<!-- Q1 -->
<div class="qrow">
<div class="qlbl">
<div class="qnum">1</div>Un commercial copie-colle un email client dans ChatGPT pour lui demander de rédiger une réponse. Le client n'a pas donné son accord pour que ses données soient traitées par OpenAI.
</div>
<div class="opts" id="q1">
<div class="opt" onclick="sel(this,'q1')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Aucun risque : les emails professionnels ne sont pas des données personnelles au sens du RGPD</div>
</div>
<div class="opt" onclick="sel(this,'q1')" data-correct="true">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Risque réel : l'email contient des données personnelles (identité, coordonnées, contexte). Leur transfert vers un tiers (OpenAI, hors UE) sans base légale constitue une violation potentielle du RGPD</div>
</div>
<div class="opt" onclick="sel(this,'q1')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Risque acceptable : ChatGPT efface les données après traitement, donc il n'y a pas de violation</div>
</div>
<div class="opt" onclick="sel(this,'q1')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Risque uniquement si le commercial est dans une entreprise de plus de 250 salariés</div>
</div>
</div>
</div>
<!-- Q2 -->
<div class="qrow">
<div class="qlbl">
<div class="qnum">2</div>Une RH utilise Mistral (hébergé en France) pour analyser des CV anonymisés - noms, prénoms et coordonnées ont été retirés. Elle garde les compétences, l'expérience et la localisation géographique.
</div>
<div class="opts" id="q2">
<div class="opt" onclick="sel(this,'q2')" data-correct="true">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Risque réduit mais non nul : la localisation géographique combinée à d'autres données peut permettre une réidentification. L'hébergement en France est un avantage mais ne suffit pas à garantir la conformité</div>
</div>
<div class="opt" onclick="sel(this,'q2')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Aucun risque : les données sont anonymisées, le RGPD ne s'applique plus</div>
</div>
<div class="opt" onclick="sel(this,'q2')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Risque élevé : toute analyse de CV par une IA est interdite, même anonymisée</div>
</div>
<div class="opt" onclick="sel(this,'q2')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Aucun risque : l'hébergement en France garantit la conformité RGPD automatique</div>
</div>
</div>
</div>
<!-- Q3 -->
<div class="qrow">
<div class="qlbl">
<div class="qnum">3</div>L'IA Act classe les systèmes d'IA par niveau de risque. Lequel de ces usages est classé "risque inacceptable" et donc interdit en Europe ?
</div>
<div class="opts" id="q3">
<div class="opt" onclick="sel(this,'q3')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Un chatbot de service client qui répond aux demandes de remboursement</div>
</div>
<div class="opt" onclick="sel(this,'q3')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Un système IA qui aide un médecin à prioriser les dossiers urgents aux urgences</div>
</div>
<div class="opt" onclick="sel(this,'q3')" data-correct="true">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Un système de notation sociale des citoyens par les autorités publiques basé sur leur comportement</div>
</div>
<div class="opt" onclick="sel(this,'q3')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Un outil IA de recommandation de contenu sur une plateforme de streaming</div>
</div>
</div>
</div>
<!-- Q4 -->
<div class="qrow">
<div class="qlbl">
<div class="qnum">4</div>Un apprenant vous demande : "Mon entreprise risque quelque chose si on utilise ChatGPT avec des données clients ?" Quelle est la bonne réponse de formateur ?
</div>
<div class="opts" id="q4">
<div class="opt" onclick="sel(this,'q4')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">"Oui, vous risquez une amende RGPD pouvant aller jusqu'à 4% de votre chiffre d'affaires mondial"</div>
</div>
<div class="opt" onclick="sel(this,'q4')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">"Non, ChatGPT est conforme RGPD depuis 2023 donc il n'y a pas de risque"</div>
</div>
<div class="opt" onclick="sel(this,'q4')" data-correct="true">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">"Je peux vous expliquer les principes généraux du risque RGPD - mais pour votre situation précise, c'est votre DPO ou service juridique qui peut vous répondre. Ce n'est pas mon rôle de vous conseiller juridiquement."</div>
</div>
<div class="opt" onclick="sel(this,'q4')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">"Ça dépend de la taille de votre entreprise - en dessous de 10 salariés, il n'y a pas d'obligation"</div>
</div>
</div>
</div>
<div class="ex-actions">
<button class="act-btn ab-check" onclick="checkEx('ex1',['q1','q2','q3','q4'],'sc1',4,'rb1')"><i class="ti ti-check" aria-hidden="true"></i>Vérifier</button>
<button class="act-btn ab-reset" onclick="resetEx(['q1','q2','q3','q4'],'sc1','rb1')"><i class="ti ti-refresh" aria-hidden="true"></i>Réinitialiser</button>
<div id="rb1" class="result-badge"></div>
</div>
<button class="corrige-btn" id="cb1" onclick="togCorrige('cp1','cb1')"><i class="ti ti-eye" aria-hidden="true"></i>Voir le corrigé</button>
<div class="corrige-panel" id="cp1">
<div class="cp-title"><i class="ti ti-check" aria-hidden="true"></i>Corrigé - exercice 1</div>
<div class="cp-item">Q1 - B. Les emails professionnels contiennent quasi systématiquement des données personnelles. OpenAI (comme la plupart des grands modèles américains) peut utiliser ces données pour l'entraînement si l'option n'est pas désactivée, et le transfert hors UE nécessite une base légale. Le risque est réel et documenté - voir l'affaire Samsung/ChatGPT (2023).</div>
<div class="cp-item">Q2 - A. L'anonymisation réduit le risque mais ne l'élimine pas : la localisation géographique est une donnée qui peut permettre une réidentification croisée. L'hébergement en France est un avantage (pas de transfert hors UE) mais la conformité RGPD dépend aussi de la finalité du traitement et de sa documentation.</div>
<div class="cp-item">Q3 - C. La notation sociale par les autorités publiques figure explicitement dans l'IA Act comme usage à "risque inacceptable" et est interdite en Europe. Les autres usages sont classés "risque élevé" (médical) ou "risque limité" (chatbot, recommandation) - encadrés mais autorisés.</div>
<div class="cp-item alert">Q4 - C. C'est la réponse la plus importante de cet exercice. Un formateur n'est pas juriste. Même si vous connaissez les chiffres des amendes, les énoncer dans ce contexte revient à donner un conseil juridique. La formule "ce n'est pas mon rôle" protège l'apprenant ET le formateur.</div>
</div>
</div>
</div>
<!-- EXERCISE 2 -->
<div class="ex-block">
<div class="ex-head">
<div class="ex-icon ei2"><i class="ti ti-pencil-x" aria-hidden="true"></i></div>
<div class="ex-meta">
<div class="ex-num">Exercice 2 · UF3 Ch.1 & Ch.2 · 12 min</div>
<div class="ex-title">Corriger un prompt non conforme RGPD</div>
</div>
<span class="ex-pts">4 pts</span>
</div>
<div class="ex-body">
<div class="cas-box">
<div class="cas-lbl"><i class="ti ti-briefcase" aria-hidden="true"></i>Contexte - Chargée de clientèle dans une mutuelle santé</div>
<div class="cas-text">Lucie est chargée de clientèle. Elle reçoit des réclamations complexes et veut utiliser l'IA pour rédiger des réponses. Elle utilise ChatGPT (compte personnel, sans option de désactivation du réentraînement activée) et soumet ce prompt :</div>
</div>
<div class="prompt-box">
<div class="prompt-lbl">Prompt original de Lucie <span class="pb-tag tag-ko">non conforme</span></div>
"Tu es un expert en assurance santé. Voici la réclamation de mon client M. Jean Dupont, né le 12/03/1978, numéro d'adhérent 445892-B, domicilié 14 rue des Lilas, 69003 Lyon. Il conteste le remboursement de son hospitalisation du 15 au 18 octobre pour une chirurgie du genou droit. Son médecin traitant est le Dr Moreau. Rédige une réponse professionnelle qui explique pourquoi son remboursement a été calculé correctement selon son contrat Formule Confort+."
</div>
<div class="consigne">Identifiez les problèmes RGPD dans ce prompt, puis réécrivez-le de façon conforme.</div>
<!-- Q5 -->
<div class="qrow">
<div class="qlbl">
<div class="qnum">5</div>Quels éléments du prompt posent un problème RGPD ? Sélectionnez toutes les réponses correctes.
</div>
<div class="opts" id="q5">
<div class="opt" onclick="selMulti(this,'q5')" data-correct="true">
<div class="opt-checkbox"><div class="opt-check"></div></div>
<div class="opt-text">Le nom, prénom et date de naissance du client - données d'identité directement nominatives</div>
</div>
<div class="opt" onclick="selMulti(this,'q5')" data-correct="true">
<div class="opt-checkbox"><div class="opt-check"></div></div>
<div class="opt-text">Le numéro d'adhérent et l'adresse - données permettant une identification et une localisation précises</div>
</div>
<div class="opt" onclick="selMulti(this,'q5')" data-correct="true">
<div class="opt-checkbox"><div class="opt-check"></div></div>
<div class="opt-text">Les informations de santé (chirurgie, hospitalisation, médecin traitant) - données de santé = catégorie spéciale RGPD, protection renforcée obligatoire</div>
</div>
<div class="opt" onclick="selMulti(this,'q5')">
<div class="opt-checkbox"><div class="opt-check"></div></div>
<div class="opt-text">Le nom du contrat (Formule Confort+) - donnée confidentielle mais pas une donnée personnelle au sens strict</div>
</div>
</div>
<p style="font-size:11.5px;color:var(--color-text-secondary);font-style:italic;margin:6px 0 0 34px;">Plusieurs réponses possibles.</p>
</div>
<!-- Q6 -->
<div class="qrow">
<div class="qlbl">
<div class="qnum">6</div>Réécrivez le prompt de Lucie de façon conforme - en conservant la capacité à obtenir une réponse utile.
</div>
<textarea class="ta ta-ml" rows="5" placeholder="Rédigez ici votre version corrigée du prompt, sans données personnelles identifiantes…" aria-label="Prompt corrigé"></textarea>
</div>
<div class="ex-actions">
<button class="act-btn ab-check" onclick="checkEx('ex2',['q5'],'sc2',4,'rb2')"><i class="ti ti-check" aria-hidden="true"></i>Vérifier</button>
<button class="act-btn ab-reset" onclick="resetEx(['q5'],'sc2','rb2')"><i class="ti ti-refresh" aria-hidden="true"></i>Réinitialiser</button>
<div id="rb2" class="result-badge"></div>
</div>
<button class="corrige-btn" id="cb2" onclick="togCorrige('cp2','cb2')"><i class="ti ti-eye" aria-hidden="true"></i>Voir le corrigé</button>
<div class="corrige-panel" id="cp2">
<div class="cp-title"><i class="ti ti-check" aria-hidden="true"></i>Corrigé - exercice 2</div>
<div class="cp-item">Q5 - Les 3 premières réponses sont correctes. Nom/prénom/date de naissance, numéro d'adhérent/adresse, et surtout les données de santé (catégorie spéciale RGPD, art. 9) posent tous un problème sérieux. Le nom du contrat n'est pas une donnée personnelle au sens RGPD - bien qu'il soit préférable de le retirer aussi.</div>
<div class="cp-item">Q6 - Version conforme attendue : <em>"Tu es un expert en assurance santé. Un adhérent conteste le remboursement d'une hospitalisation de 3 jours pour une intervention chirurgicale orthopédique. Son contrat inclut la Formule Confort+. Rédige une réponse professionnelle type expliquant les principes de calcul du remboursement pour ce type d'acte, en laissant des espaces à compléter avec les données spécifiques du dossier."</em></div>
<div class="cp-item alert">Principe clé à retenir : anonymiser ou pseudonymiser avant de soumettre à l'IA. L'IA n'a pas besoin du nom réel pour produire une réponse utile - elle a besoin du contexte et de la structure du cas.</div>
</div>
</div>
</div>
<!-- EXERCISE 3 -->
<div class="ex-block">
<div class="ex-head">
<div class="ex-icon ei3"><i class="ti ti-scale" aria-hidden="true"></i></div>
<div class="ex-meta">
<div class="ex-num">Exercice 3 · UF3 Ch.2 · 15 min</div>
<div class="ex-title">Analyser un cas de shadow AI selon l'IA Act</div>
</div>
<span class="ex-pts">4 pts</span>
</div>
<div class="ex-body">
<div class="cas-box">
<div class="cas-lbl"><i class="ti ti-building" aria-hidden="true"></i>Cas - Entreprise industrielle, 180 salariés</div>
<div class="cas-text">Dans une entreprise de fabrication, plusieurs ingénieurs utilisent ChatGPT en dehors des outils approuvés par la DSI pour générer des spécifications techniques. Un ingénieur a copié-collé des plans de fabrication d'une pièce innovante (non encore brevetée) pour demander à l'IA d'optimiser la conception. La DSI découvre cette pratique lors d'un audit. La direction hésite : sanctionner les ingénieurs, ou régulariser les usages ?</div>
</div>
<div class="consigne">Répondez aux 3 questions pour analyser ce cas sous l'angle sécurité, IA Act et gouvernance.</div>
<!-- Q7 -->
<div class="qrow">
<div class="qlbl">
<div class="qnum">7</div>Quel est le risque principal dans ce cas - au-delà du RGPD ?
</div>
<div class="opts" id="q7">
<div class="opt" onclick="sel(this,'q7')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Le risque principal est une amende RGPD - les plans techniques peuvent contenir des données personnelles</div>
</div>
<div class="opt" onclick="sel(this,'q7')" data-correct="true">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Le risque principal est la fuite de propriété intellectuelle : des plans non brevetés soumis à un modèle tiers peuvent être utilisés pour réentraîner le modèle, exposant ainsi des secrets industriels</div>
</div>
<div class="opt" onclick="sel(this,'q7')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Le risque principal est d'ordre pénal : utiliser une IA sans autorisation de la DSI constitue un accès frauduleux à un système informatique</div>
</div>
<div class="opt" onclick="sel(this,'q7')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Il n'y a pas de risque réel car les plans techniques ne sont pas des données personnelles</div>
</div>
</div>
</div>
<!-- Q8 -->
<div class="qrow">
<div class="qlbl">
<div class="qnum">8</div>Sous l'IA Act, le système utilisé par les ingénieurs (ChatGPT pour générer des spécifications techniques industrielles) est classé dans quel niveau de risque ?
</div>
<div class="opts" id="q8">
<div class="opt" onclick="sel(this,'q8')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Risque inacceptable - interdit en Europe</div>
</div>
<div class="opt" onclick="sel(this,'q8')" data-correct="true">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Risque limité à modéré - l'usage est autorisé mais doit être transparent et documenté, notamment pour les décisions critiques de sécurité industrielle</div>
</div>
<div class="opt" onclick="sel(this,'q8')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Risque nul - les outils de productivité généralistes comme ChatGPT sont hors périmètre de l'IA Act</div>
</div>
<div class="opt" onclick="sel(this,'q8')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Risque élevé automatique dès qu'une IA touche à la conception industrielle</div>
</div>
</div>
</div>
<!-- Q9 -->
<div class="qrow">
<div class="qlbl">
<div class="qnum">9</div>La direction hésite entre sanctionner et régulariser. Quelle posture recommanderiez-vous, et pourquoi ?
</div>
<div class="opts" id="q9">
<div class="opt" onclick="sel(this,'q9')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Sanctionner fermement - le non-respect des règles DSI ne peut pas être toléré, même si l'intention était productive</div>
</div>
<div class="opt" onclick="sel(this,'q9')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Ignorer - les ingénieurs ont utilisé l'IA de façon productive, punir freinerait l'innovation</div>
</div>
<div class="opt" onclick="sel(this,'q9')" data-correct="true">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Régulariser avec cadre : documenter les usages, définir quelles données peuvent ou ne peuvent pas être soumises à une IA externe, former les équipes, et choisir des outils approuvés. La sanction seule sans accompagnement ne résout pas le problème structurel</div>
</div>
<div class="opt" onclick="sel(this,'q9')">
<div class="opt-radio"><div class="opt-dot"></div></div>
<div class="opt-text">Attendre la réglementation définitive de l'IA Act avant de décider</div>
</div>
</div>
</div>
<div class="ex-actions">
<button class="act-btn ab-check" onclick="checkEx('ex3',['q7','q8','q9'],'sc3',3,'rb3')"><i class="ti ti-check" aria-hidden="true"></i>Vérifier</button>
<button class="act-btn ab-reset" onclick="resetEx(['q7','q8','q9'],'sc3','rb3')"><i class="ti ti-refresh" aria-hidden="true"></i>Réinitialiser</button>
<div id="rb3" class="result-badge"></div>
</div>
<button class="corrige-btn" id="cb3" onclick="togCorrige('cp3','cb3')" style="margin-top:14px;"><i class="ti ti-eye" aria-hidden="true"></i>Voir le corrigé détaillé</button>
<div class="corrige-panel" id="cp3">
<div class="cp-title"><i class="ti ti-check" aria-hidden="true"></i>Corrigé - exercice 3</div>
<div class="cp-item">Q7 - B. La propriété intellectuelle est le risque central ici, pas le RGPD (les plans techniques ne sont pas des données personnelles). Un plan industriel non breveté soumis à ChatGPT peut théoriquement être réutilisé dans le réentraînement du modèle. L'affaire Samsung (2023) est l'exemple réel le plus documenté de ce type d'incident.</div>
<div class="cp-item">Q8 - B. ChatGPT est un outil généraliste à risque limité sous l'IA Act. Mais l'usage pour des décisions de sécurité industrielle peut faire basculer l'usage dans une catégorie de risque plus élevé - c'est le contexte d'utilisation qui détermine le niveau de risque, pas uniquement l'outil.</div>
<div class="cp-item">Q9 - C. La sanction seule ne résout rien : si les ingénieurs ont eu recours au shadow AI, c'est souvent parce que les outils approuvés ne répondent pas à leurs besoins. La bonne réponse est structurelle : cadre, formation, outils adaptés. C'est exactement le message de l'UF3 - la sécurité par la conscience et l'outillage, pas par la peur.</div>
<div class="cp-item alert">À retenir comme formateur : face au shadow AI dans vos groupes d'apprenants, évitez la posture moralisatrice. Partez des risques concrets (propriété intellectuelle, données clients) et proposez des alternatives praticables. Le "non" sans alternative génère du contournement.</div>
</div>
</div>
</div>
<!-- EXERCISE 4 -->
<h2 style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)">Exercice drag and drop certification C3 — classifier 10 usages IA selon les 4 niveaux de risque de l'IA Act : inacceptable, élevé, limité, minimal</h2>
<div class="ex-block">
<div class="ex-head">
<div class="ex-icon"><i class="ti ti-arrows-sort" aria-hidden="true"></i></div>
<div class="ex-meta">
<div class="ex-num">Exercice 4 · UF3 Ch.1 · IA Act · 10 min</div>
<div class="ex-title">Classer 10 usages IA selon les 4 niveaux de risque de l'IA Act</div>
</div>
<span class="ex-pts">5 pts</span>
</div>
<div class="ex-body">
<div class="consigne">Faites glisser chaque usage vers le niveau de risque qui lui correspond selon l'IA Act. Cliquez sur un élément déjà placé pour le retirer.</div>
<!-- Legend Block -->
<div class="legend">
<div class="leg-item leg-r">
<div class="leg-lbl">Inacceptable</div>
<div class="leg-desc">Interdit en Europe</div>
</div>
<div class="leg-item leg-h">
<div class="leg-lbl">Élevé</div>
<div class="leg-desc">Autorisé, très encadré</div>
</div>
<div class="leg-item leg-l">
<div class="leg-lbl">Limité</div>
<div class="leg-desc">Autorisé, obligations de transparence</div>
</div>
<div class="leg-item leg-m">
<div class="leg-lbl">Minimal</div>
<div class="leg-desc">Autorisé sans contrainte spécifique</div>
</div>
</div>
<div class="pool-label">Usages à classer — faites glisser</div>
<div class="pool" id="pool">
<div class="card" draggable="true" data-id="1" data-correct="r">Notation sociale des citoyens par l'État</div>
<div class="card" draggable="true" data-id="2" data-correct="h">Aide à la décision médicale aux urgences</div>
<div class="card" draggable="true" data-id="3" data-correct="l">Chatbot de service client avec IA</div>
<div class="card" draggable="true" data-id="4" data-correct="h">Tri automatique de CV pour le recrutement</div>
<div class="card" draggable="true" data-id="5" data-correct="m">Filtre anti-spam dans une messagerie</div>
<div class="card" draggable="true" data-id="6" data-correct="r">Reconnaissance faciale en temps réel dans l'espace public</div>
<div class="card" draggable="true" data-id="7" data-correct="h">Évaluation du risque de récidive par la justice</div>
<div class="card" draggable="true" data-id="8" data-correct="l">Génération d'images par IA (deepfake déclaré)</div>
<div class="card" draggable="true" data-id="9" data-correct="m">Recommandation de contenu sur Netflix</div>
<div class="card" draggable="true" data-id="10" data-correct="h">Notation de solvabilité bancaire par IA</div>
</div>
<div class="zones">
<div class="zone" id="zone-r" ondragover="onOver(event,this)" ondragleave="onLeave(this)" ondrop="onDrop(event,'r',this)">
<div class="zone-head zh-r"><i class="ti ti-ban zone-icon zi-r" aria-hidden="true"></i><span class="zone-name zn-r">Risque inacceptable</span></div>
<div class="zone-body" id="zb-r"><span class="zone-ph">Déposez ici</span></div>
</div>
<div class="zone" id="zone-h" ondragover="onOver(event,this)" ondragleave="onLeave(this)" ondrop="onDrop(event,'h',this)">
<div class="zone-head zh-h"><i class="ti ti-alert-triangle zone-icon zi-h" aria-hidden="true"></i><span class="zone-name zn-h">Risque élevé</span></div>
<div class="zone-body" id="zb-h"><span class="zone-ph">Déposez ici</span></div>
</div>
<div class="zone" id="zone-l" ondragover="onOver(event,this)" ondragleave="onLeave(this)" ondrop="onDrop(event,'l',this)">
<div class="zone-head zh-l"><i class="ti ti-info-circle zone-icon zi-l" aria-hidden="true"></i><span class="zone-name zn-l">Risque limité</span></div>
<div class="zone-body" id="zb-l"><span class="zone-ph">Déposez ici</span></div>
</div>
<div class="zone" id="zone-m" ondragover="onOver(event,this)" ondragleave="onLeave(this)" ondrop="onDrop(event,'m',this)">
<div class="zone-head zh-m"><i class="ti ti-circle-check zone-icon zi-m" aria-hidden="true"></i><span class="zone-name zn-m">Risque minimal</span></div>
<div class="zone-body" id="zb-m"><span class="zone-ph">Déposez ici</span></div>
</div>
</div>
<div class="ex-actions">
<button class="act-btn ab-check" onclick="checkDD()"><i class="ti ti-check" aria-hidden="true"></i>Vérifier</button>
<button class="act-btn ab-reset" onclick="resetDD()"><i class="ti ti-refresh" aria-hidden="true"></i>Réinitialiser</button>
<div id="rb-dd" class="result-badge"></div>
</div>
<button class="corrige-btn" id="cb-dd" onclick="togCorrige('cp-dd','cb-dd')"><i class="ti ti-eye" aria-hidden="true"></i>Voir le corrigé</button>
<div class="corrige-panel" id="cp-dd">
<div class="cp-head"><i class="ti ti-check" aria-hidden="true"></i>Corrigé — classification IA Act</div>
<div class="cp-grid">
<div class="cp-col cpr">
<div class="cp-col-lbl cpl-r">Inacceptable — interdit</div>
<div class="cp-item">Notation sociale des citoyens : manipulation comportementale à grande échelle, explicitement interdite par l'IA Act (art. 5)</div>
<div class="cp-item">Reconnaissance faciale en temps réel dans l'espace public : surveillance de masse, interdite sauf exceptions de sécurité nationale strictement encadrées</div>
</div>
<div class="cp-col cph">
<div class="cp-col-lbl cpl-h">Élevé — très encadré</div>
<div class="cp-item">Aide médicale aux urgences : décision à fort impact sur la santé — supervision humaine obligatoire, documentation, validation CE</div>
<div class="cp-item">Tri de CV : impact sur l'emploi — transparence obligatoire, information des candidats, supervision humaine</div>
<div class="cp-item">Risque de récidive (justice) : impact sur la liberté individuelle — encadrement judiciaire strict, explicabilité requise</div>
<div class="cp-item">Notation de solvabilité : accès au crédit — base légale, droits d'opposition, non-discrimination</div>
</div>
<div class="cp-col cpl">
<div class="cp-col-lbl cpl-l">Limité — transparence requise</div>
<div class="cp-item">Chatbot service client : l'utilisateur doit savoir qu'il parle à une IA — obligation de divulgation</div>
<div class="cp-item">Deepfake déclaré : contenu généré par IA doit être labellisé comme tel — watermarking obligatoire</div>
</div>
<div class="cp-col cpm">
<div class="cp-col-lbl cpl-m">Minimal — sans contrainte spécifique</div>
<div class="cp-item">Filtre anti-spam : IA technique sans impact sur les droits des personnes</div>
<div class="cp-item">Recommandation Netflix : faible impact, pas de décision critique, usage de loisir</div>
</div>
</div>
<div class="cp-note">Le niveau de risque dépend du contexte d'usage, pas seulement de la technologie. Un même système d'IA peut être "minimal" dans un usage et "élevé" dans un autre — c'est le cas d'un outil de reconnaissance d'images utilisé pour trier des photos de vacances (minimal) vs identifier des suspects (potentiellement inacceptable).</div>
</div>
</div>
</div>
<div class="print-row">
<button class="pbtn" onclick="window.print()"><i class="ti ti-printer" aria-hidden="true"></i>Imprimer</button>
</div>
</div>
<script>
function sel(el, qid) {
document.getElementById(qid).querySelectorAll('.opt').forEach(o => o.classList.remove('selected', 'correct', 'wrong'));
el.classList.add('selected');
saveChoices();
}
function selMulti(el, qid) {
el.classList.toggle('selected');
saveChoices();
}
function checkEx(exid, qids, scid, max, rbid) {
let score = 0;
qids.forEach(qid => {
const grp = document.getElementById(qid);
const opts = grp.querySelectorAll('.opt');
const isMulti = opts[0].querySelector('.opt-checkbox') !== null;
if (isMulti) {
let allOk = true;
opts.forEach(o => {
const shouldBe = o.dataset.correct === 'true';
const isSelected = o.classList.contains('selected');
o.classList.remove('selected', 'correct', 'wrong');
if (shouldBe && isSelected) { o.classList.add('correct'); }
else if (!shouldBe && !isSelected) { o.classList.add('correct'); }
else { o.classList.add('wrong'); allOk = false; }
});
if (allOk) score = max; // Q5 is 4 pts total if all checkbox answers are correct
} else {
const sel = grp.querySelector('.opt.selected');
if (!sel) return;
const correct = grp.querySelector('[data-correct="true"]');
sel.classList.remove('selected');
if (sel === correct) { sel.classList.add('correct'); score++; }
else { sel.classList.add('wrong'); if (correct) correct.classList.add('correct'); }
}
});
document.getElementById(scid).textContent = score + '/' + max;
document.getElementById(scid).className = 'sc-v ' + (score >= Math.ceil(max * 0.75) ? 'ok' : 'ko');
const rb = document.getElementById(rbid);
rb.style.display = 'flex';
rb.className = 'result-badge ' + (score >= Math.ceil(max * 0.75) ? 'rb-ok' : 'rb-ko');
rb.innerHTML = (score >= Math.ceil(max * 0.75) ? '<i class="ti ti-check"></i>' : '<i class="ti ti-x"></i>') + ' ' + score + '/' + max;
updateTotal();
}
function resetEx(qids, scid, rbid) {
qids.forEach(qid => {
document.getElementById(qid).querySelectorAll('.opt').forEach(o => o.classList.remove('selected', 'correct', 'wrong'));
});
document.getElementById(scid).textContent = '-/' + document.getElementById(scid).textContent.split('/')[1];
document.getElementById(scid).className = 'sc-v';
document.getElementById(rbid).className = 'result-badge';
document.getElementById(rbid).style.display = 'none';
saveChoices();
updateTotal();
}
function updateTotal() {
const s1 = document.getElementById('sc1').textContent;
const s2 = document.getElementById('sc2').textContent;
const s3 = document.getElementById('sc3').textContent;
const s4 = document.getElementById('sc4').textContent;
const v1 = s1.startsWith('-') ? null : parseInt(s1);
const v2 = s2.startsWith('-') ? null : parseInt(s2);
const v3 = s3.startsWith('-') ? null : parseInt(s3);
const v4 = s4.startsWith('-') ? null : parseInt(s4);
let t = 0;
let activeCount = 0;
if (v1 !== null) { t += v1; activeCount++; }
if (v2 !== null) { t += v2; activeCount++; }
if (v3 !== null) { t += v3; activeCount++; }
if (v4 !== null) { t += v4; activeCount++; }
const el = document.getElementById('sct');
if (activeCount > 0) {
el.textContent = t + '/17';
el.className = 'sc-v ' + (t >= 13 ? 'ok' : 'ko');
} else {
el.textContent = '-/17';
el.className = 'sc-v';
}
}
function togCorrige(pid, bid) {
const p = document.getElementById(pid);
const b = document.getElementById(bid);
const v = p.classList.contains('visible');
p.classList.toggle('visible', !v);
b.classList.toggle('revealed', !v);
b.innerHTML = v ? '<i class="ti ti-eye" aria-hidden="true"></i> Voir le corrigé' : '<i class="ti ti-eye-off" aria-hidden="true"></i> Masquer le corrigé';
}
// LocalStorage Auto-save choices
function saveChoices() {
const selections = [];
document.querySelectorAll('.opt').forEach((opt) => {
selections.push(opt.classList.contains('selected'));
});
localStorage.setItem('c3_mcq_selections', JSON.stringify(selections));
// Save Drag & Drop placements
localStorage.setItem('c3_dd_placements', JSON.stringify(placements));
}
document.addEventListener('DOMContentLoaded', () => {
// Identity fields
const lastnameEl = document.getElementById('student-lastname-c3');
const firstnameEl = document.getElementById('student-firstname-c3');
const savedLastname = localStorage.getItem('student_lastname_c3');
const savedFirstname = localStorage.getItem('student_firstname_c3');
if (savedLastname) lastnameEl.value = savedLastname;
if (savedFirstname) firstnameEl.value = savedFirstname;
lastnameEl.addEventListener('input', () => {
localStorage.setItem('student_lastname_c3', lastnameEl.value);
});
firstnameEl.addEventListener('input', () => {
localStorage.setItem('student_firstname_c3', firstnameEl.value);
});
// Textareas
const textareas = document.querySelectorAll('textarea');
textareas.forEach((t, index) => {
const savedVal = localStorage.getItem(`textarea_fiche_c3_${index}`);
if (savedVal) t.value = savedVal;
t.addEventListener('input', () => {
localStorage.setItem(`textarea_fiche_c3_${index}`, t.value);
});
});
// Restore MCQ selections
const savedSelections = localStorage.getItem('c3_mcq_selections');
if (savedSelections) {
const selections = JSON.parse(savedSelections);
document.querySelectorAll('.opt').forEach((opt, index) => {
if (selections[index]) {
opt.classList.add('selected');
}
});
}
// Restore Drag & Drop placements
const savedPlacements = localStorage.getItem('c3_dd_placements');
if (savedPlacements) {
const restored = JSON.parse(savedPlacements);
Object.keys(restored).forEach(id => {
const level = restored[id];
placements[id] = level;
const card = document.querySelector(`.card[data-id="${id}"]`);
if (card) {
card.classList.add('placed');
const zb = document.getElementById('zb-' + level);
const ph = zb.querySelector('.zone-ph');
if (ph) ph.remove();
const tag = document.createElement('span');
tag.className = 'placed-tag pt-' + level;
tag.dataset.pid = id;
tag.textContent = card.textContent;
tag.title = 'Cliquer pour retirer';
tag.onclick = () => removeTag(tag, id, level);
zb.appendChild(tag);
}
});
}
});
</script>
<script>
let dragged = null;
const placements = {};
document.querySelectorAll('.card').forEach(c => {
c.addEventListener('dragstart', e => {
dragged = c;
setTimeout(() => c.classList.add('dragging'), 0);
});
c.addEventListener('dragend', () => c.classList.remove('dragging'));
});
function onOver(e, zone) {
e.preventDefault();
zone.querySelector('.zone-body').classList.add('over');
}
function onLeave(zone) {
zone.querySelector('.zone-body').classList.remove('over');
}
function onDrop(e, level, zone) {
e.preventDefault();
zone.querySelector('.zone-body').classList.remove('over');
if (!dragged) return;
const id = dragged.dataset.id;
if (placements[id]) {
const old = document.getElementById('zb-' + placements[id]);
const existing = old.querySelector('[data-pid="' + id + '"]');
if (existing) existing.remove();
checkPh(old);
}
placements[id] = level;
dragged.classList.add('placed');
const zb = document.getElementById('zb-' + level);
const ph = zb.querySelector('.zone-ph');
if (ph) ph.remove();
const tag = document.createElement('span');
tag.className = 'placed-tag pt-' + level;
tag.dataset.pid = id;
tag.textContent = dragged.textContent;
tag.title = 'Cliquer pour retirer';
tag.onclick = () => removeTag(tag, id, level);
zb.appendChild(tag);
dragged = null;
clearResults();
saveChoices();
}
function removeTag(tag, id, level) {
tag.remove();
delete placements[id];
const zb = document.getElementById('zb-' + level);
checkPh(zb);
const card = document.querySelector('.card[data-id="' + id + '"]');
if (card) {
card.classList.remove('placed', 'pt-ok', 'pt-ko');
}
clearResults();
saveChoices();
}
function checkPh(zb) {
if (!zb.querySelector('.placed-tag') && !zb.querySelector('.zone-ph')) {
const ph = document.createElement('span');
ph.className = 'zone-ph';
ph.textContent = 'Déposez ici';
zb.appendChild(ph);
}
}
function clearResults() {
document.querySelectorAll('.placed-tag').forEach(t => t.classList.remove('pt-ok', 'pt-ko'));
const rb = document.getElementById('rb-dd');
rb.className = 'result-badge';
rb.innerHTML = '';
}
function checkDD() {
let score = 0, total = 0;
document.querySelectorAll('.card').forEach(c => {
const id = c.dataset.id;
const correct = c.dataset.correct;
if (!placements[id]) return;
total++;
const tag = document.querySelector('[data-pid="' + id + '"]');
if (tag) {
if (placements[id] === correct) {
tag.classList.add('pt-ok');
score++;
} else {
tag.classList.add('pt-ko');
}
}
});
const rb = document.getElementById('rb-dd');
if (total === 0) {
rb.className = 'result-badge';
rb.innerHTML = '';
return;
}
const all = document.querySelectorAll('.card').length;
rb.className = 'result-badge ' + (score >= Math.ceil(all * 0.7) ? 'rb-ok' : 'rb-ko');
rb.innerHTML = '<i class="ti ti-' + (score >= Math.ceil(all * 0.7) ? 'check' : 'x') + '" aria-hidden="true"></i> ' + score + '/' + all;
// Update Exercise 4 score strip: Exercise 4 points is Math.round(score / 2) because it is out of 5, but there are 10 cards.
const pointScore = Math.round(score / 2);
document.getElementById('sc4').textContent = pointScore + '/5';
document.getElementById('sc4').className = 'sc-v ' + (pointScore >= 4 ? 'ok' : 'ko');
// Make result badge visible
rb.style.display = 'flex';
updateTotal();
}
function resetDD() {
['r', 'h', 'l', 'm'].forEach(level => {
const zb = document.getElementById('zb-' + level);
zb.querySelectorAll('.placed-tag').forEach(t => t.remove());
if (!zb.querySelector('.zone-ph')) {
const ph = document.createElement('span');
ph.className = 'zone-ph';
ph.textContent = 'Déposez ici';
zb.appendChild(ph);
}
});
document.querySelectorAll('.card').forEach(c => c.classList.remove('placed', 'dragging'));
Object.keys(placements).forEach(k => delete placements[k]);
// Reset score strip Exercice 4
document.getElementById('sc4').textContent = '-/5';
document.getElementById('sc4').className = 'sc-v';
clearResults();
saveChoices();
updateTotal();
}
</script>
</body>
</html>