Maquettes Claude Design avec visio de classe

This commit is contained in:
Adam Belkacemi 2026-10-06 23:28:18 +02:00
parent 238070ae54
commit 236d2d3567
243 changed files with 27992 additions and 0 deletions

View file

@ -0,0 +1,151 @@
/* Syllabus — thème global. Surcharge les anciennes classes néo-brutalistes pour appliquer la DA "SaaS doux" de la bibliothèque v2. */
@import url('https://fonts.googleapis.com/css2?family=Mulish:wght@400;500;600;700;800&display=swap');
:root { --sy-bg:#f5f6f8; --sy-surface:#fff; --sy-line:#b8c1cf; --sy-ink:#111827; --sy-muted:#6b7280; --sy-blue:#1d5cf5; --sy-blue-dark:#174bd0; --sy-navy:#1e3a8a; }
html, body { background: var(--sy-bg) !important; color: var(--sy-ink) !important; font-family: Mulish, system-ui, sans-serif !important; }
body * { font-family: inherit; }
code, pre, kbd, .font-mono, [class*="font-mono"] { font-family: ui-monospace, "IBM Plex Mono", Menlo, monospace !important; }
a { color: inherit; } a:hover { color: var(--sy-blue); }
/* Bordures : fines et grises, coins arrondis */
[class~="border-4"]:not([class~="border-transparent"]), [class~="border-2"]:not([class~="border-transparent"]), [class~="border"] { border-width: 1px !important; border-color: var(--sy-line) !important; }
[class~="border-b-4"], [class~="border-b-2"] { border-bottom-width: 1px !important; border-bottom-color: var(--sy-line) !important; }
[class~="border-t-4"], [class~="border-t-2"] { border-top-width: 1px !important; border-top-color: var(--sy-line) !important; }
[class~="border-r-2"], [class~="border-l-2"] { border-color: var(--sy-line) !important; }
[class~="divide-black"] > * + * { border-color: var(--sy-line) !important; }
section[class*="border"], article[class*="border"], aside[class*="border"], div[class~="border-4"], div[class~="border-2"], li[class~="border-2"], figure[class*="border"], details[class*="border"], table { border-radius: 12px; }
a[class~="border-2"], button[class~="border-2"], summary[class~="border-2"], span[class~="border-2"], input, select, textarea { border-radius: 6px !important; }
[class*="border-dashed"] { border-style: dashed !important; }
/* Ombres dures → ombres douces ; plus de rotations ni de décors flottants */
[class*="shadow-["] { box-shadow: 0 1px 3px rgba(17,24,39,.06) !important; }
[class*="hover:shadow-["]:hover { box-shadow: 0 6px 18px rgba(17,24,39,.08) !important; }
[class*="rotate-"], [class*="-rotate-"] { transform: none !important; }
[aria-hidden="true"][class*="absolute"][class*="pointer-events-none"] { display: none !important; }
/* Palette : jaune/vert/rose/lavande fluo → pastels ; rouge/noir d'action → bleu */
[class~="bg-[#FFD23F]"] { background-color: #dbe6ff !important; color: var(--sy-navy) !important; }
[class~="bg-[#7CF2C0]"] { background-color: #dcfce7 !important; color: #166534 !important; }
[class~="bg-[#FF6FB5]"] { background-color: #fce7f3 !important; color: #9d174d !important; }
[class~="bg-[#C4B5FD]"] { background-color: #ede4ff !important; color: #5b21b6 !important; }
[class~="bg-[#FFFBEA]"], [class~="bg-[#F6F5F1]"], [class*="hover:bg-[#FFFBEA]"]:hover { background-color: #f1f2f5 !important; }
[class~="bg-[#ec3013]"] { background-color: var(--sy-blue) !important; color: #fff !important; }
[class~="bg-black"]:not(pre):not([class*="h-2"]):not([class*="h-3"]):not([class*="h-full"]) { background-color: var(--sy-blue) !important; color: #fff !important; }
[class*="hover:bg-black"]:hover { background-color: var(--sy-blue-dark) !important; color: #fff !important; }
[class~="bg-[#13233A]"] { background-color: #0f172a !important; border-radius: 12px; }
[class*="text-[#b3001b]"], [class*="text-[#ec3013]"] { color: #b91c1c !important; }
[class~="bg-[#F6F5F1]"] { background-color: #f8f9fb !important; }
body > header, header[class*="border-b"] { background: #fff !important; box-shadow: 0 1px 0 var(--sy-line) !important; }
/* Titres un peu moins massifs */
h1[class*="font-black"] { letter-spacing: -0.015em !important; }
[class*="font-black"] { font-weight: 800 !important; }
[class*="uppercase"][class*="tracking-wider"] { color: var(--sy-muted); }
/* Focus */
:focus-visible { outline: 2px solid var(--sy-blue) !important; outline-offset: 2px; }
/* États : page courante, menu ouvert, survol */
[aria-current="page"][class*="aria-[current=page]:bg-[#FFD23F]"], details[open] > [class*="group-open:bg-[#FFD23F]"] { background-color: #dbe6ff !important; color: var(--sy-blue) !important; border-color: transparent !important; border-radius: 6px; }
[aria-current="page"][class*="aria-[current=page]:border-black"] { border-color: transparent !important; }
[class*="hover:bg-[#FFD23F]"]:hover { background-color: #dbe6ff !important; }
[class*="hover:border-black"]:hover { border-color: var(--sy-line) !important; }
/* Ton posé : titres plus mesurés, moins de couleur, pas d'emoji ni d'effets */
h1:not([style*="font-size"]) { font-size: clamp(28px, 3.2vw, 40px) !important; line-height: 1.15 !important; font-weight: 800 !important; }
h2:not([style*="font-size"]) { font-size: clamp(22px, 2.2vw, 28px) !important; line-height: 1.2 !important; }
h3:not([style*="font-size"]) { font-size: 18px !important; line-height: 1.3 !important; }
[class*="text-7xl"], [class*="text-8xl"], [class*="text-6xl"] { font-size: clamp(30px, 3.4vw, 42px) !important; line-height: 1.15 !important; }
[class*="text-5xl"] { font-size: clamp(26px, 2.6vw, 32px) !important; }
[class*="leading-[0.9"], [class*="leading-[0.8"] { line-height: 1.15 !important; }
[class*="tracking-tighter"] { letter-spacing: -0.01em !important; }
[class*="hover:-translate-y"]:hover, [class*="hover:translate"]:hover { transform: none !important; }
[class*="animate-"] { animation: none !important; }
section[class~="bg-[#ec3013]"], section[class~="bg-black"], div[class~="bg-black"][class*="p-8"], div[class~="bg-black"][class*="p-6"] { background: #fff !important; color: var(--sy-ink) !important; border: 1px solid var(--sy-line) !important; }
section[class~="bg-[#ec3013]"] *, div[class~="bg-black"][class*="p-8"] *, div[class~="bg-black"][class*="p-6"] * { color: inherit; }
[class*="bg-[#FFD23F]"][class*="px-3"][class*="uppercase"] { background: transparent !important; color: var(--sy-blue) !important; padding-left: 0 !important; box-shadow: none !important; border: 0 !important; }
[class*="E6FF3F"],[class*="E8FF3C"]{background-color:#eef2ff!important;color:#1e3a8a!important}
/* Contraste : fond de page plus sombre, contours visibles partout, traits fins */
html, body { background: #eef1f5 !important; }
main section.bg-white, main section[class*="bg-white"] { background: #eef1f5 !important; }
[class*="border-4"], [class*="border-2"], [class*="border-black"], [class*="border-y-4"], [class*="border-t-4"], [class*="border-b-4"] { border-color: #b8c1cf !important; }
[class*="border-4"] { border-width: 1px !important; }
[class*="border-2"] { border-width: 1px !important; }
[class*="border-y-4"] { border-top-width: 1px !important; border-bottom-width: 1px !important; }
[class*="border-t-4"] { border-top-width: 1px !important; }
[class*="border-b-4"] { border-bottom-width: 1px !important; }
[class*="border-r-4"], [class*="border-l-4"] { border-width: 0 1px 0 0 !important; }
[class*="divide-black"] > * + * { border-color: #b8c1cf !important; }
main article, main figure, main li[class*="border"], main div[class*="border"][class*="bg-"] { box-shadow: 0 1px 2px rgba(17,24,39,.06), 0 2px 8px rgba(17,24,39,.05) !important; }
[class*="bg-white"][class*="border"], figure[style*="border"] { background: #fff !important; }
/* Badges collés aux cartes : dans le flux, alignés en haut */
main article > span[class*="absolute"], main li > span[class*="absolute"], main div[class*="relative"] > span[class*="absolute"][class*="border"] { position: static !important; display: inline-block !important; margin: 0 0 12px 0 !important; transform: none !important; }
header a, header summary, nav a, header [class*="border-transparent"], nav [class*="border-transparent"] { border-color: transparent !important; }
header a[aria-current="page"], header details[open] > summary { border-color: #bfd0f5 !important; }
header ul[class*="absolute"] { border: 1px solid #b8c1cf !important; }
main [class*="border-4"], main [class*="border-2"]:not([class*="border-transparent"]) { border-color: #b8c1cf !important; }
main li[class*="min-h-[340px]"] { min-height: 0 !important; }
main li[class*="min-h-[340px]"] > *:first-child + * { margin-top: 12px !important; }
h1 span[class*="bg-"] { background: transparent !important; border: 0 !important; padding: 0 !important; color: #1d4ed8 !important; }
[class*="border-transparent"] { border-color: transparent !important; }
[class*="border-transparent"][aria-current="page"], [class*="border-transparent"]:hover { border-color: transparent !important; background: #e8eefc !important; }
aside a[class*="border-black"][class*="bg-black"] { border-color: transparent !important; }
/* === SOBRIÉTÉ (inspiration Google Workspace) : l'espace et la typographie structurent, un seul appel à l'action fort === */
:root { --sy-ink:#0b1220; --sy-text:#3c4043; --sy-hair:#e3e5e8; --sy-soft:#f8f9fa; --sy-blue:#0b57d0; --sy-blue-dark:#0842a0; }
html, body { background:#fff !important; }
main p { color: var(--sy-text); }
main h1, main h2, main h3 { color: var(--sy-ink) !important; text-wrap: balance; }
main h1:not([style*="line-height"]) { font-weight:800 !important; line-height:1.06 !important; }
main p, main li { text-wrap: pretty; }
/* Fonds : blanc, et un gris très léger pour alterner les sections */
main section[class*="bg-"], main div[class~="bg-[#F6F5F1]"], main div[class~="bg-[#FFFBEA]"] { background-color:#fff !important; }
main section[class~="bg-[#F6F5F1]"], main section[class~="bg-[#FFFBEA]"] { background-color: var(--sy-soft) !important; }
main section { border-color: transparent !important; box-shadow:none !important; }
/* Pages vitrine : beaucoup plus d'air */
main > section > div[class*="py-"] { padding-top: clamp(64px, 9vw, 112px) !important; padding-bottom: clamp(64px, 9vw, 112px) !important; }
main > section > div[class*="max-w-"] > p[class*="text-xl"], main > section > div[class*="max-w-"] p[class*="text-lg"] { line-height:1.65 !important; }
/* Cartes et encadrés : trait très fin, grands rayons, aucune ombre */
[class~="border-4"]:not([class~="border-transparent"]), [class~="border-2"]:not([class~="border-transparent"]), [class~="border"] { border-color: var(--sy-hair) !important; }
main article[class*="border"], main li[class~="border-2"], main div[class~="border-2"], main div[class~="border-4"], main figure[class*="border"], main details[class*="border"] { border-radius:16px !important; }
[class*="shadow-["], [class*="shadow-md"], [class*="shadow-lg"] { box-shadow:none !important; }
[class*="rotate-"], [class*="-rotate-"], [class*="md:rotate"], [class*="md:-rotate"], [class*="translate-y-8"] { transform:none !important; }
main [aria-hidden="true"][class*="absolute"] { display:none !important; }
/* Badges et pastilles : neutres, texte foncé */
main span[class~="border-2"][class*="text-xs"], main span[class~="border-2"][class*="text-sm"][class*="px-2"], main span[class*="rounded-full"][class*="px-"] { background:#f1f3f4 !important; color:#3c4043 !important; border-color:transparent !important; border-radius:999px !important; }
[class~="bg-[#FFD23F]"], [class~="bg-[#7CF2C0]"], [class~="bg-[#FF6FB5]"], [class~="bg-[#C4B5FD]"] { background-color:#f1f3f4 !important; color:#202124 !important; }
main div[class*="bg-[#FFD23F]"][class*="p-"], main div[class*="bg-[#7CF2C0]"][class*="p-"], main div[class*="bg-[#C4B5FD]"][class*="p-"], main div[class*="bg-[#FF6FB5]"][class*="p-"] { background: var(--sy-soft) !important; }
/* Boutons : pilules ; l'action principale en bleu plein, le reste en contour discret */
a[class*="inline-flex"][class*="h-11"], a[class*="inline-flex"][class*="h-12"], a[class*="inline-flex"][class*="h-10"], button[class*="h-11"], button[class*="h-12"], button[class*="h-10"] { border-radius:999px !important; padding-left:24px !important; padding-right:24px !important; font-weight:700 !important; }
a[class~="bg-[#ec3013]"], button[class~="bg-[#ec3013]"], a[class~="bg-black"], button[class~="bg-black"] { background-color: var(--sy-blue) !important; border-color: var(--sy-blue) !important; color:#fff !important; }
a[class~="bg-[#ec3013]"]:hover, button[class~="bg-[#ec3013]"]:hover, a[class~="bg-black"]:hover, button[class~="bg-black"]:hover { background-color: var(--sy-blue-dark) !important; }
main a[class~="bg-white"][class*="inline-flex"], main button[class~="bg-white"][class*="h-"] { background:#fff !important; color: var(--sy-blue) !important; border:1px solid #dadce0 !important; }
main a[class~="bg-white"][class*="inline-flex"]:hover, main button[class~="bg-white"][class*="h-"]:hover { background:#f6f9fe !important; }
/* En-tête : conservé, épuré */
body > header { background:#fff !important; box-shadow:none !important; border-bottom:1px solid var(--sy-hair) !important; }
body > header nav a, body > header nav summary { font-weight:600 !important; color:#3c4043 !important; text-decoration:none !important; }
body > header nav a:hover, body > header nav summary:hover { color: var(--sy-ink) !important; background:transparent !important; }
body > header nav ul a[aria-current="page"] { color: var(--sy-blue) !important; background:transparent !important; }
body > header a[href*="inscription"] { background: var(--sy-blue) !important; color:#fff !important; border:0 !important; border-radius:999px !important; padding:0 22px !important; }
body > header a[href*="inscription"] > span[aria-hidden="true"] { display:none !important; }
body > header a[href*="inscription"]:hover { background: var(--sy-blue-dark) !important; color:#fff !important; }
body > header a[href*="connexion"] { border:0 !important; background:transparent !important; }
[class*="text-[#FFD23F]"], [class*="text-[#7CF2C0]"], [class*="text-[#FF6FB5]"], [class*="text-[#C4B5FD]"], [class*="text-[#E6FF3F]"], [class*="text-[#E8FF3C]"] { color: var(--sy-blue) !important; }
main li[class*="min-h-[340px]"] { min-height:0 !important; aspect-ratio:auto !important; }
main li[class*="min-h-[340px]"] > div[class*="justify-between"] { justify-content:flex-start !important; gap:16px !important; padding-bottom:0 !important; }
main li[class*="min-h-[340px]"] > div > span[class*="self-end"] { align-self:flex-start !important; font-size:40px !important; color: var(--sy-blue) !important; }
body > header a[href*="connexion"] { border:0 !important; background:transparent !important; box-shadow:none !important; padding-left:8px !important; padding-right:8px !important; }
main h1:not([style*="letter-spacing"]), main h2:not([style*="letter-spacing"]) { letter-spacing:-0.02em !important; }
header a[style*="background:#0b57d0"], header a[style*="background: #0b57d0"], nav a[style*="background:#0b57d0"] { color: #fff !important; }
header a[style*="background:#0b57d0"]:hover, nav a[style*="background:#0b57d0"]:hover { color: #fff !important; background: #0842a0 !important; }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

75
design/vitrine/index.html Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,199 @@
// Terminal élève Syllabus : xterm.js + un petit shell simulé (vitrine et lab d'essai).
// En production, le terminal se branche sur le proxy WebSocket de la console série Nova.
(function () {
var THEME = {
background: '#13233A', foreground: '#E8EDF5', cursor: '#FFD23F', cursorAccent: '#13233A',
selectionBackground: '#2B4A73', black: '#0D192B', red: '#FF7A66', green: '#7CF2C0', yellow: '#FFD23F',
blue: '#8DB4FF', magenta: '#FF6FB5', cyan: '#7CE3F2', white: '#E8EDF5',
brightBlack: '#6B7F99', brightRed: '#FF9A8A', brightGreen: '#7CF2C0', brightYellow: '#FFD23F',
brightBlue: '#A9C6FF', brightMagenta: '#FF8FC6', brightCyan: '#9CEBF7', brightWhite: '#FFFFFF'
};
var G = '\x1b[1;92m', B = '\x1b[1;94m', Y = '\x1b[93m', R = '\x1b[91m', D = '\x1b[2m', X = '\x1b[0m';
function Shell(term, o) {
this.t = term; this.o = o;
this.user = o.user || 'eleve'; this.host = o.host || 'debian-lab';
this.home = '/home/' + this.user; this.cwd = this.home;
this.dirs = new Set(['/', '/home', this.home, '/etc', '/tmp', '/var', '/var/log']);
this.files = new Map([
[this.home + '/.bashrc', '# ~/.bashrc'],
['/etc/hostname', this.host],
['/etc/os-release', 'PRETTY_NAME="Debian GNU/Linux 13 (trixie)"\nID=debian']
]);
this.line = ''; this.hist = []; this.hi = 0; this.busy = false;
}
Shell.prototype.short = function (p) { return p === this.home ? '~' : p.indexOf(this.home + '/') === 0 ? '~' + p.slice(this.home.length) : p; };
Shell.prototype.prompt = function () { this.t.write(G + this.user + '@' + this.host + X + ':' + B + this.short(this.cwd) + X + '$ '); };
Shell.prototype.path = function (p) {
if (!p || p === '~') return this.home;
if (p.indexOf('~/') === 0) p = this.home + p.slice(1);
var parts = (p[0] === '/' ? p : this.cwd + '/' + p).split('/'), out = [];
parts.forEach(function (s) { if (!s || s === '.') return; if (s === '..') out.pop(); else out.push(s); });
return '/' + out.join('/');
};
Shell.prototype.parent = function (p) { var i = p.lastIndexOf('/'); return i <= 0 ? '/' : p.slice(0, i); };
Shell.prototype.base = function (p) { return p.slice(p.lastIndexOf('/') + 1); };
Shell.prototype.children = function (d) {
var self = this, out = [];
this.dirs.forEach(function (x) { if (x !== '/' && self.parent(x) === d) out.push({ n: self.base(x), dir: true }); });
this.files.forEach(function (v, x) { if (self.parent(x) === d) out.push({ n: self.base(x), dir: false, size: v.length }); });
return out.sort(function (a, b) { return a.n.replace(/^\./, '').localeCompare(b.n.replace(/^\./, '')); });
};
Shell.prototype.out = function (s) { this.t.write(String(s).replace(/\n/g, '\r\n') + '\r\n'); };
Shell.prototype.err = function (s) { this.out(R + s + X); };
Shell.prototype.exec = function (raw) {
var self = this, parts = raw.split(/&&|;/);
for (var i = 0; i < parts.length; i++) { if (!self.run(parts[i].trim())) break; }
if (this.o.onCommand) this.o.onCommand(raw, this);
};
Shell.prototype.run = function (cmd) {
if (!cmd) return true;
var toks = [], m, re = /"([^"]*)"|'([^']*)'|(\S+)/g;
while ((m = re.exec(cmd))) toks.push(m[1] != null ? m[1] : m[2] != null ? m[2] : m[3]);
var redir = null, ri = toks.findIndex(function (t) { return t === '>' || t === '>>'; });
if (ri > -1) { redir = { mode: toks[ri], file: toks[ri + 1] }; toks = toks.slice(0, ri); }
var c = toks[0], a = toks.slice(1), self = this, flags = a.filter(function (x) { return x[0] === '-'; }).join(''), args = a.filter(function (x) { return x[0] !== '-'; });
var capture = null, print = function (s) { if (redir) capture = (capture ? capture + '\n' : '') + s; else self.out(s); };
switch (c) {
case 'help': print('Commandes : pwd, ls, cd, mkdir, touch, echo, cat, rm, rmdir, whoami, hostname, date, uname, ip a, clear'); break;
case 'pwd': print(this.cwd); break;
case 'whoami': print(this.user); break;
case 'hostname': print(this.host); break;
case 'date': print(new Date().toLocaleString('fr-FR', { dateStyle: 'full', timeStyle: 'medium' })); break;
case 'uname': print(flags.indexOf('a') > -1 ? 'Linux ' + this.host + ' 6.12.0-amd64 #1 SMP Debian x86_64 GNU/Linux' : 'Linux'); break;
case 'clear': this.t.clear(); break;
case 'ip':
if (/^a|^addr/.test(args[0] || '')) print('1: lo: <LOOPBACK,UP> mtu 65536\n inet 127.0.0.1/8 scope host lo\n2: ens3: <BROADCAST,MULTICAST,UP> mtu 1500\n inet 192.168.10.10/26 brd 192.168.10.63 scope global ens3');
else print('Usage : ip addr'); break;
case 'ls': {
var d = this.path(args[0] || '.');
if (!this.dirs.has(d)) { this.err("ls: impossible d'accéder à '" + (args[0] || '.') + "': Aucun fichier ou dossier de ce nom"); return false; }
var all = flags.indexOf('a') > -1, long = flags.indexOf('l') > -1;
var list = this.children(d).filter(function (e) { return all || e.n[0] !== '.'; });
if (all) list = [{ n: '.', dir: true }, { n: '..', dir: true }].concat(list);
var col = function (e) { return redir ? e.n : e.dir ? B + e.n + X : e.n; };
if (long) {
var now = new Date(), stamp = now.toLocaleDateString('fr-FR', { day: '2-digit', month: 'short' }) + ' ' + now.toTimeString().slice(0, 5);
print('total ' + list.length * 4);
list.forEach(function (e) { print((e.dir ? 'drwxr-xr-x 2 ' : '-rw-r--r-- 1 ') + self.user + ' ' + self.user + ' ' + String(e.dir ? 4096 : e.size).padStart(5) + ' ' + stamp + ' ' + col(e)); });
} else if (list.length) print(list.map(col).join(' '));
break;
}
case 'cd': {
var p = this.path(args[0]);
if (!this.dirs.has(p)) { this.err('bash: cd: ' + args[0] + ': Aucun fichier ou dossier de ce nom'); return false; }
this.cwd = p; break;
}
case 'mkdir':
if (!args.length) { this.err('mkdir: opérande manquant'); return false; }
for (var i = 0; i < args.length; i++) {
var np = this.path(args[i]);
if (this.dirs.has(np)) { if (flags.indexOf('p') < 0) { this.err("mkdir: impossible de créer le répertoire « " + args[i] + " »: Le fichier existe"); return false; } continue; }
if (!this.dirs.has(this.parent(np))) {
if (flags.indexOf('p') < 0) { this.err("mkdir: impossible de créer le répertoire « " + args[i] + " »: Aucun fichier ou dossier de ce nom"); return false; }
var acc = ''; np.split('/').slice(1).forEach(function (s) { acc += '/' + s; self.dirs.add(acc); });
} else this.dirs.add(np);
}
break;
case 'touch':
if (!args.length) { this.err('touch: opérande de fichier manquant'); return false; }
args.forEach(function (f) { var fp = self.path(f); if (!self.files.has(fp)) self.files.set(fp, ''); }); break;
case 'echo': print(args.join(' ')); break;
case 'cat': {
var f = this.path(args[0]);
if (this.dirs.has(f)) { this.err('cat: ' + args[0] + ': est un dossier'); return false; }
if (!this.files.has(f)) { this.err('cat: ' + args[0] + ': Aucun fichier ou dossier de ce nom'); return false; }
var v = this.files.get(f); if (v) print(v); break;
}
case 'rm':
for (var k = 0; k < args.length; k++) {
var rp = this.path(args[k]);
if (this.dirs.has(rp)) { this.err("rm: impossible de supprimer '" + args[k] + "': est un dossier"); return false; }
if (!this.files.delete(rp)) { this.err("rm: impossible de supprimer '" + args[k] + "': Aucun fichier ou dossier de ce nom"); return false; }
}
break;
case 'rmdir': {
var dp = this.path(args[0]);
if (!this.dirs.has(dp)) { this.err("rmdir: '" + args[0] + "': Aucun fichier ou dossier de ce nom"); return false; }
if (this.children(dp).length) { this.err("rmdir: '" + args[0] + "': Le dossier n'est pas vide"); return false; }
this.dirs.delete(dp); break;
}
case 'sudo': if (this.o.commands) return this.run(a.join(' ')); print(Y + 'Pas besoin de sudo pour ce lab : tout se passe dans ton dossier.' + X); break;
default:
if (this.o.commands && this.o.commands[c]) { var res = this.o.commands[c](a, this); if (res === false) return false; if (res) print(res); break; }
this.err('bash: ' + c + ' : commande introuvable'); return false;
}
if (redir) {
if (!redir.file) { this.err('bash: erreur de syntaxe près du symbole inattendu « newline »'); return false; }
var fp2 = this.path(redir.file);
if (!this.dirs.has(this.parent(fp2))) { this.err('bash: ' + redir.file + ': Aucun fichier ou dossier de ce nom'); return false; }
var prev = redir.mode === '>>' && this.files.has(fp2) ? this.files.get(fp2) : '';
this.files.set(fp2, prev ? prev + '\n' + (capture || '') : (capture || ''));
}
return true;
};
Shell.prototype.key = function (d) {
if (this.busy) return;
var t = this.t;
if (d === '\r') { t.write('\r\n'); var l = this.line; this.line = ''; if (l.trim()) { this.hist.push(l); } this.hi = this.hist.length; this.exec(l); this.prompt(); return; }
if (d === '\x7f') { if (this.line) { this.line = this.line.slice(0, -1); t.write('\b \b'); } return; }
if (d === '\x03') { t.write('^C\r\n'); this.line = ''; this.prompt(); return; }
if (d === '\x0c') { t.clear(); return; }
if (d === '\x1b[A' || d === '\x1b[B') {
if (!this.hist.length) return;
this.hi = Math.max(0, Math.min(this.hist.length, this.hi + (d === '\x1b[A' ? -1 : 1)));
var h = this.hist[this.hi] || '';
t.write('\b \b'.repeat(this.line.length)); this.line = h; t.write(h); return;
}
if (d[0] === '\x1b') return;
var clean = d.replace(/[\x00-\x1f]/g, ''); this.line += clean; t.write(clean);
};
Shell.prototype.demo = function (cmds, loop) {
var self = this, reduce = window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)').matches;
this.busy = true;
var i = 0;
function next() {
if (i >= cmds.length) {
if (!loop || reduce) return;
return setTimeout(function () { self.t.clear(); self.t.write('\x1b[2J\x1b[H'); self.cwd = self.home; self.dirs = new Set(['/', '/home', self.home, '/etc', '/tmp', '/var', '/var/log']); self.files.forEach(function (v, k) { if (k.indexOf(self.home + '/') === 0 && k !== self.home + '/.bashrc') self.files.delete(k); }); i = 0; self.prompt(); setTimeout(next, 600); }, 3500);
}
var c = cmds[i++], j = 0;
if (reduce) { self.t.write(c + '\r\n'); self.exec(c); self.prompt(); return next(); }
(function type() {
if (j < c.length) { self.t.write(c[j++]); return setTimeout(type, 40 + Math.random() * 50); }
setTimeout(function () { self.t.write('\r\n'); self.exec(c); self.prompt(); setTimeout(next, 900); }, 300);
})();
}
setTimeout(next, 700);
};
function mount(el, o) {
o = o || {};
var term = new window.Terminal({
theme: THEME, fontFamily: '"IBM Plex Mono", ui-monospace, monospace', fontSize: o.fontSize || 14,
lineHeight: 1.25, cursorBlink: true, cursorStyle: 'block', scrollback: 500, convertEol: false,
disableStdin: !!o.demo, allowTransparency: false
});
var fit = window.FitAddon ? new window.FitAddon.FitAddon() : null;
if (fit) term.loadAddon(fit);
term.open(el);
var fitNow = function () { try { fit && fit.fit(); } catch (e) {} };
var raf, doFit = function () { cancelAnimationFrame(raf); raf = requestAnimationFrame(fitNow); };
fitNow(); window.addEventListener('resize', doFit);
if (window.ResizeObserver) new ResizeObserver(doFit).observe(el);
var sh = new Shell(term, o);
if (o.welcome) term.write(o.welcome.replace(/\n/g, '\r\n') + '\r\n');
sh.prompt();
if (o.demo) sh.demo(o.demo, o.loop !== false);
else { term.onData(function (d) { sh.key(d); }); if (o.focus) term.focus(); }
return sh;
}
window.SyllabusTerminal = { mount: function (el, o) {
var go = function () { mount(el, o); };
(document.fonts && document.fonts.ready ? document.fonts.ready : Promise.resolve()).then(go);
} };
})();

View file

@ -0,0 +1,52 @@
(function () {
var L = window.RESSOURCES, id = new URLSearchParams(location.search).get('outil');
var R = L.find(function (r) { return r.id === id; }) || L[0];
var el = function (i) { return document.getElementById(i); };
var demo = (window.URL_DEMOS && window.URL_DEMOS[R.id]) || R.demo;
document.title = R.titre + ' · Syllabus';
el('r-titre-k').textContent = R.titre;
el('r-titre').textContent = R.accroche;
el('r-probleme').textContent = R.probleme;
el('r-pour').textContent = 'Pour : ' + R.pour;
el('r-accroche-fin').textContent = 'Essayez ' + R.titre.toLowerCase() + ' en quelques clics.';
el('r-demo').href = el('r-demo2').href = demo;
var ul = el('r-points');
R.points.forEach(function (pt) {
var li = document.createElement('li'), h = document.createElement('h3'), t = document.createElement('p');
h.style.cssText = 'margin:0;font-size:20px;font-weight:800;letter-spacing:-0.01em;color:#0b1220';
t.style.cssText = 'margin:12px 0 0;font-size:16px;line-height:1.65;font-weight:500;color:#374151';
h.textContent = pt[0]; t.textContent = pt[1]; li.appendChild(h); li.appendChild(t); ul.appendChild(li);
});
var ol = el('r-etapes');
R.etapes.forEach(function (e, i) {
var li = document.createElement('li'), n = document.createElement('span'), t = document.createElement('p');
li.style.cssText = 'display:grid;grid-template-columns:48px 1fr;align-items:baseline;gap:16px';
n.style.cssText = 'font-size:28px;font-weight:800;color:#1d5cf5;font-variant-numeric:tabular-nums';
t.style.cssText = 'margin:0;font-size:20px;line-height:1.5;font-weight:600;color:#0b1220';
n.textContent = String(i + 1).padStart(2, '0'); t.textContent = e;
li.appendChild(n); li.appendChild(t); ol.appendChild(li);
});
var box = el('r-video'), base = window.URL_VIDEOS || 'videos', reduit = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var v = document.createElement('video');
v.muted = true; v.loop = true; v.playsInline = true; v.autoplay = !reduit; v.preload = 'metadata';
v.setAttribute('aria-label', 'Démonstration vidéo : ' + R.titre);
v.style.cssText = 'display:block;width:100%;height:100%;object-fit:cover';
v.src = base + '/' + R.id + '.mp4';
var btn = document.createElement('button');
btn.type = 'button';
btn.style.cssText = 'position:absolute;right:20px;bottom:20px;width:44px;height:44px;border-radius:999px;border:0;background:rgba(255,255,255,.92);color:#0b1220;font-size:14px;font-weight:800;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,.15)';
var maj = function () { btn.textContent = v.paused ? '▶' : '❚❚'; btn.setAttribute('aria-label', v.paused ? 'Lire la vidéo' : 'Mettre en pause'); };
btn.addEventListener('click', function () { v.paused ? v.play() : v.pause(); });
v.addEventListener('play', maj); v.addEventListener('pause', maj);
v.addEventListener('error', function () {
box.innerHTML = '';
var d = document.createElement('div');
d.style.cssText = 'height:100%;display:grid;place-items:center;text-align:center;padding:32px';
d.innerHTML = '<div><p style="margin:0;font-size:18px;font-weight:700;color:#0b1220">Vidéo de démonstration</p><p style="margin:8px 0 0;font-size:14px;font-weight:600;color:#4b5563">Fichier attendu : <code>videos/' + R.id + '.mp4</code></p></div>';
box.appendChild(d);
el('r-video-legende').textContent = '';
});
box.appendChild(v); box.appendChild(btn); maj();
el('r-video-legende').textContent = R.titre + ', en conditions réelles.';
if (!reduit) { var pr = v.play(); if (pr && pr.catch) pr.catch(function () {}); }
})();

View file

@ -0,0 +1,123 @@
// Présentations des outils Syllabus (page ressource). demo = page de démonstration existante.
window.RESSOURCES = [
{ id: 'visio', cat: 'Piloter', titre: 'Visio de classe', demo: 'liste-attente.html', pour: 'Enseignants, élèves',
accroche: 'Une visio intégrée où les élèves arrivent en sourdine et ne parlent que quand vous leur donnez la parole.',
probleme: 'En classe à distance, les micros ouverts et le chat qui défile empêchent d’enseigner, et les élèves discrets n’osent pas intervenir.',
points: [['Tous en sourdine', 'Micro et caméra bloqués tant que le prof n’a pas donné la parole.'], ['File des mains levées', 'Premier arrivé en haut, avec l’étape du lab de chaque élève.'], ['Salle d’attente', 'Vous admettez chaque élève avant qu’il rejoigne la classe.'], ['Chat contrôlé', 'Désactivé par défaut, activable d’un interrupteur.']],
etapes: ['Lancez la visio depuis votre tableau de bord', 'Admettez les élèves de la salle d’attente', 'Donnez la parole depuis la file des mains levées'] },
{ id: 'cockpit', cat: 'Piloter', titre: 'Tableau de bord prof', demo: 'liste-attente.html', pour: 'Enseignants',
accroche: 'Toute la classe sur un seul écran : qui avance, qui bloque, qui a levé la main.',
probleme: 'Avec 30 élèves en TP, on ne voit que ceux qui appellent. Les élèves discrets en difficulté passent inaperçus jusqu’à l’évaluation.',
points: [['Mains levées dans l’ordre', 'La file d’attente s’affiche en temps réel avec l’étape où chaque élève bloque.'], ['Alertes de décrochage', 'Un élève qui n’avance plus ou accumule les indices est signalé, sans surveillance intrusive.'], ['Examens et devoirs en cours', 'Copies rendues, sorties de fenêtre, temps restant : tout est suivi depuis le même écran.'], ['Accès à la fiche élève', 'Un clic ouvre l’historique complet pour préparer un entretien ou un conseil de classe.']],
etapes: ['Ouvrez votre classe en début de séance', 'Suivez la progression pendant le TP', 'Repérez les élèves à accompagner en priorité'] },
{ id: 'espace-eleve', cat: 'Piloter', titre: 'Espace élève', demo: 'liste-attente.html', pour: 'Élèves et étudiants',
accroche: 'Un calendrier, les devoirs à rendre, les examens à venir et de quoi s’entraîner.',
probleme: 'Les consignes sont dispersées entre l’ENT, les mails et le tableau. L’élève ne sait pas toujours ce qu’il doit rendre ni quand.',
points: [['Calendrier unique', 'Devoirs, examens et séances de TP au même endroit, avec rappels.'], ['Progression visible', 'Compétences acquises et chapitres à revoir, chapitre par chapitre.'], ['Entraînement libre', 'Exercices et labs disponibles hors classe, corrigés automatiquement.'], ['Lever la main', 'Une demande d’aide en un clic pendant le TP.']],
etapes: ['L’élève se connecte avec ses identifiants', 'Il consulte ce qui l’attend cette semaine', 'Il s’entraîne et rend ses travaux en ligne'] },
{ id: 'vie-scolaire', cat: 'Piloter', titre: 'Vie scolaire', demo: 'liste-attente.html', pour: 'CPE, direction, intendance',
accroche: 'L’assiduité et les signaux de décrochage de tout l’établissement, classe par classe.',
probleme: 'Les informations utiles au suivi sont réparties entre les enseignants. Le CPE les découvre souvent trop tard.',
points: [['Présence aux séances en ligne', 'Connexions aux quiz, labs et examens, par classe et par élève.'], ['Signalements centralisés', 'Les alertes des enseignants arrivent au même endroit, avec leur historique.'], ['Suivi des accompagnements', 'Entretiens, contacts familles et décisions consignés.'], ['Exports', 'Données prêtes pour le conseil de classe ou le logiciel de vie scolaire.']],
etapes: ['Choisissez la classe ou le niveau', 'Repérez les élèves signalés', 'Planifiez l’accompagnement et suivez-le'] },
{ id: 'academie', cat: 'Piloter', titre: 'Académie', demo: 'liste-attente.html', pour: 'Inspection, rectorat, réseaux d’établissements',
accroche: 'Une vue agrégée de plusieurs établissements, sans aucune donnée nominative.',
probleme: 'Évaluer l’usage d’un outil ou repérer les compétences mal acquises à l’échelle d’un territoire demande de compiler des tableaux à la main.',
points: [['Indicateurs par établissement', 'Activité, labs réalisés, compétences validées.'], ['Compétences les moins acquises', 'Pour cibler les formations et les ressources.'], ['Données anonymisées', 'Uniquement des moyennes par établissement et par classe.'], ['Rapports téléchargeables', 'Bilans en PDF et en CSV.']],
etapes: ['Choisissez le périmètre', 'Comparez les établissements', 'Exportez le rapport'] },
{ id: 'cohortes', cat: 'Piloter', titre: 'Suivi des cohortes', demo: 'liste-attente.html', pour: 'Responsables de formation, scolarité',
accroche: 'La progression d’une promotion entière, semestre après semestre.',
probleme: 'Savoir si une promotion est en avance ou en retard sur le référentiel suppose de croiser les résultats de plusieurs enseignants.',
points: [['Progression par compétence', 'Taux d’acquisition de chaque bloc du référentiel.'], ['Comparaison entre promotions', 'Même formation, années différentes.'], ['Assiduité et résultats', 'Corrélés pour repérer les décrochages.'], ['Export des notes', 'CSV compatible avec les logiciels de scolarité.']],
etapes: ['Sélectionnez la promotion', 'Lisez les indicateurs par compétence', 'Exportez pour le jury ou le conseil'] },
{ id: 'espace-etablissement', cat: 'Piloter', titre: 'Espace établissement', demo: 'liste-attente.html', pour: 'Intendance, direction',
accroche: 'Licences, devis, factures et conventions au même endroit.',
probleme: 'Commander un service en ligne dans un établissement public impose devis, bon de commande, Chorus Pro et suivi des licences.',
points: [['Gestion des licences', 'Ajout et retrait d’élèves, licences utilisées et disponibles.'], ['Devis et bons de commande', 'Générés au nom de l’établissement.'], ['Factures Chorus Pro', 'Déposées automatiquement, téléchargeables en PDF.'], ['Documents contractuels', 'Conditions, DPA et convention signée.']],
etapes: ['Demandez un devis', 'Validez le bon de commande', 'Gérez les licences au fil de l’année'] },
{ id: 'integration', cat: 'Piloter', titre: 'Intégration et sécurité', demo: 'liste-attente.html', pour: 'DSI, administrateurs',
accroche: 'SSO, API, hébergement et conformité : ce que votre DSI doit vérifier.',
probleme: 'Avant d’adopter un outil, la DSI doit s’assurer de l’authentification, de la protection des données et des prérequis réseau.',
points: [['Authentification unique', 'Connexion par l’ENT ou l’annuaire de l’établissement.'], ['Hébergement en France', 'Serveurs Scaleway à Paris.'], ['RGPD', 'Registre, DPA, durées de conservation documentées.'], ['Prérequis réseau', 'Navigateur récent, accès HTTPS, aucun logiciel à installer.']],
etapes: ['Consultez la fiche technique', 'Testez la connexion depuis votre réseau', 'Échangez avec nous pour le SSO'] },
{ id: 'cours', cat: 'Apprendre', titre: 'Cours gratuits', demo: 'liste-attente.html', pour: 'Enseignants et élèves',
accroche: 'Des cours complets alignés sur les référentiels, du lycée au master.',
probleme: 'Préparer un cours technique complet prend des heures, et les ressources en ligne sont rarement adaptées au référentiel.',
points: [['Cours magistral détaillé', 'Théorie, exemples commentés, schémas et mise en situation.'], ['QCM de lecture', 'Pour vérifier que le cours a été lu et compris.'], ['TD et TP corrigés', 'Exercices progressifs et travaux pratiques sur machine.'], ['Sujets d’examen', 'Avec éléments de correction.']],
etapes: ['Choisissez le cursus', 'Ouvrez un chapitre', 'Donnez-le à lire ou projetez-le'] },
{ id: 'labs', cat: 'Apprendre', titre: 'TP sur machine Linux', demo: 'liste-attente.html', pour: 'Élèves, enseignants',
accroche: 'Une vraie machine Linux par élève, dans le navigateur, corrigée automatiquement.',
probleme: 'Installer et maintenir des machines virtuelles pour chaque élève prend du temps et dépend du matériel de la salle.',
points: [['Terminal dans le navigateur', 'Aucune installation, sur PC comme sur tablette.'], ['Étapes vérifiées', 'Chaque étape est validée automatiquement dans la machine.'], ['Indices progressifs', 'Débloqués après plusieurs essais pour encourager la réflexion.'], ['Machine réinitialisable', 'L’élève peut tout recommencer sans risque.']],
etapes: ['Lancez le lab pour la classe', 'Les élèves suivent les étapes', 'Consultez les résultats dans le tableau de bord'] },
{ id: 'lab-web', cat: 'Apprendre', titre: 'Lab web', demo: 'liste-attente.html', pour: 'Élèves, enseignants',
accroche: 'Un terminal et un navigateur reliés : on configure un serveur et on voit le résultat.',
probleme: 'Comprendre le lien entre une commande serveur et ce qu’affiche le navigateur est difficile sans les avoir côte à côte.',
points: [['Terminal et navigateur liés', 'Le navigateur affiche la machine de l’élève.'], ['Serveur réel', 'Apache, Nginx, PHP installés pour de vrai.'], ['Vérifications automatiques', 'Page servie, service actif, journaux.'], ['Idéal pour SNT, NSI, SIO', 'Du premier site au serveur HTTPS.']],
etapes: ['Ouvrez le lab', 'Installez et configurez le serveur', 'Actualisez le navigateur relié'] },
{ id: 'ide', cat: 'Apprendre', titre: 'Éditeur de code en ligne', demo: 'liste-attente.html', pour: 'Élèves, enseignants',
accroche: 'Python, SQL, web et Bash dans le navigateur, avec des exercices testés automatiquement.',
probleme: 'Installer un environnement de développement sur chaque poste et à la maison est une source d’échecs en début d’année.',
points: [['Quatre langages', 'Python, SQL, HTML/CSS/JS et Bash.'], ['Tests automatiques', 'L’élève sait immédiatement si son code est juste.'], ['Exercices progressifs', 'Du niveau découverte aux défis.'], ['Aucune installation', 'Fonctionne aussi à la maison.']],
etapes: ['Choisissez un exercice', 'L’élève code et lance les tests', 'Suivez les réussites dans le tableau de bord'] },
{ id: 'maison', cat: 'Apprendre', titre: 'Ressources à la maison', demo: 'liste-attente.html', pour: 'Élèves',
accroche: 'Pour aller plus loin chez soi : exercices, défis et plateformes reconnues.',
probleme: 'Les élèves motivés ne savent pas toujours où trouver des ressources sérieuses et adaptées à leur niveau.',
points: [['Parcours par niveau', 'Du lycée au supérieur.'], ['Plateformes reconnues', 'HackerRank, DataCamp, Root-Me, France-IOI.'], ['Défis sans prendre d’avance', 'Des notions connexes qui développent la culture générale.'], ['Suivi optionnel', 'L’enseignant voit les défis réalisés.']],
etapes: ['L’élève choisit un thème', 'Il réalise les exercices', 'Il partage sa progression s’il le souhaite'] },
{ id: 'bibliotheque', cat: 'Préparer', titre: 'Bibliothèque du prof', demo: 'liste-attente.html', pour: 'Enseignants',
accroche: 'Tous les chapitres du référentiel, avec leurs cours, QCM, TD et TP.',
probleme: 'Retrouver une ressource adaptée à un point précis du programme demande de fouiller plusieurs sites.',
points: [['Classée par référentiel', 'SNT, NSI, BTS SIO, CIEL, BUT, titres professionnels, master.'], ['Recherche', 'Par mot-clé, compétence ou type de ressource.'], ['Prêt à l’emploi', 'À projeter, imprimer ou donner en devoir.'], ['Personnalisable', 'Dupliquez et adaptez une ressource.']],
etapes: ['Choisissez le référentiel', 'Filtrez par chapitre', 'Ajoutez la ressource à votre séquence'] },
{ id: 'banque', cat: 'Préparer', titre: 'Banque de sujets', demo: 'liste-attente.html', pour: 'Enseignants',
accroche: 'Des centaines de questions et de sujets d’examen, à combiner et à adapter.',
probleme: 'Rédiger des sujets d’évaluation variés et équilibrés prend un temps considérable.',
points: [['Questions classées', 'Par chapitre, type et difficulté.'], ['Sujets blancs', 'Calqués sur les épreuves officielles.'], ['Vos questions', 'Ajoutez et partagez vos propres questions.'], ['Correction fournie', 'Éléments de correction et barème.']],
etapes: ['Recherchez des questions', 'Composez votre sujet', 'Programmez-le en examen'] },
{ id: 'generateur', cat: 'Préparer', titre: 'Générateur de TD', demo: 'liste-attente.html', pour: 'Enseignants, élèves',
accroche: 'Des exercices de calcul générés à l’infini : conversions, sous-réseaux, droits.',
probleme: 'Pour automatiser un savoir-faire, il faut beaucoup d’exercices différents, ce qu’aucun manuel ne fournit.',
points: [['Exercices aléatoires', 'Toujours nouveaux, jamais copiables.'], ['Correction immédiate', 'Avec la méthode détaillée.'], ['Niveaux réglables', 'De l’échauffement à l’approfondissement.'], ['Mode chronométré', 'Pour préparer l’examen.']],
etapes: ['Choisissez le type d’exercice', 'Réglez la difficulté', 'Lancez la série'] },
{ id: 'td-imprimable', cat: 'Préparer', titre: 'TD à imprimer', demo: 'liste-attente.html', pour: 'Enseignants',
accroche: 'Des fiches papier avec les étapes à suivre, des cases à remplir et la correction séparée.',
probleme: 'Tout ne se fait pas sur écran : certains exercices s’apprennent mieux sur papier, et la salle n’est pas toujours équipée.',
points: [['Mise en page soignée', 'Format A4, lisible en noir et blanc.'], ['Cases à remplir', 'Pour structurer la réponse.'], ['Correction à part', 'Imprimée séparément.'], ['Export PDF', 'Prêt pour la photocopieuse.']],
etapes: ['Choisissez le TD', 'Prévisualisez', 'Téléchargez le PDF'] },
{ id: 'quiz', cat: 'Évaluer', titre: 'Quiz flash', demo: 'liste-attente.html', pour: 'Enseignants, élèves',
accroche: 'Un quiz projeté en début d’heure, auquel les élèves répondent depuis leur téléphone ou leur PC.',
probleme: 'Vérifier ce qui a été retenu de la séance précédente prend du temps et ne touche que les élèves qui lèvent la main.',
points: [['Projection en classe', 'Diaporama plein écran, question par question.'], ['Réponse sur tout appareil', 'Dans le navigateur, avec les identifiants de l’élève.'], ['Présences', 'Vous voyez qui est connecté et qui manque.'], ['Résultats immédiats', 'Par question et par élève.']],
etapes: ['Choisissez ou créez un quiz', 'Projetez-le et donnez le code', 'Lisez les résultats en fin de quiz'] },
{ id: 'sujet', cat: 'Évaluer', titre: 'Créer un sujet', demo: 'liste-attente.html', pour: 'Enseignants',
accroche: 'Un sujet d’examen en cinq étapes : cadre, questions, barème, surveillance, publication.',
probleme: 'Organiser une évaluation en ligne fiable demande de penser au barème, aux aménagements et à la surveillance.',
points: [['Questions de la banque ou personnelles', 'QCM, calcul, code, lab, rédaction.'], ['Barème automatique', 'Ramené sur 20, avec pré-correction.'], ['Mode examen', 'Plein écran, détection des changements d’onglet.'], ['Aménagements', 'Tiers-temps appliqué automatiquement.']],
etapes: ['Définissez le cadre', 'Ajoutez les questions', 'Programmez l’examen'] },
{ id: 'devoirs', cat: 'Évaluer', titre: 'Devoirs maison', demo: 'liste-attente.html', pour: 'Enseignants, élèves',
accroche: 'Programmez un devoir, recevez les rendus, corrigez en ligne.',
probleme: 'Collecter des devoirs par mail ou sur clé USB, c’est des fichiers perdus, des retards non tracés et des relances.',
points: [['Programmation', 'Date d’ouverture et date limite.'], ['Rendus centralisés', 'Fichiers, code ou lab, horodatés.'], ['Relances automatiques', 'Pour les élèves en retard.'], ['Lien avec la correction', 'Les copies arrivent directement dans l’outil de correction.']],
etapes: ['Créez le devoir', 'Les élèves rendent en ligne', 'Corrigez et publiez les notes'] },
{ id: 'correction', cat: 'Évaluer', titre: 'Corriger les copies', demo: 'liste-attente.html', pour: 'Enseignants',
accroche: 'Une pré-correction selon votre barème, que vous validez et commentez.',
probleme: 'Corriger 30 copies de TP identiques prend des heures, surtout pour vérifier ce qu’une machine pourrait contrôler.',
points: [['Pré-correction', 'Calculs, commandes et code vérifiés automatiquement.'], ['Vous gardez la main', 'Rien n’est publié sans votre validation.'], ['Commentaires rapides', 'Remarques fréquentes en un clic.'], ['Navigation copie par copie', 'Avec la note recalculée à chaque ajustement.']],
etapes: ['Ouvrez le devoir', 'Validez ou ajustez la pré-correction', 'Publiez les notes'] },
{ id: 'fiche-eleve', cat: 'Suivre', titre: 'Fiche élève', demo: 'liste-attente.html', pour: 'Enseignants, CPE',
accroche: 'L’historique, les compétences et les observations d’un élève sur une seule page.',
probleme: 'Préparer un conseil de classe ou un entretien demande de rassembler des informations éparses.',
points: [['Compétences et évolution', 'Par bloc du référentiel.'], ['Historique', 'Labs, QCM, devoirs, examens.'], ['Observations partagées', 'Entre enseignants et vie scolaire.'], ['Export PDF', 'Pour le conseil de classe.']],
etapes: ['Ouvrez la fiche depuis le tableau de bord', 'Consultez l’historique', 'Ajoutez une observation'] },
{ id: 'messagerie', cat: 'Suivre', titre: 'Messagerie', demo: 'liste-attente.html', pour: 'Enseignants, élèves, CPE',
accroche: 'Des échanges encadrés entre enseignant, élève et vie scolaire.',
probleme: 'Les échanges par réseaux sociaux ou téléphone personnel sont difficiles à encadrer et à tracer.',
points: [['Conversations par élève et par classe', 'Avec la fiche élève à portée de clic.'], ['Réponses rapides', 'Envoyer un indice, joindre un cours, proposer un créneau.'], ['Pas de messages entre élèves', 'Échanges visibles par l’équipe pédagogique.'], ['Horaires conseillés', 'Pour respecter le droit à la déconnexion.']],
etapes: ['Ouvrez une conversation', 'Répondez ou joignez une ressource', 'Associez la CPE si besoin'] },
{ id: 'export', cat: 'Suivre', titre: 'Export Pronote / ENT', demo: 'liste-attente.html', pour: 'Enseignants, scolarité',
accroche: 'Notes, présences et appréciations prêtes à charger dans votre logiciel de vie scolaire.',
probleme: 'Ressaisir les notes d’un outil à l’autre est une perte de temps et une source d’erreurs.',
points: [['Fichier CSV compatible', 'Format attendu par les principaux logiciels de vie scolaire.'], ['Choix du contenu', 'Notes, moyennes par compétence, présences, appréciations.'], ['Aperçu avant export', 'Pour vérifier les colonnes.'], ['Guide d’import', 'Étapes détaillées pour chaque logiciel.']],
etapes: ['Choisissez le contenu et la période', 'Vérifiez l’aperçu', 'Téléchargez et importez le fichier'] }
];

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long