fiche-classe-inversee-m5/fiche_classe_inversee_mercredi5.html

1986 lines
60 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fiche classe inversée Mercredi 5</title>
<!-- Tabler Icons CSS 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 (Red/Orange) */
--color-a-bg: #FCEBEB;
--color-a-border: #F09595;
--color-a-accent: #A32D2D;
--color-a-dark: #791F1F;
}
/* Header Right Container & Timer styles */
.header-right {
display: flex;
align-items: center;
gap: 16px;
flex-shrink: 0;
}
/* Timer Widget */
.timer-pill {
background: var(--primary-light);
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
padding: 8px 18px;
display: flex;
align-items: center;
gap: 16px;
box-shadow: var(--shadow-md);
transition: all 0.3s ease;
}
.timer-texts {
display: flex;
flex-direction: column;
}
.timer-label {
font-size: 0.65rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--primary-dark);
opacity: 0.8;
}
.timer-display {
font-size: 1.35rem;
font-weight: 900;
color: var(--primary-dark);
min-width: 60px;
line-height: 1.1;
text-align: center;
}
.timer-controls {
display: flex;
gap: 6px;
}
.tcbtn {
background: var(--bg-secondary);
border: 1px solid var(--color-border-secondary);
border-radius: 8px;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 0.95rem;
color: var(--color-text-primary);
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: var(--shadow-sm);
}
.tcbtn:hover {
background: var(--primary);
color: white;
border-color: var(--primary);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(117, 95, 236, 0.25);
}
.tcbtn:active {
transform: translateY(0);
}
@keyframes pulse-timer {
0% {
box-shadow: 0 0 0 0 hsla(247, 80%, 62%, 0.4);
}
70% {
box-shadow: 0 0 0 10px hsla(247, 80%, 62%, 0);
}
100% {
box-shadow: 0 0 0 0 hsla(247, 80%, 62%, 0);
}
}
.timer-pill.ticking {
animation: pulse-timer 2s infinite;
border-color: var(--primary);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-primary);
color: var(--color-text-primary);
font-family: 'Nunito', sans-serif;
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;
}
.fiche {
max-width: 960px;
width: 100%;
margin: 0 auto;
padding: 2.5rem 24px;
flex-grow: 1;
display: flex;
flex-direction: column;
}
/* Header */
.fiche-header {
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;
}
.fiche-kicker {
font-size: 0.75rem;
font-weight: 800;
letter-spacing: .2em;
text-transform: uppercase;
color: var(--primary);
margin-bottom: 8px;
}
.fiche-title {
font-size: 2rem;
font-weight: 900;
color: var(--color-text-primary);
line-height: 1.2;
letter-spacing: -0.02em;
}
.fiche-badge {
background: var(--primary-light);
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
padding: 10px 18px;
text-align: center;
flex-shrink: 0;
box-shadow: var(--shadow-sm);
}
.badge-top {
font-size: 0.65rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--primary-dark);
opacity: 0.8;
}
.badge-bottom {
font-size: 1.25rem;
font-weight: 900;
color: var(--primary-dark);
margin-top: 2px;
}
/* Identity input cards */
.identity-row {
display: grid;
grid-template-columns: 1fr 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);
}
.field-line {
border: none;
background: transparent;
font-family: 'DM Sans', sans-serif;
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;
}
/* Instructions & Reminder boxes */
.intro-block {
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;
box-shadow: var(--shadow-sm);
display: flex;
gap: 12px;
align-items: flex-start;
}
.intro-block i {
color: var(--primary);
font-size: 1.3rem;
flex-shrink: 0;
margin-top: 1px;
}
.intro-block p {
font-size: 0.9rem;
color: var(--color-text-secondary);
line-height: 1.6;
}
.intro-block strong {
color: var(--color-text-primary);
font-weight: 700;
}
.reminder-box {
background: var(--color-a-bg);
border: 1px solid var(--color-a-border);
border-left: 4px solid var(--color-a-accent);
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);
}
.reminder-box i {
color: var(--color-a-accent);
font-size: 1.3rem;
flex-shrink: 0;
margin-top: 1px;
}
.reminder-box p {
font-size: 0.9rem;
color: var(--color-a-dark);
line-height: 1.6;
}
.reminder-box strong {
color: #501313;
font-weight: 800;
}
/* Section Headers */
.section-title {
font-size: 0.85rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--primary);
margin: 2.5rem 0 1.5rem 0;
display: flex;
align-items: center;
gap: 10px;
}
.section-title i {
font-size: 1.2rem;
}
.section-title::after {
content: "";
flex: 1;
height: 1px;
background: var(--color-border-secondary);
opacity: 0.8;
}
/* Question Block Cards */
.question-block {
margin-bottom: 2rem;
background: var(--bg-secondary);
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-lg);
padding: 20px;
box-shadow: var(--shadow-sm);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.question-block:hover {
box-shadow: var(--shadow-md);
}
.q-header {
display: flex;
align-items: flex-start;
gap: 14px;
margin-bottom: 12px;
}
.q-num {
width: 28px;
height: 28px;
border-radius: 50%;
background: var(--primary-light);
border: 1px solid var(--color-border-secondary);
display: flex;
align-items: center;
justify-content: center;
font-size: 0.8rem;
font-weight: 800;
color: var(--primary-dark);
flex-shrink: 0;
margin-top: 1px;
box-shadow: var(--shadow-sm);
}
.q-text {
font-size: 0.95rem;
font-weight: 800;
color: var(--color-text-primary);
line-height: 1.5;
flex: 1;
letter-spacing: -0.01em;
}
.q-hint {
font-size: 0.825rem;
color: var(--color-text-secondary);
font-style: italic;
line-height: 1.5;
margin-left: 42px;
margin-bottom: 12px;
opacity: 0.85;
}
/* Textarea inputs */
.write-area {
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
background: var(--bg-primary);
width: 100%;
font-family: 'DM Sans', sans-serif;
font-size: 0.875rem;
color: var(--color-text-primary);
padding: 12px 16px;
resize: vertical;
outline: none;
line-height: 1.6;
transition: all 0.25s ease;
}
.write-area:focus {
border-color: var(--primary);
background: var(--bg-secondary);
box-shadow: 0 0 0 3px hsla(247, 80%, 62%, 0.12), var(--shadow-md);
}
.write-area::placeholder {
color: var(--color-text-tertiary);
font-style: italic;
opacity: 0.7;
}
/* Competence Cards */
.competence-card {
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
overflow: hidden;
background: var(--bg-secondary);
box-shadow: var(--shadow-sm);
margin-bottom: 16px;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.competence-card:hover {
box-shadow: var(--shadow-md);
}
.competence-card-header {
padding: 10px 16px;
display: flex;
align-items: center;
gap: 10px;
border-bottom: 1px solid var(--color-border-secondary);
}
.competence-card-header span {
font-size: 0.85rem;
font-weight: 800;
}
.competence-card-body {
padding: 16px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
.tc-wrap {
display: flex;
flex-direction: column;
gap: 6px;
}
.tc-lbl {
font-size: 0.7rem;
font-weight: 800;
letter-spacing: .05em;
text-transform: uppercase;
color: var(--color-text-secondary);
}
.ct-badge {
font-size: 0.75rem;
font-weight: 800;
padding: 4px 8px;
border-radius: 6px;
letter-spacing: 0.05em;
}
/* Competence header colors */
.c1-hdr {
background: #EEEDFE;
border-bottom-color: #AFA9EC;
color: #3C3489;
}
.c2-hdr {
background: #E1F5EE;
border-bottom-color: #5DCAA5;
color: #085041;
}
.c3-hdr {
background: #FCEBEB;
border-bottom-color: #F09595;
color: #791F1F;
}
.c4-hdr {
background: #E6F1FB;
border-bottom-color: #85B7EB;
color: #0C447C;
}
.c5-hdr {
background: #EAF3DE;
border-bottom-color: #97C459;
color: #27500A;
}
.c6-hdr {
background: #FAEEDA;
border-bottom-color: #EF9F27;
color: #633806;
}
/* Competence badge colors */
.bg-p {
background: #EEEDFE;
color: #3C3489;
border: 1px solid #AFA9EC;
}
.bg-t {
background: #E1F5EE;
color: #085041;
border: 1px solid #5DCAA5;
}
.bg-r {
background: #FCEBEB;
color: #791F1F;
border: 1px solid #F09595;
}
.bg-b {
background: #E6F1FB;
color: #0C447C;
border: 1px solid #85B7EB;
}
.bg-g {
background: #EAF3DE;
color: #27500A;
border: 1px solid #97C459;
}
.bg-a {
background: #FAEEDA;
color: #633806;
border: 1px solid #EF9F27;
}
/* Auto-evaluation grid styles */
.autoe-block {
background: var(--bg-secondary);
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-lg);
box-shadow: var(--shadow-sm);
margin-bottom: 2rem;
overflow: hidden;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.autoe-block:hover {
box-shadow: var(--shadow-md);
}
.autoe-head {
background: var(--primary-light);
border-bottom: 1px solid var(--color-border-secondary);
padding: 14px 20px;
display: flex;
align-items: center;
gap: 10px;
}
.autoe-head i {
color: var(--primary);
font-size: 1.25rem;
}
.autoe-lbl {
font-size: 0.8rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--primary-dark);
}
.autoe-body {
padding: 0;
background: var(--bg-secondary);
}
.comp-row {
border-bottom: 1px solid var(--color-border-secondary);
display: grid;
grid-template-columns: 58px 1.2fr 160px 1.5fr;
gap: 0;
align-items: stretch;
}
.comp-row:last-child {
border-bottom: none;
}
.comp-row.header {
background: var(--bg-tertiary);
}
.cr-num {
padding: 12px;
display: flex;
align-items: center;
justify-content: center;
border-right: 1px solid var(--color-border-secondary);
}
.cr-num.head span {
background: transparent;
border: none;
color: var(--color-text-secondary);
font-size: 0.7rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
}
.cr-comp {
padding: 16px;
border-right: 1px solid var(--color-border-secondary);
display: flex;
align-items: center;
}
.cr-comp-text {
font-size: 0.95rem;
font-weight: 800;
color: var(--color-text-primary);
line-height: 1.45;
}
.cr-comp-sub {
font-size: 0.75rem;
color: var(--color-text-secondary);
margin-top: 4px;
line-height: 1.4;
}
.cr-scale {
padding: 16px;
border-right: 1px solid var(--color-border-secondary);
display: flex;
align-items: center;
justify-content: center;
}
.cr-scale.head {
font-size: 0.7rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--color-text-secondary);
}
.stat-opts {
display: flex;
flex-direction: column;
gap: 8px;
width: 100%;
}
.stat-opt {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
}
.stat-opt input {
width: 16px;
height: 16px;
cursor: pointer;
}
.ig {
accent-color: #3B6D11;
}
.ia {
accent-color: #854F0B;
}
.ir {
accent-color: #A32D2D;
}
.stat-opt span {
font-size: 0.85rem;
font-weight: 700;
color: var(--color-text-secondary);
}
.cr-obs {
padding: 16px;
display: flex;
flex-direction: column;
justify-content: center;
}
.cr-obs.head {
font-size: 0.7rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--color-text-secondary);
}
.co-lbl {
font-size: 0.65rem;
font-weight: 800;
letter-spacing: .05em;
text-transform: uppercase;
color: var(--color-text-tertiary);
margin-bottom: 4px;
margin-top: 6px;
}
.co-lbl:first-child {
margin-top: 0;
}
.cr-obs-ta {
width: 100%;
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-sm);
background: var(--bg-primary);
font-family: 'DM Sans', sans-serif;
font-size: 0.8rem;
color: var(--color-text-primary);
padding: 6px 10px;
resize: vertical;
outline: none;
line-height: 1.4;
transition: all 0.25s ease;
}
.cr-obs-ta:focus {
border-color: var(--primary);
background: var(--bg-secondary);
box-shadow: 0 0 0 3px hsla(247, 80%, 62%, 0.12);
}
.cr-obs-ta::placeholder {
color: var(--color-text-tertiary);
font-style: italic;
}
.synth-row {
padding: 16px 20px;
background: var(--bg-tertiary);
border-top: 1px solid var(--color-border-secondary);
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
.sr-col {
display: flex;
flex-direction: column;
gap: 6px;
}
.sr-lbl {
font-size: 0.7rem;
font-weight: 800;
letter-spacing: .05em;
text-transform: uppercase;
color: var(--color-text-secondary);
}
/* Confidence / Stress level tag group */
.level-row {
display: flex;
gap: 10px;
margin-left: 42px;
margin-top: 12px;
margin-bottom: 12px;
flex-wrap: wrap;
}
.level-opt {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
background: var(--bg-primary);
border: 1px solid var(--color-border-secondary);
border-radius: 20px;
padding: 8px 16px;
transition: all 0.2s ease;
}
.level-opt:hover {
border-color: var(--primary);
background: var(--primary-light);
}
.level-opt input[type="radio"] {
accent-color: var(--primary);
width: 16px;
height: 16px;
cursor: pointer;
}
.level-opt span {
font-size: 0.85rem;
font-weight: 700;
color: var(--color-text-primary);
}
/* Footer Strip */
.footer-strip {
display: flex;
align-items: center;
justify-content: space-between;
border-top: 1px solid var(--color-border-secondary);
padding-top: 1.5rem;
margin-top: 3rem;
gap: 1.5rem;
flex-wrap: wrap;
}
.footer-note {
font-size: 0.85rem;
color: var(--color-text-secondary);
font-style: italic;
line-height: 1.5;
flex: 1;
max-width: 60%;
}
.footer-btns {
display: flex;
gap: 8px;
}
.print-btn {
font-family: 'Nunito', sans-serif;
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;
white-space: nowrap;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: var(--shadow-sm);
}
.print-btn:hover {
background: var(--primary-dark);
border-color: var(--primary-dark);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(117, 95, 236, 0.25);
}
.print-btn:active {
transform: translateY(0);
}
/* Accessibility Utilities */
.sr-only {
position: absolute !important;
width: 1px !important;
height: 1px !important;
padding: 0 !important;
margin: -1px !important;
overflow: hidden !important;
clip: rect(0, 0, 0, 0) !important;
white-space: nowrap !important;
border: 0 !important;
}
/* Signature Section Styles */
.signature-block {
background: var(--bg-secondary);
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-lg);
padding: 24px;
box-shadow: var(--shadow-sm);
margin-bottom: 2rem;
transition: box-shadow 0.2s ease;
}
.signature-block:hover {
box-shadow: var(--shadow-md);
}
.signature-grid {
display: grid;
grid-template-columns: 1.5fr 1fr;
gap: 24px;
}
.signature-col {
display: flex;
flex-direction: column;
gap: 12px;
}
.signature-label {
font-size: 0.75rem;
font-weight: 800;
letter-spacing: .05em;
text-transform: uppercase;
color: var(--color-text-secondary);
}
.signature-pad-wrapper {
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
background: var(--bg-primary);
padding: 12px;
display: flex;
flex-direction: column;
gap: 12px;
transition: all 0.25s ease;
}
.signature-pad-wrapper:focus-within {
border-color: var(--primary);
box-shadow: 0 0 0 3px hsla(247, 80%, 62%, 0.12);
}
.signature-pad {
width: 100%;
height: 180px;
background: #ffffff;
border-radius: var(--border-radius-sm);
border: 1px dashed var(--color-border-secondary);
cursor: crosshair;
touch-action: none;
}
.signature-pad-controls {
display: flex;
gap: 10px;
justify-content: flex-end;
}
.signature-btn {
font-family: 'Nunito', sans-serif;
font-size: 0.75rem;
font-weight: 700;
letter-spacing: .03em;
text-transform: uppercase;
background: var(--bg-secondary);
border: 1px solid var(--color-border-secondary);
color: var(--color-text-secondary);
border-radius: 8px;
padding: 8px 14px;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 6px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: var(--shadow-sm);
}
.signature-btn:hover {
background: var(--bg-tertiary);
color: var(--color-text-primary);
transform: translateY(-1px);
}
.signature-btn.clear:hover {
background: #fee2e2;
color: #ef4444;
border-color: #fca5a5;
box-shadow: 0 2px 4px rgba(239, 68, 68, 0.1);
}
.signature-btn.save {
background: var(--primary);
border-color: var(--primary);
color: white;
}
.signature-btn.save:hover {
background: var(--primary-dark);
border-color: var(--primary-dark);
box-shadow: 0 4px 8px rgba(117, 95, 236, 0.25);
}
.date-col {
justify-content: space-between;
}
.signature-info-box {
background: var(--primary-light);
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
padding: 16px;
display: flex;
gap: 12px;
align-items: flex-start;
}
.signature-info-box i {
color: var(--primary);
font-size: 1.25rem;
flex-shrink: 0;
margin-top: 2px;
}
.signature-info-box p {
font-size: 0.8rem;
color: var(--color-text-secondary);
line-height: 1.5;
}
/* Responsive CSS Overrides */
@media (max-width: 860px) {
.fiche {
padding: 1.5rem 16px;
}
.fiche-header {
flex-direction: column;
align-items: stretch;
gap: 1rem;
}
.header-right {
flex-direction: row;
justify-content: space-between;
width: 100%;
gap: 12px;
}
.identity-row {
grid-template-columns: 1fr;
gap: 12px;
}
.comp-row {
grid-template-columns: 1fr;
border-bottom: 2px solid var(--color-border-secondary);
}
.comp-row.header {
display: none;
}
.cr-num {
border-right: none;
border-bottom: 1px solid var(--color-border-secondary);
justify-content: flex-start;
background: var(--bg-tertiary);
padding: 8px 12px;
}
.cr-comp {
border-right: none;
border-bottom: 1px solid var(--color-border-secondary);
}
.cr-scale {
border-right: none;
border-bottom: 1px solid var(--color-border-secondary);
justify-content: flex-start;
padding: 12px;
}
.cr-obs {
padding: 12px;
}
.synth-row {
grid-template-columns: 1fr;
}
.level-row {
margin-left: 0;
flex-direction: column;
align-items: stretch;
gap: 8px;
}
.level-opt {
width: 100%;
}
.q-hint {
margin-left: 0;
}
.signature-grid {
grid-template-columns: 1fr;
gap: 16px;
}
.date-col {
gap: 16px;
}
.footer-strip {
flex-direction: column;
align-items: flex-start;
gap: 1rem;
}
.footer-note {
max-width: 100%;
}
.footer-btns {
flex-direction: column;
width: 100%;
gap: 8px;
}
.footer-btns button {
width: 100%;
justify-content: center;
}
}
/* Print Styles Overrides */
@media print {
body {
background: white !important;
color: black !important;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.print-btn,
.timer-pill,
.signature-pad-controls {
display: none !important;
}
.question-block,
.competence-card,
.autoe-block,
.signature-block {
page-break-inside: avoid;
border: 1px solid #94a3b8 !important;
background: white !important;
box-shadow: none !important;
}
.write-area,
.cr-obs-ta {
background: white !important;
border: 1px solid #94a3b8 !important;
resize: none;
}
.level-opt,
.id-field,
.signature-info-box {
border: 1px solid #94a3b8 !important;
background: white !important;
box-shadow: none !important;
}
.signature-pad {
border: 1px solid #94a3b8 !important;
background: white !important;
}
}
</style>
</head>
<body>
<div class="fiche">
<!-- Accessibility Hidden Title -->
<h2 class="sr-only">Fiche classe inversée à compléter avant le Mercredi 5 - dernière séance du parcours, relecture
grille critères C1 à C6, préparation d'une bonne réponse par compétence, autoévaluation à blanc avec statut acquis
en cours à réviser, identification des deux points faibles prioritaires</h2>
<!-- Header -->
<div class="fiche-header">
<div class="header-left">
<div class="fiche-kicker">Formation de formateurs IA-PRO · Classe inversée · Séance 5/5 - Dernière</div>
<div class="fiche-title">Fiche de préparation<br>Mercredi 5 - Entraînement certification</div>
</div>
<div class="header-right">
<!-- Estimated duration badge -->
<div class="fiche-badge">
<div class="badge-top">Durée estimée</div>
<div class="badge-bottom">~1h00</div>
</div>
<!-- Timer widget -->
<div class="timer-pill" id="timer-widget">
<div class="timer-texts">
<span class="timer-label">Minuteur préparation</span>
<span class="timer-display" id="timer-display">60:00</span>
</div>
<div class="timer-controls">
<button class="tcbtn" onclick="startTimer()" aria-label="Démarrer le minuteur">
<i class="ti ti-player-play" aria-hidden="true"></i>
</button>
<button class="tcbtn" onclick="pauseTimer()" aria-label="Pause">
<i class="ti ti-player-pause" aria-hidden="true"></i>
</button>
<button class="tcbtn" onclick="resetTimer()" aria-label="Réinitialiser">
<i class="ti ti-refresh" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
<!-- Identity card row -->
<div class="identity-row">
<div class="id-field">
<span class="field-label">Prénom & nom</span>
<input class="field-line" type="text" placeholder="Votre nom" aria-label="Prénom et nom" />
</div>
<div class="id-field">
<span class="field-label">Date de la séance</span>
<input class="field-line" type="text" placeholder="Mercredi __/__/____" aria-label="Date de la séance" />
</div>
<div class="id-field">
<span class="field-label">Complétée le</span>
<input class="field-line" type="text" placeholder="__/__/____" aria-label="Complétée le" />
</div>
</div>
<!-- Informative Intro Block -->
<div class="intro-block">
<i class="ti ti-book" aria-hidden="true"></i>
<p>Cette fiche a deux parties. La <strong>partie 1</strong> vous demande de relire la grille critères et de
préparer une phrase résumant ce que le jury évalue pour chaque compétence. La <strong>partie 2</strong> est
votre autoévaluation à blanc - à compléter seul, sans complaisance. C'est elle qui structure le débrief
collectif en début de séance.</p>
</div>
<!-- Warning Reminder capsule -->
<div class="reminder-box" aria-label="Conseil important">
<i class="ti ti-flag" aria-hidden="true"></i>
<p><strong>C'est la dernière classe inversée du parcours.</strong> Ce que vous préparez ici conditionne
directement votre plan d'action avant l'épreuve. L'heure investie maintenant vaut plus que 3 heures de révision
à l'aveugle.</p>
</div>
<!-- PART 1 -->
<div class="section-title">
<i class="ti ti-list-check" aria-hidden="true"></i>Partie 1 - Relecture de la grille critères
</div>
<!-- Question 1 -->
<div class="question-block">
<div class="q-header">
<div class="q-num">1</div>
<div class="q-text">Relisez la grille Critères-IA. Pour chaque compétence, rédigez en 1 phrase ce que le jury
évalue - avec vos propres mots, pas ceux du référentiel.</div>
</div>
<p class="q-hint">L'objectif n'est pas de mémoriser - c'est de reformuler pour vérifier que vous avez vraiment
compris. Si vous ne pouvez pas le dire avec vos mots, vous ne pourrez pas le démontrer en situation.</p>
<!-- Competence Cards Container -->
<div style="display:flex;flex-direction:column;gap:12px;margin-top:16px;">
<!-- C1 -->
<div class="competence-card">
<div class="competence-card-header c1-hdr">
<span class="ct-badge bg-p">C1</span>
<span>Utiliser les outils IA générative · Cr1.1 à Cr1.3</span>
</div>
<div class="competence-card-body">
<div class="tc-wrap">
<span class="tc-lbl">Ce que le jury évalue (vos mots)</span>
<textarea class="write-area" rows="2"
placeholder="Ex. : Le jury vérifie que je sais identifier ce qu'une IA peut ou ne peut pas faire dans un contexte pro donné, et que je justifie mes choix d'outils de façon cohérente…"
aria-label="C1 reformulation"></textarea>
</div>
<div class="tc-wrap">
<span class="tc-lbl">Un exemple de bonne réponse issu de mes passages</span>
<textarea class="write-area" rows="2"
placeholder="Ce que j'ai dit ou fait en séance 2, 3 ou 4 qui illustre cette compétence…"
aria-label="C1 exemple"></textarea>
</div>
</div>
</div>
<!-- C2 -->
<div class="competence-card">
<div class="competence-card-header c2-hdr">
<span class="ct-badge bg-t">C2</span>
<span>Prompt engineering · Cr2.1 à Cr2.3</span>
</div>
<div class="competence-card-body">
<div class="tc-wrap">
<span class="tc-lbl">Ce que le jury évalue (vos mots)</span>
<textarea class="write-area" rows="2"
placeholder="Ex. : Le jury ne cherche pas le prompt parfait - il cherche à voir que je structure mon raisonnement ROCCO et que j'itère…"
aria-label="C2 reformulation"></textarea>
</div>
<div class="tc-wrap">
<span class="tc-lbl">Un exemple de bonne réponse</span>
<textarea class="write-area" rows="2" placeholder="Ce que j'ai dit ou fait qui illustre C2…"
aria-label="C2 exemple"></textarea>
</div>
</div>
</div>
<!-- C3 -->
<div class="competence-card">
<div class="competence-card-header c3-hdr">
<span class="ct-badge bg-r">C3</span>
<span>Sécuriser l'usage IA · Cr3.1 à Cr3.3</span>
</div>
<div class="competence-card-body">
<div class="tc-wrap">
<span class="tc-lbl">Ce que le jury évalue (vos mots)</span>
<textarea class="write-area" rows="2"
placeholder="Ex. : Le jury teste que je sais reformuler les risques RGPD sans jargon juridique, et que je renvoie vers le DPO au bon moment…"
aria-label="C3 reformulation"></textarea>
</div>
<div class="tc-wrap">
<span class="tc-lbl">Un exemple de bonne réponse</span>
<textarea class="write-area" rows="2" placeholder="Ce que j'ai dit ou fait qui illustre C3…"
aria-label="C3 exemple"></textarea>
</div>
</div>
</div>
<!-- C4 -->
<div class="competence-card">
<div class="competence-card-header c4-hdr">
<span class="ct-badge bg-b">C4</span>
<span>Contenus inclusifs · Cr4.1 à Cr4.3</span>
</div>
<div class="competence-card-body">
<div class="tc-wrap">
<span class="tc-lbl">Ce que le jury évalue (vos mots)</span>
<textarea class="write-area" rows="2"
placeholder="Ex. : Le jury vérifie que je sais nommer les standards précis (WCAG, FALC) dans mes prompts - pas juste 'rendre accessible'…"
aria-label="C4 reformulation"></textarea>
</div>
<div class="tc-wrap">
<span class="tc-lbl">Un exemple de bonne réponse</span>
<textarea class="write-area" rows="2" placeholder="Ce que j'ai dit ou fait qui illustre C4…"
aria-label="C4 exemple"></textarea>
</div>
</div>
</div>
<!-- C5 -->
<div class="competence-card">
<div class="competence-card-header c5-hdr">
<span class="ct-badge bg-g">C5</span>
<span>Optimiser les contenus IA · Cr5.1 & Cr5.2</span>
</div>
<div class="competence-card-body">
<div class="tc-wrap">
<span class="tc-lbl">Ce que le jury évalue (vos mots)</span>
<textarea class="write-area" rows="2"
placeholder="Ex. : Le jury évalue ma capacité à guider l'IA pour améliorer un contenu - pas à le réécrire moi-même…"
aria-label="C5 reformulation"></textarea>
</div>
<div class="tc-wrap">
<span class="tc-lbl">Un exemple de bonne réponse</span>
<textarea class="write-area" rows="2" placeholder="Ce que j'ai dit ou fait qui illustre C5…"
aria-label="C5 exemple"></textarea>
</div>
</div>
</div>
<!-- C6 -->
<div class="competence-card">
<div class="competence-card-header c6-hdr">
<span class="ct-badge bg-a">C6</span>
<span>Posture éthique · Cr6.1 à Cr6.3</span>
</div>
<div class="competence-card-body">
<div class="tc-wrap">
<span class="tc-lbl">Ce que le jury évalue (vos mots)</span>
<textarea class="write-area" rows="2"
placeholder="Ex. : Le jury teste que je sais animer un débat sur les biais sans prendre parti - et que je distingue risque élevé d'interdit…"
aria-label="C6 reformulation"></textarea>
</div>
<div class="tc-wrap">
<span class="tc-lbl">Un exemple de bonne réponse</span>
<textarea class="write-area" rows="2" placeholder="Ce que j'ai dit ou fait qui illustre C6…"
aria-label="C6 exemple"></textarea>
</div>
</div>
</div>
</div>
</div>
<!-- PART 2 -->
<div class="section-title">
<i class="ti ti-chart-radar" aria-hidden="true"></i>Partie 2 - Autoévaluation à blanc (avant la séance)
</div>
<p
style="font-size: 0.95rem; color: var(--color-text-secondary); line-height: 1.6; margin-bottom: 1.5rem; margin-top: -0.5rem;">
Pour chaque compétence : un statut honnête + le piège jury qui vous menace le plus + ce que vous ferez
concrètement avant l'épreuve. Cette grille sera le point de départ du débrief collectif en séance.</p>
<!-- Auto-evaluation block -->
<div class="autoe-block">
<div class="autoe-head">
<i class="ti ti-adjustments" aria-hidden="true"></i>
<span class="autoe-lbl">Autoévaluation C1 à C6 - avant le passage</span>
</div>
<div class="autoe-body">
<div class="comp-row header">
<div class="cr-num head"><span></span></div>
<div class="cr-comp" style="padding: 8px 12px;">
<span
style="font-size: 0.7rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--color-text-secondary);">Compétence</span>
</div>
<div class="cr-scale head">Mon statut</div>
<div class="cr-obs head">Piège jury + action avant l'épreuve</div>
</div>
<!-- C1 -->
<div class="comp-row">
<div class="cr-num"><span class="ct-badge bg-p">C1</span></div>
<div class="cr-comp">
<div>
<div class="cr-comp-text">Outils IA</div>
<div class="cr-comp-sub">Sélectionner & justifier selon le contexte</div>
</div>
</div>
<div class="cr-scale" role="radiogroup" aria-label="C1">
<div class="stat-opts">
<label class="stat-opt"><input type="radio" name="st1" value="Acquise"
class="ig"><span>Acquise</span></label>
<label class="stat-opt"><input type="radio" name="st1" value="En cours" class="ia"><span>En
cours</span></label>
<label class="stat-opt"><input type="radio" name="st1" value="À réviser" class="ir"><span>À
réviser</span></label>
</div>
</div>
<div class="cr-obs">
<span class="co-lbl">Le piège qui me menace</span>
<textarea class="cr-obs-ta" rows="2"
placeholder="Ex. : Oublier le RGPD dans la justification d'un outil avec données clients…"
aria-label="C1 piège"></textarea>
<span class="co-lbl">Ce que je fais avant l'épreuve</span>
<textarea class="cr-obs-ta" rows="2"
placeholder="Ex. : Réviser les 3 critères de sélection (contexte / RGPD / intégration) et m'entraîner à les citer naturellement…"
aria-label="C1 action"></textarea>
</div>
</div>
<!-- C2 -->
<div class="comp-row">
<div class="cr-num"><span class="ct-badge bg-t">C2</span></div>
<div class="cr-comp">
<div>
<div class="cr-comp-text">Prompt ROCCO</div>
<div class="cr-comp-sub">Structurer, itérer, commenter</div>
</div>
</div>
<div class="cr-scale" role="radiogroup" aria-label="C2">
<div class="stat-opts">
<label class="stat-opt"><input type="radio" name="st2" value="Acquise"
class="ig"><span>Acquise</span></label>
<label class="stat-opt"><input type="radio" name="st2" value="En cours" class="ia"><span>En
cours</span></label>
<label class="stat-opt"><input type="radio" name="st2" value="À réviser" class="ir"><span>À
réviser</span></label>
</div>
</div>
<div class="cr-obs">
<span class="co-lbl">Le piège qui me menace</span>
<textarea class="cr-obs-ta" rows="2"
placeholder="Ex. : Présenter directement ma meilleure version sans montrer l'itération…"
aria-label="C2 piège"></textarea>
<span class="co-lbl">Ce que je fais avant l'épreuve</span>
<textarea class="cr-obs-ta" rows="2"
placeholder="Ex. : M'entraîner à commenter à voix haute chaque ajout : 'j'ajoute le contexte parce que…'"
aria-label="C2 action"></textarea>
</div>
</div>
<!-- C3 -->
<div class="comp-row">
<div class="cr-num"><span class="ct-badge bg-r">C3</span></div>
<div class="cr-comp">
<div>
<div class="cr-comp-text">Sécurité RGPD</div>
<div class="cr-comp-sub">Identifier, pseudonymiser, renvoyer au DPO</div>
</div>
</div>
<div class="cr-scale" role="radiogroup" aria-label="C3">
<div class="stat-opts">
<label class="stat-opt"><input type="radio" name="st3" value="Acquise"
class="ig"><span>Acquise</span></label>
<label class="stat-opt"><input type="radio" name="st3" value="En cours" class="ia"><span>En
cours</span></label>
<label class="stat-opt"><input type="radio" name="st3" value="À réviser" class="ir"><span>À
réviser</span></label>
</div>
</div>
<div class="cr-obs">
<span class="co-lbl">Le piège qui me menace</span>
<textarea class="cr-obs-ta" rows="2"
placeholder="Ex. : Répondre à une question juridique précise au lieu de renvoyer vers le DPO…"
aria-label="C3 piège"></textarea>
<span class="co-lbl">Ce que je fais avant l'épreuve</span>
<textarea class="cr-obs-ta" rows="2"
placeholder="Ex. : Mémoriser la formule exacte : 'Ce n'est pas mon rôle de vous conseiller - consultez votre DPO'…"
aria-label="C3 action"></textarea>
</div>
</div>
<!-- C4 -->
<div class="comp-row">
<div class="cr-num"><span class="ct-badge bg-b">C4</span></div>
<div class="cr-comp">
<div>
<div class="cr-comp-text">Contenus inclusifs</div>
<div class="cr-comp-sub">WCAG, FALC, déficiences visuelles & auditives</div>
</div>
</div>
<div class="cr-scale" role="radiogroup" aria-label="C4">
<div class="stat-opts">
<label class="stat-opt"><input type="radio" name="st4" value="Acquise"
class="ig"><span>Acquise</span></label>
<label class="stat-opt"><input type="radio" name="st4" value="En cours" class="ia"><span>En
cours</span></label>
<label class="stat-opt"><input type="radio" name="st4" value="À réviser" class="ir"><span>À
réviser</span></label>
</div>
</div>
<div class="cr-obs">
<span class="co-lbl">Le piège qui me menace</span>
<textarea class="cr-obs-ta" rows="2"
placeholder="Ex. : Confondre 'langage simple' et FALC dans mes prompts…" aria-label="C4 piège"></textarea>
<span class="co-lbl">Ce que je fais avant l'épreuve</span>
<textarea class="cr-obs-ta" rows="2"
placeholder="Ex. : Relire la définition FALC vs WCAG et préparer 1 exemple de prompt qui nomme le standard explicitement…"
aria-label="C4 action"></textarea>
</div>
</div>
<!-- C5 -->
<div class="comp-row">
<div class="cr-num"><span class="ct-badge bg-g">C5</span></div>
<div class="cr-comp">
<div>
<div class="cr-comp-text">Optimisation contenus</div>
<div class="cr-comp-sub">Diagnostiquer, guider l'IA, ne pas réécrire soi-même</div>
</div>
</div>
<div class="cr-scale" role="radiogroup" aria-label="C5">
<div class="stat-opts">
<label class="stat-opt"><input type="radio" name="st5" value="Acquise"
class="ig"><span>Acquise</span></label>
<label class="stat-opt"><input type="radio" name="st5" value="En cours" class="ia"><span>En
cours</span></label>
<label class="stat-opt"><input type="radio" name="st5" value="À réviser" class="ir"><span>À
réviser</span></label>
</div>
</div>
<div class="cr-obs">
<span class="co-lbl">Le piège qui me menace</span>
<textarea class="cr-obs-ta" rows="2"
placeholder="Ex. : Réécrire le contenu moi-même au lieu de passer par un prompt de correction…"
aria-label="C5 piège"></textarea>
<span class="co-lbl">Ce que je fais avant l'épreuve</span>
<textarea class="cr-obs-ta" rows="2"
placeholder="Ex. : M'entraîner sur 1 exemple : diagnostiquer les défauts → rédiger le prompt de correction → comparer avant/après…"
aria-label="C5 action"></textarea>
</div>
</div>
<!-- C6 -->
<div class="comp-row">
<div class="cr-num"><span class="ct-badge bg-a">C6</span></div>
<div class="cr-comp">
<div>
<div class="cr-comp-text">Posture éthique</div>
<div class="cr-comp-sub">Biais, IA Act, sobriété - faciliter sans prendre parti</div>
</div>
</div>
<div class="cr-scale" role="radiogroup" aria-label="C6">
<div class="stat-opts">
<label class="stat-opt"><input type="radio" name="st6" value="Acquise"
class="ig"><span>Acquise</span></label>
<label class="stat-opt"><input type="radio" name="st6" value="En cours" class="ia"><span>En
cours</span></label>
<label class="stat-opt"><input type="radio" name="st6" value="À réviser" class="ir"><span>À
réviser</span></label>
</div>
</div>
<div class="cr-obs">
<span class="co-lbl">Le piège qui me menace</span>
<textarea class="cr-obs-ta" rows="2"
placeholder="Ex. : Confondre 'risque élevé IA Act' et 'interdit' - ou moraliser sur la sobriété…"
aria-label="C6 piège"></textarea>
<span class="co-lbl">Ce que je fais avant l'épreuve</span>
<textarea class="cr-obs-ta" rows="2"
placeholder="Ex. : Mémoriser : risque élevé = autorisé avec obligations. Préparer 1 formule sobre sur la sobriété numérique…"
aria-label="C6 action"></textarea>
</div>
</div>
</div>
<!-- Synthesis row inside auto-evaluation card -->
<div class="synth-row">
<div class="sr-col">
<span class="sr-lbl">Mes 2 compétences à statut "à réviser" - priorité absolue</span>
<textarea class="write-area" rows="3"
placeholder="Nommez-les ici. Ce sont elles qui ouvriront le débrief collectif en séance."
aria-label="Priorités à réviser"></textarea>
</div>
<div class="sr-col">
<span class="sr-lbl">Ma compétence la plus solide - celle sur laquelle je m'appuie</span>
<textarea class="write-area" rows="3"
placeholder="Celle que vous pouvez mobiliser sous pression, avec un exemple concret ancré dans les séances passées…"
aria-label="Compétence solide"></textarea>
</div>
</div>
</div>
<!-- PART 3 -->
<div class="section-title">
<i class="ti ti-mood-check" aria-hidden="true"></i>Partie 3 - Positionnement avant la dernière séance
</div>
<!-- Question 2 -->
<div class="question-block">
<div class="q-header">
<div class="q-num">2</div>
<div class="q-text">Comment vous sentez-vous par rapport à l'épreuve de certification - par rapport à comment
vous vous sentiez au début du parcours ?</div>
</div>
<div class="level-row" role="radiogroup" aria-label="Positionnement par rapport au début">
<label class="level-opt"><input type="radio" name="pos" value="1"><span>Beaucoup moins
confiant(e)</span></label>
<label class="level-opt"><input type="radio" name="pos" value="2"><span>Un peu moins confiant(e)</span></label>
<label class="level-opt"><input type="radio" name="pos" value="3"><span>Pareil</span></label>
<label class="level-opt"><input type="radio" name="pos" value="4"><span>Plus confiant(e)</span></label>
<label class="level-opt"><input type="radio" name="pos" value="5"><span>Beaucoup plus confiant(e)</span></label>
</div>
<textarea class="write-area" rows="2" style="margin-top:12px;"
placeholder="Ce qui explique cette évolution - un moment précis du parcours qui a changé quelque chose…"
aria-label="Évolution du positionnement"></textarea>
</div>
<!-- Question 3 -->
<div class="question-block">
<div class="q-header">
<div class="q-num">3</div>
<div class="q-text">Si vous deviez retenir une seule chose de ce parcours de 5 mercredis avant l'épreuve - une
conviction, une méthode, une posture - laquelle serait-ce ?</div>
</div>
<p class="q-hint">Pas la plus technique. La plus utile sous pression.</p>
<textarea class="write-area" rows="3"
placeholder="Ex. : Que la bonne réponse n'est pas toujours la plus complète - c'est celle qui montre mon raisonnement clairement."
aria-label="Une chose à retenir"></textarea>
</div>
<!-- PART 4 -->
<div class="section-title">
<i class="ti ti-edit" aria-hidden="true"></i>Partie 4 - Validation &amp; Signature
</div>
<!-- Signature Block -->
<div class="signature-block">
<div class="signature-grid">
<div class="signature-col">
<div class="signature-label">Signature</div>
<div class="signature-pad-wrapper">
<canvas class="signature-pad" id="signature-pad"></canvas>
<div class="signature-pad-controls">
<button type="button" class="signature-btn clear" onclick="clearSignature()">
<i class="ti ti-trash" aria-hidden="true"></i> Effacer
</button>
<button type="button" class="signature-btn save" onclick="saveSignature()">
<i class="ti ti-circle-check" aria-hidden="true"></i> Enregistrer
</button>
</div>
</div>
</div>
<div class="signature-col date-col">
<div class="id-field">
<span class="field-label">Date de signature</span>
<input type="text" class="field-line" placeholder="__/__/____" id="signature-date" />
</div>
<div class="signature-info-box">
<i class="ti ti-info-circle" aria-hidden="true"></i>
<p>Cette signature atteste que vous avez complété cette fiche et préparé vos révisions et votre
autoévaluation pour le Mercredi 5.</p>
</div>
</div>
</div>
</div>
<!-- Footer strip with clear and print buttons -->
<div class="footer-strip">
<div class="footer-note">À apporter en séance. La partie 2 (autoévaluation) est votre contribution au débrief
collectif - vos 2 points "à réviser" structurent la séance. La partie 3 reste personnelle.</div>
<div class="footer-btns">
<button class="signature-btn clear" onclick="clearAll()">
<i class="ti ti-eraser" aria-hidden="true"></i> Effacer toutes les saisies
</button>
<button class="print-btn" onclick="window.print()">
<i class="ti ti-printer" aria-hidden="true"></i>Imprimer la fiche
</button>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
const canvas = document.getElementById('signature-pad');
const ctx = canvas.getContext('2d');
let isDrawing = false;
let lastX = 0;
let lastY = 0;
let ratio = Math.max(window.devicePixelRatio || 1, 1);
// Fonction optimisée pour le redimensionnement du canvas
function resizeCanvas() {
const rect = canvas.getBoundingClientRect();
canvas.width = rect.width * ratio;
canvas.height = rect.height * ratio;
canvas.style.width = rect.width + 'px';
canvas.style.height = rect.height + 'px';
ctx.scale(ratio, ratio);
ctx.lineWidth = 2;
ctx.lineCap = 'round';
ctx.strokeStyle = '#0f172a';
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
// Initialisation du canvas
function initCanvas() {
// Utilisation de ResizeObserver pour une meilleure gestion du redimensionnement
const resizeObserver = new ResizeObserver(() => {
resizeCanvas();
// Recharger la signature après redimensionnement
const savedSignature = localStorage.getItem('signatureData_m5');
if (savedSignature) {
const img = new Image();
img.onload = function () {
ctx.drawImage(img, 0, 0, canvas.width / ratio, canvas.height / ratio);
};
img.src = savedSignature;
}
});
resizeObserver.observe(canvas);
resizeCanvas();
}
// Fonctions de dessin optimisées
function startDrawing(e) {
isDrawing = true;
const rect = canvas.getBoundingClientRect();
lastX = (e.clientX || e.touches[0].clientX) - rect.left;
lastY = (e.clientY || e.touches[0].clientY) - rect.top;
}
function draw(e) {
if (!isDrawing) return;
const rect = canvas.getBoundingClientRect();
const currentX = (e.clientX || e.touches[0].clientX) - rect.left;
const currentY = (e.clientY || e.touches[0].clientY) - rect.top;
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(currentX, currentY);
ctx.stroke();
[lastX, lastY] = [currentX, currentY];
}
// Gestion des événements avec dessin
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', () => { isDrawing = false; });
canvas.addEventListener('mouseout', () => { isDrawing = false; });
canvas.addEventListener('touchstart', function (e) {
e.preventDefault();
startDrawing(e);
}, { passive: false });
canvas.addEventListener('touchmove', function (e) {
e.preventDefault();
draw(e);
}, { passive: false });
canvas.addEventListener('touchend', () => { isDrawing = false; });
// Fonctions de gestion de la signature
window.clearSignature = function () {
ctx.clearRect(0, 0, canvas.width, canvas.height);
localStorage.removeItem('signatureData_m5');
};
window.saveSignature = function () {
const signatureData = canvas.toDataURL('image/png');
localStorage.setItem('signatureData_m5', signatureData);
return signatureData;
};
// Chargement de la signature sauvegardée
const savedSignature = localStorage.getItem('signatureData_m5');
if (savedSignature) {
const img = new Image();
img.onload = function () {
ctx.drawImage(img, 0, 0, canvas.width / ratio, canvas.height / ratio);
};
img.src = savedSignature;
}
// Gestion de la date de signature
const signatureDate = document.getElementById('signature-date');
const savedDate = localStorage.getItem('signatureDate_m5');
if (savedDate) signatureDate.value = savedDate;
signatureDate.addEventListener('input', () => {
localStorage.setItem('signatureDate_m5', signatureDate.value);
});
// Initialisation finale
initCanvas();
});
</script>
<!-- Active Auto-save script -->
<script>
// Auto-save & Load for Textareas
const textareas = document.querySelectorAll('textarea');
textareas.forEach((t, index) => {
const savedVal = localStorage.getItem(`textarea_fiche_m5_${index}`);
if (savedVal) t.value = savedVal;
t.addEventListener('input', () => {
localStorage.setItem(`textarea_fiche_m5_${index}`, t.value);
});
});
// Auto-save & Load for Text Inputs
const textInputs = document.querySelectorAll('input[type="text"]');
textInputs.forEach((input, index) => {
// Exclude signature date to avoid double saving/loading clash
if (input.id === 'signature-date') return;
const savedVal = localStorage.getItem(`input_fiche_m5_${index}`);
if (savedVal) input.value = savedVal;
input.addEventListener('input', () => {
localStorage.setItem(`input_fiche_m5_${index}`, input.value);
});
});
// Auto-save & Load for Radio Inputs
const radios = document.querySelectorAll('input[type="radio"]');
radios.forEach((radio) => {
const name = radio.name;
const savedVal = localStorage.getItem(`radio_fiche_m5_${name}`);
if (savedVal && radio.value === savedVal) {
radio.checked = true;
}
radio.addEventListener('change', () => {
localStorage.setItem(`radio_fiche_m5_${name}`, radio.value);
});
});
// Clear All Function
window.clearAll = function () {
if (!confirm('Effacer toutes les saisies de cette fiche ?')) return;
document.querySelectorAll('textarea').forEach(t => t.value = '');
document.querySelectorAll('.field-line').forEach(i => i.value = '');
document.querySelectorAll('input[type=radio]').forEach(r => r.checked = false);
if (typeof clearSignature === 'function') {
clearSignature();
}
// Clean signature date field
const sigDateEl = document.getElementById('signature-date');
if (sigDateEl) sigDateEl.value = '';
// Remove from localStorage
const keysToRemove = [];
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key && (key.startsWith('textarea_fiche_m5_') || key.startsWith('input_fiche_m5_') || key.startsWith('radio_fiche_m5_') || key === 'signatureData_m5' || key === 'signatureDate_m5')) {
keysToRemove.push(key);
}
}
keysToRemove.forEach(k => localStorage.removeItem(k));
};
// Timer Logic (60 minutes)
let secs = 3600, interval = null;
function fmt(s) {
const m = Math.floor(s / 60), ss = s % 60;
return String(m).padStart(2, '0') + ':' + String(ss).padStart(2, '0');
}
function render() {
document.getElementById('timer-display').textContent = fmt(secs);
}
function startTimer() {
if (interval) return;
document.getElementById('timer-widget').classList.add('ticking');
interval = setInterval(() => {
if (secs <= 0) {
clearInterval(interval);
interval = null;
document.getElementById('timer-widget').classList.remove('ticking');
document.getElementById('timer-display').textContent = 'Temps !';
return;
}
secs--;
render();
}, 1000);
}
function pauseTimer() {
clearInterval(interval);
interval = null;
document.getElementById('timer-widget').classList.remove('ticking');
}
function resetTimer() {
clearInterval(interval);
interval = null;
secs = 3600;
document.getElementById('timer-widget').classList.remove('ticking');
render();
}
</script>
</body>
</html>