obs-m4/grille_observation_mise_en_situation_mercredi4.html

1855 lines
64 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Grille d'observation - Mise en situation 20 min - Formation IA</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 (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%);
/* Dimension 4 Accent (Blue) */
--color-b-bg: hsl(207, 85%, 96%);
--color-b-border: hsl(207, 80%, 88%);
--color-b-accent: hsl(207, 90%, 45%);
--color-b-dark: hsl(207, 95%, 22%);
}
* {
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(207, 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;
}
/* Timer Widget */
.header-right {
display: flex;
align-items: center;
gap: 16px;
flex-shrink: 0;
}
.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;
transition: color 0.3s ease;
}
.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);
}
/* 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;
}
/* Notices / Alerts styling */
.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: 1.25rem;
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;
}
.notice strong {
font-weight: 800;
color: var(--primary-dark);
}
.notice.notice-warning {
background: var(--color-a-bg);
border-left-color: var(--color-a-accent);
}
.notice.notice-warning i {
color: var(--color-a-accent);
}
.notice.notice-warning strong {
color: var(--color-a-dark);
}
/* Chron Strip Details */
.chron-strip {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
margin-bottom: 2rem;
}
.cs-item {
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);
transition: all 0.25s ease;
}
.cs-item:hover {
box-shadow: var(--shadow-md);
transform: translateY(-2px);
}
.cs-lbl {
font-size: 0.65rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--color-text-tertiary);
margin-bottom: 4px;
}
.cs-val {
font-size: 1.1rem;
font-weight: 900;
color: var(--primary);
margin-bottom: 2px;
}
.cs-sub {
font-size: 0.75rem;
color: var(--color-text-secondary);
}
/* Dimension Blocks */
.dim-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;
}
.dim-block:hover {
box-shadow: var(--shadow-md);
}
.dim-head {
display: flex;
align-items: center;
gap: 16px;
padding: 16px 20px;
border-bottom: 1px solid var(--color-border-secondary);
}
.dim-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);
}
/* Theme Dimension 1: Contenu (Indigo/Violet) */
.dim-block.dim-contenu .dim-head {
background: var(--primary-light);
}
.dim-block.dim-contenu .dim-icon {
background: hsl(247, 85%, 90%);
color: var(--primary);
}
.dim-block.dim-contenu .dim-title {
color: var(--primary-dark);
}
/* Theme Dimension 2: Methode (Emerald Green) */
.dim-block.dim-methode .dim-head {
background: hsl(162, 85%, 96%);
border-bottom-color: hsl(162, 80%, 90%);
}
.dim-block.dim-methode .dim-icon {
background: hsl(162, 85%, 90%);
color: hsl(162, 75%, 34%);
}
.dim-block.dim-methode .dim-title {
color: hsl(162, 80%, 20%);
}
/* Theme Dimension 3: Posture (Amber/Orange) */
.dim-block.dim-posture .dim-head {
background: var(--color-a-bg);
border-bottom-color: var(--color-a-border);
}
.dim-block.dim-posture .dim-icon {
background: hsl(36, 85%, 90%);
color: var(--color-a-accent);
}
.dim-block.dim-posture .dim-title {
color: var(--color-a-dark);
}
/* Theme Dimension 4: Conduite de sequence (Blue) */
.dim-block.dim-conduite .dim-head {
background: var(--color-b-bg);
border-bottom-color: var(--color-b-border);
}
.dim-block.dim-conduite .dim-icon {
background: hsl(207, 85%, 90%);
color: var(--color-b-accent);
}
.dim-block.dim-conduite .dim-title {
color: var(--color-b-dark);
}
.dim-meta {
flex: 1;
display: flex;
flex-direction: column;
}
.dim-num {
font-size: 0.65rem;
font-weight: 800;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--color-text-tertiary);
margin-bottom: 2px;
}
.dim-title {
font-size: 1.15rem;
font-weight: 900;
}
.dim-q {
font-size: 0.85rem;
color: var(--color-text-secondary);
font-style: italic;
opacity: 0.9;
}
.dim-new {
font-size: 10px;
font-weight: 800;
padding: 2px 10px;
border-radius: 20px;
background: var(--color-b-bg);
color: var(--color-b-dark);
border: 1px solid var(--color-b-border);
text-transform: uppercase;
letter-spacing: 0.05em;
flex-shrink: 0;
}
/* Criteria Grid */
.crit-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0;
}
.crit {
border-right: 1px solid var(--color-border-secondary);
border-bottom: 1px solid var(--color-border-secondary);
padding: 20px;
display: flex;
flex-direction: column;
gap: 8px;
background: var(--bg-secondary);
transition: background-color 0.2s ease;
}
.crit:hover {
background: var(--bg-primary);
}
.crit:nth-child(2n) {
border-right: none;
}
.crit:nth-last-child(-n+2) {
border-bottom: none;
}
.cl {
font-size: 0.7rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--color-text-tertiary);
margin-bottom: 2px;
}
.cq {
font-size: 0.9rem;
font-weight: 800;
color: var(--color-text-primary);
line-height: 1.5;
margin-bottom: 4px;
}
/* Rating segment controller */
.scale-labels {
display: flex;
justify-content: space-between;
margin-top: 4px;
padding: 0 4px;
}
.sl-label {
font-size: 0.7rem;
font-weight: 700;
color: var(--color-text-tertiary);
text-transform: uppercase;
letter-spacing: .03em;
}
.scale-row {
display: flex;
gap: 8px;
margin-top: 6px;
margin-bottom: 8px;
}
.scale-opt {
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
cursor: pointer;
background: var(--bg-primary);
border: 1px solid var(--color-border-secondary);
border-radius: 12px;
padding: 6px 12px;
flex: 1;
transition: all 0.2s ease;
}
/* Customize Accent Colors on Radio checks */
.dim-contenu .scale-opt input[type="radio"] { accent-color: var(--primary); }
.dim-methode .scale-opt input[type="radio"] { accent-color: hsl(162, 75%, 34%); }
.dim-posture .scale-opt input[type="radio"] { accent-color: var(--color-a-accent); }
.dim-conduite .scale-opt input[type="radio"] { accent-color: var(--color-b-accent); }
/* Custom Hovers per Dimension Theme */
.dim-contenu .scale-opt:hover { border-color: var(--primary); background: var(--primary-light); }
.dim-methode .scale-opt:hover { border-color: hsl(162, 75%, 34%); background: hsl(162, 85%, 96%); }
.dim-posture .scale-opt:hover { border-color: var(--color-a-accent); background: var(--color-a-bg); }
.dim-conduite .scale-opt:hover { border-color: var(--color-b-accent); background: var(--color-b-bg); }
.scale-num {
font-size: 0.8rem;
font-weight: 800;
color: var(--color-text-primary);
}
.scale-opt input[type="radio"] {
width: 15px;
height: 15px;
cursor: pointer;
}
/* Custom Textarea styling */
.obs-area {
width: 100%;
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
background: var(--bg-primary);
font-family: 'DM Sans', sans-serif;
font-size: 0.875rem;
color: var(--color-text-primary);
padding: 10px 14px;
resize: vertical;
outline: none;
line-height: 1.55;
transition: all 0.25s ease;
}
.obs-area:focus {
border-color: var(--primary);
background: var(--bg-secondary);
box-shadow: 0 0 0 3px hsla(247, 80%, 62%, 0.12);
}
.obs-area::placeholder {
color: var(--color-text-tertiary);
font-style: italic;
opacity: 0.7;
}
/* Chronological Observations Timeline */
.timeline-obs {
background: var(--bg-tertiary);
border-top: 1px solid var(--color-border-secondary);
padding: 20px;
grid-column: 1 / -1;
}
.tobs-lbl {
font-size: 0.8rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--color-b-dark);
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 8px;
}
.tobs-grid {
display: grid;
grid-template-columns: 80px 1fr 80px 1fr;
gap: 12px;
align-items: center;
}
.tobs-t {
font-size: 0.8rem;
font-weight: 800;
color: var(--color-b-accent);
text-align: right;
padding-right: 8px;
}
.tobs-ta {
width: 100%;
border: 1px solid var(--color-border-secondary);
border-radius: var(--border-radius-md);
background: var(--bg-secondary);
font-family: 'DM Sans', sans-serif;
font-size: 0.875rem;
color: var(--color-text-primary);
padding: 8px 12px;
resize: none;
outline: none;
line-height: 1.5;
transition: all 0.25s ease;
}
.tobs-ta:focus {
border-color: var(--color-b-accent);
box-shadow: 0 0 0 3px hsla(207, 80%, 62%, 0.12);
}
.tobs-ta::placeholder {
color: var(--color-text-tertiary);
font-style: italic;
opacity: 0.7;
}
/* Synthesis & Scores styling */
.synth-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: 2.5rem;
overflow: hidden;
transition: box-shadow 0.25s ease;
}
.synth-block:hover {
box-shadow: var(--shadow-md);
}
.synth-head {
background: var(--primary-light);
border-bottom: 1px solid var(--color-border-secondary);
padding: 14px 20px;
display: flex;
align-items: center;
gap: 10px;
}
.synth-head i {
color: var(--primary);
font-size: 1.25rem;
}
.synth-lbl {
font-size: 0.8rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--primary-dark);
}
.synth-body {
padding: 20px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.sb-col {
display: flex;
flex-direction: column;
gap: 8px;
}
.sb-col-lbl {
font-size: 0.7rem;
font-weight: 800;
letter-spacing: .05em;
text-transform: uppercase;
color: var(--color-text-secondary);
}
.score-strip {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 12px;
padding: 20px;
background: var(--bg-tertiary);
border-top: 1px solid var(--color-border-secondary);
}
.sc-card {
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;
}
.sc-lbl {
font-size: 0.7rem;
font-weight: 800;
text-transform: uppercase;
letter-spacing: .05em;
color: var(--color-text-secondary);
}
.sc-val {
font-size: 1.5rem;
font-weight: 900;
color: var(--color-text-primary);
}
.sc-val.svc { color: var(--primary); }
.sc-val.svt { color: hsl(162, 75%, 34%); }
.sc-val.sva { color: var(--color-a-accent); }
.sc-val.svb { color: var(--color-b-accent); }
/* 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;
}
/* Signature Section */
.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;
}
/* Footer / Bottom strip styling */
.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%;
}
.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);
}
/* Screen Reader helper */
.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;
}
/* 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;
}
.chron-strip {
grid-template-columns: repeat(2, 1fr);
gap: 8px;
}
.crit-grid {
grid-template-columns: 1fr;
}
.crit {
border-right: none;
}
.crit:nth-last-child(-n+2) {
border-bottom: 1px solid var(--color-border-secondary);
}
.crit:last-child {
border-bottom: none;
}
.tobs-grid {
grid-template-columns: 80px 1fr;
}
.synth-body {
grid-template-columns: 1fr;
gap: 16px;
}
.score-strip {
grid-template-columns: repeat(2, 1fr);
gap: 8px;
}
.score-strip > .sc-card:last-child {
grid-column: span 2;
}
.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, .footer-btns .signature-btn {
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;
}
.dim-block, .synth-block, .signature-block {
page-break-inside: avoid;
border: 1px solid #94a3b8 !important;
background: white !important;
box-shadow: none !important;
}
.obs-area, .tobs-ta {
background: white !important;
border: 1px solid #94a3b8 !important;
resize: none;
}
.crit {
page-break-inside: avoid;
}
.scale-opt {
border: 1px solid #94a3b8 !important;
background: white !important;
}
.id-field {
border: 1px solid #94a3b8 !important;
background: white !important;
box-shadow: none !important;
}
.signature-pad {
border: 1px solid #94a3b8 !important;
background: white !important;
}
.signature-info-box {
border: 1px solid #94a3b8 !important;
background: white !important;
}
}
</style>
</head>
<body>
<div class="fiche">
<!-- Accessibility Hidden Title -->
<h2 class="sr-only">Grille d'observation pour la mise en situation complète du Mercredi 4 - passage de 20 minutes toutes UF, 4 dimensions dont conduite de séquence complète avec minuteur intégré, synthèse débrief et scores automatiques</h2>
<!-- Header -->
<div class="fiche-header">
<div class="header-left">
<div class="fiche-kicker">Mercredi 4 · Mise en situation complète · Grille observateur</div>
<div class="fiche-title">Grille d'observation<br>mise en situation 20 min</div>
</div>
<div class="header-right">
<!-- Timer widget -->
<div class="timer-pill" id="timer-widget">
<div class="timer-texts">
<span class="timer-label">Minuteur passage</span>
<span class="timer-display" id="timer-display">20:00</span>
</div>
<div class="timer-controls">
<button class="tcbtn" onclick="startTimer()" aria-label="Démarrer">
<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">Formateur observé</span>
<input class="field-line" type="text" placeholder="Prénom Nom" aria-label="Formateur observé" />
</div>
<div class="id-field">
<span class="field-label">Séquence animée</span>
<input class="field-line" type="text" placeholder="Ex. : UF2 Prompt Engineering (20 min)" aria-label="Séquence animée" />
</div>
<div class="id-field">
<span class="field-label">Observateur</span>
<input class="field-line" type="text" placeholder="Prénom Nom" aria-label="Observateur" />
</div>
</div>
<!-- Info Boxes -->
<div class="notice">
<i class="ti ti-arrows-exchange" aria-hidden="true"></i>
<p><strong>Mercredi 4 - grille augmentée :</strong> le passage dure 20 min, pas 10. Une 4e dimension s'ajoute - la conduite de séquence complète : transitions entre sous-parties, calibrage du rythme sur la durée, et réponse aux questions imprévues. C'est ce qui distingue un bon formateur d'un bon présentateur.</p>
</div>
<div class="notice notice-warning">
<i class="ti ti-info-circle" aria-hidden="true"></i>
<p>Notez pendant le passage, pas après. Pour le débrief : <strong>1 point fort + 1 axe prioritaire</strong>, maximum. Signaler à mi-passage (10 min) si le formateur va dériver sur le temps.</p>
</div>
<!-- Chron Strip -->
<div class="chron-strip">
<div class="cs-item">
<div class="cs-lbl">Durée passage</div>
<div class="cs-val">20 min</div>
<div class="cs-sub">vs 10 min M2 & M3</div>
</div>
<div class="cs-item">
<div class="cs-lbl">Signal mi-temps</div>
<div class="cs-val">10 min</div>
<div class="cs-sub">Lever la main discrèt.</div>
</div>
<div class="cs-item">
<div class="cs-lbl">Signal fin</div>
<div class="cs-val">20 min</div>
<div class="cs-sub">Stop ferme</div>
</div>
<div class="cs-item">
<div class="cs-lbl">Débrief passage</div>
<div class="cs-val">5 min</div>
<div class="cs-sub">Avant le suivant</div>
</div>
</div>
<!-- Dimension 1: Contenu -->
<div class="dim-block dim-contenu">
<div class="dim-head">
<div class="dim-icon"><i class="ti ti-file-text" aria-hidden="true"></i></div>
<div class="dim-meta">
<div class="dim-num">Dimension 1</div>
<div class="dim-title">Contenu</div>
</div>
<div class="dim-q">Exactitude, hiérarchisation, complétude sur 20 min</div>
</div>
<div class="crit-grid">
<div class="crit">
<div class="cl">Cr1.1</div>
<div class="cq">Les points clés sont couverts sans erreur factuelle - aucun oubli majeur sur la durée complète</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr1.1">
<label class="scale-opt"><input type="radio" name="c11" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c11" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c11" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c11" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr1.1"></textarea>
</div>
<div class="crit">
<div class="cl">Cr1.2</div>
<div class="cq">La hiérarchisation est claire sur toute la durée - l'essentiel reste en avant, le secondaire reste secondaire</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr1.2">
<label class="scale-opt"><input type="radio" name="c12" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c12" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c12" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c12" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr1.2"></textarea>
</div>
<div class="crit">
<div class="cl">Cr1.3</div>
<div class="cq">Au moins 2 exemples concrets ancrés dans un contexte professionnel réel - un par sous-partie minimum</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr1.3">
<label class="scale-opt"><input type="radio" name="c13" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c13" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c13" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c13" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr1.3"></textarea>
</div>
<div class="crit">
<div class="cl">Cr1.4</div>
<div class="cq">Une synthèse intermédiaire ou une accroche de transition relie les sous-parties entre elles</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr1.4">
<label class="scale-opt"><input type="radio" name="c14" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c14" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c14" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c14" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr1.4"></textarea>
</div>
</div>
</div>
<!-- Dimension 2: Méthode -->
<div class="dim-block dim-methode">
<div class="dim-head">
<div class="dim-icon"><i class="ti ti-tools" aria-hidden="true"></i></div>
<div class="dim-meta">
<div class="dim-num">Dimension 2</div>
<div class="dim-title">Méthode</div>
</div>
<div class="dim-q">Calibrage du rythme, transitions, gestion des imprévus sur 20 min</div>
</div>
<div class="crit-grid">
<div class="crit">
<div class="cl">Cr2.1</div>
<div class="cq">La méthode sert le contenu - le choix pédagogique (démo, atelier, échanges) est cohérent avec la séquence</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr2.1">
<label class="scale-opt"><input type="radio" name="c21" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c21" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c21" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c21" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr2.1"></textarea>
</div>
<div class="crit">
<div class="cl">Cr2.2</div>
<div class="cq">Le rythme est calibré sur 20 min - ni trop lent (temps mort) ni trop rapide (contenu expédié)</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr2.2">
<label class="scale-opt"><input type="radio" name="c22" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c22" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c22" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c22" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr2.2"></textarea>
</div>
<div class="crit">
<div class="cl">Cr2.3</div>
<div class="cq">Les consignes des activités sont claires et autonomisantes - le groupe sait quoi faire sans relancer</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr2.3">
<label class="scale-opt"><input type="radio" name="c23" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c23" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c23" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c23" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr2.3"></textarea>
</div>
<div class="crit">
<div class="cl">Cr2.4</div>
<div class="cq">Une question imprévue est gérée sans déstabilisation - le formateur répond ou renvoie sans perdre le fil</div>
<div class="scale-labels"><span class="sl-label">N/A</span><span class="sl-label">Très bien géré</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr2.4">
<label class="scale-opt"><input type="radio" name="c24" value="0" /><span class="scale-num" style="font-size:0.75rem;">N/A</span></label>
<label class="scale-opt"><input type="radio" name="c24" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c24" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c24" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c24" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Décrire la question et la gestion…" aria-label="Obs Cr2.4"></textarea>
</div>
</div>
</div>
<!-- Dimension 3: Posture -->
<div class="dim-block dim-posture">
<div class="dim-head">
<div class="dim-icon"><i class="ti ti-user-check" aria-hidden="true"></i></div>
<div class="dim-meta">
<div class="dim-num">Dimension 3</div>
<div class="dim-title">Posture</div>
</div>
<div class="dim-q">Présence, crédibilité, engagement du groupe sur la durée</div>
</div>
<div class="crit-grid">
<div class="crit">
<div class="cl">Cr3.1</div>
<div class="cq">L'engagement du groupe est maintenu sur les 20 min - pas de décrochage visible après la première sous-partie</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr3.1">
<label class="scale-opt"><input type="radio" name="c31" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c31" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c31" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c31" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr3.1"></textarea>
</div>
<div class="crit">
<div class="cl">Cr3.2</div>
<div class="cq">La posture est cohérente avec la séquence animée et reste stable sur toute la durée - pas de glissement vers le cours magistral</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr3.2">
<label class="scale-opt"><input type="radio" name="c32" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c32" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c32" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c32" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr3.2"></textarea>
</div>
<div class="crit">
<div class="cl">Cr3.3</div>
<div class="cq">L'écoute active est maintenue - les questions et réponses du groupe sont reprises et reliées au contenu</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr3.3">
<label class="scale-opt"><input type="radio" name="c33" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c33" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c33" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c33" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr3.3"></textarea>
</div>
<div class="crit">
<div class="cl">Cr3.4</div>
<div class="cq">Le formateur assume ses zones d'incertitude sans perdre en crédibilité - il ne survend pas ce qu'il maîtrise moins</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr3.4">
<label class="scale-opt"><input type="radio" name="c34" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c34" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c34" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c34" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr3.4"></textarea>
</div>
</div>
</div>
<!-- Dimension 4: Conduite de séquence complète -->
<div class="dim-block dim-conduite">
<div class="dim-head">
<div class="dim-icon"><i class="ti ti-layers-linked" aria-hidden="true"></i></div>
<div class="dim-meta">
<div class="dim-num">Dimension 4 - spécifique Mercredi 4</div>
<div class="dim-title">Conduite de séquence complète</div>
</div>
<div class="dim-q">Transitions, progression interne, clôture - ce que 10 min ne permettait pas d'évaluer</div>
<span class="dim-new">Nouveau</span>
</div>
<div class="crit-grid">
<div class="crit">
<div class="cl">Cr4.1</div>
<div class="cq">L'ouverture est efficace - l'intention pédagogique est posée clairement en moins de 2 min, sans préambule inutile</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr4.1">
<label class="scale-opt"><input type="radio" name="c41" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c41" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c41" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c41" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr4.1"></textarea>
</div>
<div class="crit">
<div class="cl">Cr4.2</div>
<div class="cq">Les transitions entre sous-parties sont explicites et reliées - pas de coupure abrupte ni de répétition inutile</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr4.2">
<label class="scale-opt"><input type="radio" name="c42" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c42" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c42" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c42" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr4.2"></textarea>
</div>
<div class="crit">
<div class="cl">Cr4.3</div>
<div class="cq">La clôture ancre l'apprentissage - une synthèse ou une phrase de bilan final rappelle ce que le groupe repart avec</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr4.3">
<label class="scale-opt"><input type="radio" name="c43" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c43" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c43" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c43" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr4.3"></textarea>
</div>
<div class="crit">
<div class="cl">Cr4.4</div>
<div class="cq">La progression est visible - on ressent une montée en densité ou en complexité entre le début et la fin du passage</div>
<div class="scale-labels"><span class="sl-label">Absent</span><span class="sl-label">Excellent</span></div>
<div class="scale-row" role="radiogroup" aria-label="Cr4.4">
<label class="scale-opt"><input type="radio" name="c44" value="1" /><span class="scale-num">1</span></label>
<label class="scale-opt"><input type="radio" name="c44" value="2" /><span class="scale-num">2</span></label>
<label class="scale-opt"><input type="radio" name="c44" value="3" /><span class="scale-num">3</span></label>
<label class="scale-opt"><input type="radio" name="c44" value="4" /><span class="scale-num">4</span></label>
</div>
<textarea class="obs-area" rows="2" placeholder="Ce que j'ai observé…" aria-label="Obs Cr4.4"></textarea>
</div>
</div>
<div class="timeline-obs">
<div class="tobs-lbl"><i class="ti ti-clock" aria-hidden="true"></i>Observations chronologiques - notez à chaud pendant le passage</div>
<div class="tobs-grid">
<span class="tobs-t">0 → 5 min</span>
<textarea class="tobs-ta" rows="2" placeholder="Ouverture, intention, consigne initiale…" aria-label="Obs 0 à 5 min"></textarea>
<span class="tobs-t">5 → 10 min</span>
<textarea class="tobs-ta" rows="2" placeholder="Première sous-partie, rythme, engagement…" aria-label="Obs 5 à 10 min"></textarea>
<span class="tobs-t">10 → 15 min</span>
<textarea class="tobs-ta" rows="2" placeholder="Transition, activité centrale, tenue du temps…" aria-label="Obs 10 à 15 min"></textarea>
<span class="tobs-t">15 → 20 min</span>
<textarea class="tobs-ta" rows="2" placeholder="Clôture, synthèse, question imprévue…" aria-label="Obs 15 à 20 min"></textarea>
</div>
</div>
</div>
<!-- Synthesis & Scores -->
<div class="synth-block">
<div class="synth-head">
<i class="ti ti-message-dots" aria-hidden="true"></i>
<span class="synth-lbl">Synthèse pour le débrief - à préparer avant de parler</span>
</div>
<div class="synth-body">
<div class="sb-col">
<div class="sb-col-lbl">1 point fort (à dire en premier)</div>
<textarea class="obs-area" rows="3" placeholder="Ce qui était vraiment solide sur les 20 min - avec le moment précis qui l'illustre…" aria-label="Point fort"></textarea>
</div>
<div class="sb-col">
<div class="sb-col-lbl">1 axe prioritaire (1 seul)</div>
<textarea class="obs-area" rows="3" placeholder="Ce qui serait le plus utile à améliorer pour la Phase 2 - formulé positivement…" aria-label="Axe d'amélioration"></textarea>
</div>
<div class="sb-col">
<div class="sb-col-lbl">Moment de bascule observé</div>
<textarea class="obs-area" rows="3" placeholder="Le moment précis (minute) où le formateur a pris ou perdu le groupe - à nommer dans le débrief…" aria-label="Moment de bascule"></textarea>
</div>
<div class="sb-col">
<div class="sb-col-lbl">Comparaison avec M2 & M3</div>
<textarea class="obs-area" rows="3" placeholder="Ce qui a progressé depuis les micro-teachings - un point concret de progression à valoriser…" aria-label="Progression parcours"></textarea>
</div>
</div>
<div class="score-strip" id="ss">
<div class="sc-card">
<div class="sc-lbl">Contenu /16</div>
<div class="sc-val svc" id="sv1">-</div>
</div>
<div class="sc-card">
<div class="sc-lbl">Méthode /16</div>
<div class="sc-val svt" id="sv2">-</div>
</div>
<div class="sc-card">
<div class="sc-lbl">Posture /16</div>
<div class="sc-val sva" id="sv3">-</div>
</div>
<div class="sc-card">
<div class="sc-lbl">Conduite /16</div>
<div class="sc-val svb" id="sv4">-</div>
</div>
<div class="sc-card">
<div class="sc-lbl">Total /64</div>
<div class="sc-val" id="svt">-</div>
</div>
</div>
</div>
<!-- Observator Signature (Part 4) -->
<div class="section-title">
<i class="ti ti-edit" aria-hidden="true"></i>Signature de l'observateur
</div>
<div class="signature-block">
<div class="signature-grid">
<div class="signature-col">
<div class="signature-label">Signature de l'observateur</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 d'observation</span>
<input type="text" class="field-line" placeholder="__/__/____" id="signature-date" aria-label="Date d'observation" />
</div>
<div class="signature-info-box">
<i class="ti ti-info-circle" aria-hidden="true"></i>
<p>Cette signature valide officiellement la grille d'observation et le débriefing de la mise en situation complète effectuée.</p>
</div>
</div>
</div>
</div>
<!-- Footer row with controls -->
<div class="footer-strip">
<div class="footer-note">À remettre au formateur référent après le débrief. Une grille par observateur par passage. La dimension 4 (conduite de séquence complète) est la nouvelle dimension clé de cette séance.</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 grille
</button>
</div>
</div>
</div>
<!-- Main scripts -->
<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);
// Canvas auto resizing function
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);
}
// Initialise Canvas
function initCanvas() {
const resizeObserver = new ResizeObserver(() => {
resizeCanvas();
const savedSignature = localStorage.getItem('signatureData_obs_m4');
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();
}
// Drawing coordinate extraction
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];
}
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; });
// Signature Pad handlers
window.clearSignature = function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
localStorage.removeItem('signatureData_obs_m4');
};
window.saveSignature = function() {
const signatureData = canvas.toDataURL('image/png');
localStorage.setItem('signatureData_obs_m4', signatureData);
return signatureData;
};
const savedSignature = localStorage.getItem('signatureData_obs_m4');
if (savedSignature) {
const img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width / ratio, canvas.height / ratio);
};
img.src = savedSignature;
}
// Date field auto-save
const signatureDate = document.getElementById('signature-date');
const savedDate = localStorage.getItem('signatureDate_obs_m4');
if (savedDate) signatureDate.value = savedDate;
signatureDate.addEventListener('input', () => {
localStorage.setItem('signatureDate_obs_m4', signatureDate.value);
});
initCanvas();
updateScores();
});
</script>
<!-- Scores calculations & Auto-save -->
<script>
const DIMS = {
c: ['c11', 'c12', 'c13', 'c14'],
m: ['c21', 'c22', 'c23', 'c24'],
p: ['c31', 'c32', 'c33', 'c34'],
b: ['c41', 'c42', 'c43', 'c44']
};
function calcDim(keys) {
let t = 0, checkedCount = 0, naCount = 0;
keys.forEach(k => {
const v = document.querySelector('input[name=' + k + ']:checked');
if (v) {
checkedCount++;
if (v.value === '0') {
naCount++;
} else {
t += parseInt(v.value);
}
}
});
if (checkedCount === keys.length) {
let gradedCount = keys.length - naCount;
if (gradedCount === 0) return 0;
// Project the score out of 16 if N/A is checked
return Math.round(t * (keys.length / gradedCount));
}
return null;
}
function updateScores() {
const c = calcDim(DIMS.c), m = calcDim(DIMS.m), p = calcDim(DIMS.p), b = calcDim(DIMS.b);
document.getElementById('sv1').textContent = c !== null ? c : '-';
document.getElementById('sv2').textContent = m !== null ? m : '-';
document.getElementById('sv3').textContent = p !== null ? p : '-';
document.getElementById('sv4').textContent = b !== null ? b : '-';
document.getElementById('svt').textContent = (c !== null && m !== null && p !== null && b !== null) ? (c + m + p + b) : '-';
}
// Auto-save & Load for Textareas
const textareas = document.querySelectorAll('textarea');
textareas.forEach((t, index) => {
const savedVal = localStorage.getItem(`textarea_obs_m4_${index}`);
if (savedVal !== null) t.value = savedVal;
t.addEventListener('input', () => {
localStorage.setItem(`textarea_obs_m4_${index}`, t.value);
});
});
// Auto-save & Load for Text Inputs
const textInputs = document.querySelectorAll('input[type="text"]');
textInputs.forEach((input, index) => {
if (input.id === 'signature-date') return;
const savedVal = localStorage.getItem(`input_obs_m4_${index}`);
if (savedVal !== null) input.value = savedVal;
input.addEventListener('input', () => {
localStorage.setItem(`input_obs_m4_${index}`, input.value);
});
});
// Auto-save & Load for Radios
const radios = document.querySelectorAll('input[type="radio"]');
radios.forEach((radio) => {
const savedVal = localStorage.getItem(`radio_obs_m4_${radio.name}`);
if (savedVal && radio.value === savedVal) {
radio.checked = true;
}
radio.addEventListener('change', () => {
localStorage.setItem(`radio_obs_m4_${radio.name}`, radio.value);
updateScores();
});
});
// Clear All Function
window.clearAll = function() {
if (!confirm('Effacer toutes les saisies de cette grille d\'observation ?')) return;
document.querySelectorAll('textarea').forEach(t => t.value = '');
document.querySelectorAll('input[type=radio]').forEach(r => r.checked = false);
document.querySelectorAll('.field-line').forEach(i => i.value = '');
if (typeof clearSignature === 'function') {
clearSignature();
}
const sigDateEl = document.getElementById('signature-date');
if (sigDateEl) sigDateEl.value = '';
resetTimer();
updateScores();
// Remove from localStorage
const keysToRemove = [];
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key && (key.startsWith('textarea_obs_m4_') || key.startsWith('input_obs_m4_') || key.startsWith('radio_obs_m4_') || key === 'signatureData_obs_m4' || key === 'signatureDate_obs_m4')) {
keysToRemove.push(key);
}
}
keysToRemove.forEach(k => localStorage.removeItem(k));
};
// Timer Logic (20 minutes passage)
let secs = 1200, 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 renderTimer() {
const displayEl = document.getElementById('timer-display');
displayEl.textContent = fmt(secs);
// Set to warning color at 10 minutes (600 seconds)
if (secs <= 600) {
displayEl.style.color = 'var(--color-a-accent)';
} else {
displayEl.style.color = 'var(--primary-dark)';
}
}
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--;
renderTimer();
}, 1000);
}
function pauseTimer() {
clearInterval(interval);
interval = null;
document.getElementById('timer-widget').classList.remove('ticking');
}
function resetTimer() {
clearInterval(interval);
interval = null;
secs = 1200;
document.getElementById('timer-widget').classList.remove('ticking');
renderTimer();
}
</script>
</body>
</html>