Paillasse/portail/resources/views/cours/fiche.blade.php

175 lines
51 KiB
PHP
Raw Permalink Normal View History

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Cours · Syllabus</title>
{{ Vite::fonts() }}
<script src="https://cdn.tailwindcss.com"></script>
<script>tailwind.config={theme:{extend:{fontFamily:{display:['Archivo','system-ui','sans-serif'],mono:['"IBM Plex Mono"','monospace']}}}}</script>
<style>
.etoile { clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); }
.zigzag { background: linear-gradient(135deg, transparent 50%, #000 50% 62%, transparent 62%) 0 0 / 16px 16px, linear-gradient(45deg, transparent 50%, #000 50% 62%, transparent 62%) 0 0 / 16px 16px; }
@keyframes flotte { 0%,100% { transform: translateY(0) rotate(var(--r, 0deg)); } 50% { transform: translateY(-10px) rotate(var(--r, 0deg)); } }
.flotte { animation: flotte 6s ease-in-out infinite; }
@keyframes clignote { 50% { opacity: 0; } }
.curseur { animation: clignote 1s steps(1) infinite; }
@media (prefers-reduced-motion: reduce) { .flotte, .curseur { animation: none; } }
@media print { header, footer, .no-print { display: none !important; } [data-tab-panel] { display: block !important; } }
</style>
<link rel="stylesheet" href="{{ asset('vendor/xterm/xterm.css') }}">
<script defer src="{{ asset('vendor/xterm/xterm.js') }}"></script>
<script defer src="{{ asset('vendor/xterm/addon-fit.js') }}"></script>
<script defer src="{{ asset('js/paillasse-terminal.js') }}"></script>
<link rel="stylesheet" href="{{ asset('css/syllabus-theme.css') }}">
</head>
<body class="bg-white font-display text-black antialiased">
@include('partials.apercu')
<header style="position:sticky;top:0;z-index:40;background:rgba(255,255,255,.92);backdrop-filter:saturate(180%) blur(12px);border-bottom:1px solid #e3e5e8">
<nav aria-label="Navigation principale" style="position:relative;max-width:1200px;margin:0 auto;padding:0 20px;min-height:64px;display:flex;flex-wrap:wrap;align-items:center;gap:12px 40px">
<a href="{{ route('accueil') }}" aria-label="Syllabus, accueil" style="display:flex;align-items:center;gap:0;text-decoration:none"><img src="{{ asset('images/logo-syllabus-icone.png') }}" alt="" style="height:32px;width:auto;display:block"><span style="font-family:Mulish,system-ui,sans-serif;font-weight:800;font-size:19px;color:#111827;letter-spacing:-0.01em;margin-left:-14px;position:relative">Syllabus</span></a>
<ul style="margin:0;padding:0;list-style:none;display:flex;flex-wrap:wrap;align-items:center;gap:8px 28px;flex:1;line-height:1.5"><li><details class="group"><summary @if(request()->routeIs('fonctionnalites') || request()->routeIs('ressource')) aria-current="page" @endif style="cursor:pointer;list-style:none;display:flex;align-items:center;gap:6px;height:36px;margin:-6px -12px;padding:0 12px;border-radius:999px;line-height:1.5;font-size:15px;font-weight:600;color:#0b1220" class="hover:bg-[#f1f3f4] group-open:bg-[#e8f0fe] group-open:text-[#0b57d0] aria-[current=page]:text-[#0b57d0] [&::-webkit-details-marker]:hidden">Fonctionnalités<svg aria-hidden="true" viewBox="0 0 16 16" width="16" height="16" class="transition-transform duration-200 group-open:rotate-180" style="flex:none;opacity:.7"><path d="M4 6l4 4 4-4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></summary>
<div style="position:absolute;left:20px;right:20px;top:100%;margin-top:4px;z-index:50;max-width:1160px;margin-left:auto;margin-right:auto;box-sizing:border-box;max-height:calc(100vh - 90px);overflow:auto;border-radius:20px;background:#fff;border:1px solid #e3e5e8;box-shadow:0 24px 48px -16px rgba(15,23,42,.22)">
<div class="grid grid-cols-2 sm:grid-cols-3 min-[1100px]:grid-cols-5 [&>div:last-child]:col-span-2 min-[1100px]:[&>div:last-child]:col-span-1" style="gap:1px;background:#e3e5e8"><div style="padding:22px 20px 20px;min-width:0;background:#fff"><p style="margin:0;display:flex;align-items:center;gap:10px;font-size:14px;font-weight:800;color:#0b1220"><span aria-hidden="true" style="flex:none;width:10px;height:10px;border-radius:3px;background:#0b57d0"></span>Piloter la classe</p><p style="margin:4px 0 0 20px;min-height:32px;font-size:12px;line-height:16px;font-weight:500;color:#5f6368">En direct et au quotidien</p><ul style="margin:10px 0 0 20px;padding:12px 0 0;border-top:1px solid #f1f3f4;list-style:none;display:grid;gap:2px"><li><a href="{{ route('ressource') }}?outil=cockpit" style="display:block;margin:0 -8px;padding:6px 8px;border-radius:8px;font-size:14px;line-height:1.35;font-weight:600;color:#0b1220;text-decoration:none" class="hover:bg-[#f1f3f4] hover:text-[#0b57d0]">Tableau de bord prof</a></li><li><a href="{{ route('ressource') }}?outil=visio" style="display:block;margin:0 -8px;padding:6px 8px;border-radius:8px;font-size:14px;line-height:1.35;font-weight:600;color:#0b1220;text-decoration:none" class="hover:bg-[#f1f3f4] hover:text-[#0b57d0]">Visio de classe</a></li><li><a href="{{ route('ressource') }}?outil=espace-eleve" style="display:block;margin:0 -8px;padding:6px 8px;border-radius:8px;font-size:14px;line-height:1.35;font-weight:600;color:#0b1220;text-decoration:none" class="hover:bg-[#f1f3f4] hover:text-[#0b57d0]">Espace élève</a></li><li><a href="{{ route('ressource') }}?outil=fiche-eleve" style="display:block;margin:0 -8px;padding:6px 8px;border-radius:8px;font-size:14px;line-height:1.35;font-weight:600;color:#0b1220;text-decoration:none" class="hover:bg-[#f1f3f4] hover:text-[#0b57d0]">Fiche élève</a></li><li><a href="{{ route('ressource') }}?outil=messagerie" style="display:block;margin:0 -8px;padding:6px 8px;border-radius:8px;font-size:14px;line-height:1.35;font-weight:600;color:#0b1220;text-decoration:none" class="hover:bg-[#f1f3f4] hover:text-[#0b57d0]">Messagerie</a></li></ul></div><div style="padding:22px 20px 20px;min-width:0;background:#fff"><p style="margin:0;display:flex;align-items:center;gap:10px;font-size:14px;font-weight:800;color:#0b1220"><span aria-hidden="true" style="flex:none;width:10px;height:10px;border-radius:3px;background:#137333"></span>Apprendre</p><p style="margin:4px 0 0 20px;min-height:32px;font-size:12px;line-height:16px;font-weight:500;color:#5f6368">Cours, TP et code</p><ul style="margin:10px 0 0 20px;padding:12px 0 0;border-top:1px solid #f1f3f4;list-style:none;display:grid;gap:2px"><li><a href="{{ route('ressource') }}?outil=cours" style="display:block;margin:0 -8px;padding:6px 8px;border-radius:8px;font-size:14px;line-height:1.35;font-weight:600;color:#0b1220;text-decoration:none" class="hover:bg-[#f1f3f4] hover:text-[#0b57d0]">Cours gratuits</a></li><li><a href="{{ route('ressource') }}?outil=labs" style="display:block;margin:0 -8px;padding:6px 8px;border-radius:8px;font-size:14px;line-height:1.35;font-weight:600;color:#0b1220;text-decoration:none" class="hover:bg-[#f1f3f4] hover:text-[#0b57d0]">TP sur machine Linux</a></li><li><a href="{{ route('ressource') }}?outil=lab-web" style="display:block;margin:0 -8px;padding:6px 8px;border-radius:8px;font-size:14px;line-height:1.35;font-weight:600;color:#0b1220;text-decoration:none" class="hover:bg-[#f1f3f4] hover:text-[#0b57d0]">Lab web</a></li><li><a href="{{ route('ressource') }}?outil=ide" style="display:block;margin:0 -8px;padding:6px 8px;border-radius:8px;font-size:14px;line-height:1.35;font-weight:600;color:#0b1220;text-decoration:none" class="hover:bg-[#f1f3f4] hover:text-[#0b57d0]">Éditeur de code en ligne</a></li><li><a href="{{ route('ressource') }}?outil=maison" style="display:block;margin:0 -8px;padding:6px 8px;border-radius:8px;font-size:14px;line-height:1.35;font-weight:600;color:#0b1220;text-decoration:none" class="hover:bg-[#f1f3f4] hover:text-[#0b57d0]">Ressources à la maison</a></li></ul></div><div style
<div style="position:sticky;bottom:0;padding:14px 24px;border-top:1px solid #e3e5e8;background:#f8f9fa;display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px"><span style="font-size:14px;font-weight:500;color:#5f6368">24 outils, chacun avec sa présentation et sa démo</span><a href="{{ route('fonctionnalites') }}" style="font-size:15px;font-weight:700;color:#0b57d0;text-decoration:none">Voir toutes les fonctionnalités →</a></div>
</div></details></li><li><a href="{{ route('cours.index') }}" @if(request()->routeIs('cours.index')) aria-current="page" @endif style="display:inline-flex;align-items:center;height:24px;line-height:1.5;font-size:15px;font-weight:600;color:#0b1220;text-decoration:none" class="hover:text-[#0b57d0] aria-[current=page]:text-[#0b57d0]">Cours</a></li><li><a href="{{ route('tarifs') }}" @if(request()->routeIs('tarifs')) aria-current="page" @endif style="display:inline-flex;align-items:center;height:24px;line-height:1.5;font-size:15px;font-weight:600;color:#0b1220;text-decoration:none" class="hover:text-[#0b57d0] aria-[current=page]:text-[#0b57d0]">Tarifs</a></li></ul>
<div style="display:flex;align-items:center;gap:20px">
<a href="{{ route('login') }}" style="font-size:15px;font-weight:600;color:#0b1220;text-decoration:none" class="hover:text-[#0b57d0]">Se connecter</a>
<a href="{{ route('register') }}" style="display:inline-flex;align-items:center;height:40px;padding:0 20px;border-radius:999px;background:#0b57d0;color:#fff;font-size:15px;font-weight:700;text-decoration:none">Créer une classe</a>
</div>
</nav>
</header>
<main>
<section class="border-b border-[#e3e5e8] bg-white">
<div class="mx-auto max-w-6xl px-5 py-10 lg:px-10">
<a href="{{ route('cours.index') }}" class="no-print text-sm font-extrabold underline underline-offset-4">← Tous les cours</a>
<p id="c-niveau" class="mt-4 font-mono text-xs font-semibold"></p>
<div class="min-w-0 flex-1"><p data-public="E" class="mb-2 inline-flex items-center gap-2 rounded-full border border-[#b8c1cf] bg-white px-3 py-1 text-sm font-bold text-[#0b5e3c]">Pour les élèves</p>
<h1 id="c-titre" class="mt-2 [overflow-wrap:anywhere] text-5xl font-extrabold leading-[0.95] tracking-tight">Chargement…</h1></div>
<div class="mt-4 flex flex-wrap items-center gap-3"><span id="c-duree" class="border border-[#dadce0] rounded-lg bg-[#f8f9fa] px-2 py-0.5 font-mono text-sm font-semibold"></span><span id="c-statut" class="border border-[#dadce0] rounded-lg px-2 py-0.5 text-sm font-extrabold"></span>
<button type="button" onclick="window.print()" class="no-print ml-auto inline-flex h-11 items-center gap-2 border border-[#dadce0] rounded-lg bg-[#fef7e0] px-4 text-sm font-extrabold">Télécharger en PDF</button></div>
</div>
</section>
<nav class="no-print sticky top-0 z-20 border-b border-[#e3e5e8] bg-white" aria-label="Parties du cours"><div id="c-tabs" class="mx-auto flex max-w-6xl flex-wrap gap-2 px-5 py-3 text-sm font-extrabold lg:px-10"></div></nav>
<div id="c-corps" class="mx-auto max-w-7xl px-5 py-10 lg:px-10"></div>
<script src="{{ asset('js/referentiel.js') }}"></script>
<script src="{{ asset('js/contenus.js') }}"></script>
<script src="{{ asset('js/contenus-1.js') }}"></script>
<script src="{{ asset('js/contenus-2.js') }}"></script>
<script src="{{ asset('js/contenus-3.js') }}"></script>
<script src="{{ asset('js/contenus-plus-1.js') }}"></script>
<script src="{{ asset('js/contenus-plus-2.js') }}"></script>
<script src="{{ asset('js/contenus-plus-3.js') }}"></script>
<script src="{{ asset('js/contenus-plus-4.js') }}"></script>
<script src="{{ asset('js/contenus-exemples.js') }}"></script>
<script src="{{ asset('js/contenus-long.js') }}"></script>
<script src="{{ asset('js/contenus-schemas.js') }}"></script>
<script src="{{ asset('js/contenus-reseau-1.js') }}"></script>
<script src="{{ asset('js/contenus-reseau-2.js') }}"></script>
<script src="{{ asset('js/contenus-devops-1.js') }}"></script>
<script src="{{ asset('js/contenus-devops-2.js') }}"></script>
<script src="{{ asset('js/contenus-infra-3.js') }}"></script>
<script src="{{ asset('js/contenus-data-4.js') }}"></script>
<script src="{{ asset('js/contenus-sys-5.js') }}"></script>
<script src="{{ asset('js/contenus-lot-6.js') }}"></script>
<script src="{{ asset('js/contenus-lot-7.js') }}"></script>
<script src="{{ asset('js/contenus-lot-8.js') }}"></script>
<script src="{{ asset('js/contenus-lot-9.js') }}"></script>
<script src="{{ asset('js/contenus-lot-10.js') }}"></script>
<script src="{{ asset('js/contenus-lot-11.js') }}"></script>
<script src="{{ asset('js/contenus-lot-12.js') }}"></script>
<script src="{{ asset('js/contenus-alias.js') }}"></script>
<script src="{{ asset('image-slot.js') }}"></script>
<script>
(function () {
var q = new URLSearchParams(location.search), titre = q.get('chapitre') || 'Découverte du terminal, commandes de base';
var ALL = (window.CONTENUS_PRO || []).concat(window.CONTENUS || []);
var C = ALL.find(function (c) { return c.match.test(titre); });
var X = C && window.CONTENUS_PLUS && window.CONTENUS_PLUS[C.id];
if (X && C.intro) { C = Object.assign({}, C, { cm: C.cm.concat(X.cm || []), qcm: C.qcm.concat(X.qcm || []), cas: X.cas, erreurs: X.erreurs, examen: X.examen, prof: X.prof, memo: X.memo, resolu: X.resolu, vf: X.vf }); }
var meta = null; window.REFERENTIEL.themes.forEach(function (th) { th.items.forEach(function (it) { if (!meta && it[0] === titre) meta = { theme: th.nom, tags: it[1] }; }); });
var el = function (id) { return document.getElementById(id); }, esc = function (s) { return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;'); };
var pro = C && C.intro;
el('c-titre').textContent = C ? C.titre : titre;
el('c-niveau').textContent = C ? C.niveau : (meta ? meta.theme : 'Référentiel');
el('c-duree').textContent = ''; el('c-duree').style.display = 'none';
document.title = (C ? C.titre : titre) + ' · Syllabus';
el('c-statut').textContent = C ? 'Cours complet' : 'Plan détaillé';
el('c-statut').style.background = C ? '#7CF2C0' : '#FFD23F';
var tabs; tabs = C ? [['cm', 'Cours (CM)'], ['qcm', 'QCM · ' + C.qcm.length + ' questions'], ['td', 'TD · ' + C.td.length + ' exercices'], ['tp', 'TP']].concat(C.examen ? [['exam', 'Sujet d’examen']] : []).concat(C.prof ? [['prof', 'Côté prof']] : []) : [['cm', 'Plan du cours'], ['tp', 'S’entraîner']];
var table = function (t) { return '<div class="mt-4 overflow-x-auto"><table class="w-full border-collapse border border-[#dadce0] rounded-lg text-left text-sm">' + t.map(function (r, i) { return '<tr class="' + (i ? '' : 'bg-[#f8f9fa] font-mono text-xs uppercase') + '">' + r.map(function (c) { return '<td class="border border-[#dadce0] rounded-lg px-3 py-2 ' + (i ? 'font-semibold' : 'font-semibold') + '">' + esc(c) + '</td>'; }).join('') + '</tr>'; }).join('') + '</table></div>'; };
var pre = function (s) { return '<pre class="mt-4 overflow-x-auto border border-[#dadce0] rounded-lg bg-[#13233A] p-4 font-mono text-sm leading-relaxed text-white">' + esc(s) + '</pre>'; };
var h = '';
if (C) {
var secs = pro ? C.cm : C.cm.map(function (s) { return { t: s[0], html: s[1] }; });
var syn = pro ? C.synthese : C.retenir;
h += '<div data-tab-panel="cm" class="grid gap-10 lg:grid-cols-[minmax(0,1fr)_300px]"><article class="min-w-0">';
var L = window.CONTENUS_LONG && window.CONTENUS_LONG[C.id];
var SC = window.CONTENUS_SCHEMAS && window.CONTENUS_SCHEMAS[C.id];
var HL = function (s) { if (!SC) return s; var terms = SC.termes.slice().sort(function (x, y) { return y.length - x.length; }).map(function (x) { return x.replace(/[.*+?^${}()|[\]\\\/]/g, '\\var L = window.CONTENUS_LONG && window.CONTENUS_LONG[C.id];'); }); var re = new RegExp('(<[^>]+>)|(?<![\\wÀ-ÿ.\\-/$])(' + terms.join('|') + ')(?![\\wÀ-ÿ-])', 'g'); var inCode = 0; return s.replace(re, function (m, tag, w) { if (tag) { if (/^<code/.test(tag)) inCode++; if (/^<\/code/.test(tag)) inCode--; return tag; } return inCode ? w : '<code>' + w + '</code>'; }); };
var FIG = function (i) { return SC ? SC.figs.filter(function (f) { return f[0] === i; }).map(function (f) { return '<figure class="mt-8 border border-[#dadce0] rounded-lg bg-white p-5">' + f[2] + '<figcaption class="mt-3 flex gap-2 border-t border-[#e3e5e8] pt-3 text-sm font-semibold"><span class="bg-black px-1.5 font-mono text-xs text-white">SCHÉMA</span>' + f[1] + '</figcaption></figure>'; }).join('') : ''; };
if (pro) h += '<p class="max-w-3xl text-2xl font-medium leading-relaxed">' + C.intro + '</p>';
if (L) h += '<figure class="mt-10 border border-[#dadce0] rounded-lg bg-white p-5">' + L.figure + '<figcaption class="mt-3 border-t border-[#e3e5e8] pt-3 text-sm font-semibold">Schéma · ' + L.legende + '</figcaption></figure>' +
'<section class="mt-12"><p class="font-mono text-xs font-semibold uppercase">Lecture</p><h2 class="mt-2 text-3xl font-extrabold">Pour bien comprendre</h2><div class="mt-6 grid max-w-3xl gap-6 text-lg font-medium leading-[1.8] [&_code]:whitespace-nowrap [&_code]:border [&_code]:border-black/30 [&_code]:bg-[#E9E8E6] [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:font-mono [&_code]:text-[0.9em] [&_code]:font-semibold">' + L.lecture.map(function (p, i) { return '<p>' + HL(p) + '</p>' + (i === 1 ? '<figure class="my-4 border border-[#dadce0] rounded-lg"><div class="aspect-[16/7]"><image-slot id="photo-' + C.id + '" shape="rect" placeholder="' + L.photo + '"></image-slot></div><figcaption class="border-t border-[#e3e5e8] bg-[#f8f9fa] px-3 py-2 text-xs font-semibold">' + L.photo + '</figcaption></figure>' : ''); }).join('') + '</div></section>';
h += '<nav class="mt-8 border border-[#dadce0] rounded-lg bg-white p-5" aria-label="Sommaire"><p class="font-mono text-xs font-semibold uppercase">Sommaire</p><ol class="mt-3 grid gap-x-10 gap-y-1 sm:grid-cols-2">' + secs.map(function (s, i) { return '<li><a href="#s' + i + '" class="flex gap-2 font-bold hover:underline"><span class="font-mono">' + (i + 1) + '.</span>' + s.t + '' + '</a></li>'; }).join('') + '</ol></nav>';
h += secs.map(function (s, i) { return '<section id="s' + i + '" class="mt-12 scroll-mt-24 border-t border-[#e3e5e8] pt-8"><div class="flex flex-wrap items-baseline justify-between gap-2"><h2 class="flex items-baseline gap-3 text-3xl font-extrabold"><span class="font-mono text-lg">' + (i + 1) + '.</span>' + s.t + '</h2>' + '' + '</div>' + (s.html ? '<div class="mt-4 grid max-w-3xl gap-4 text-lg font-medium leading-[1.8] [&_code]:whitespace-nowrap [&_code]:border [&_code]:border-black/30 [&_code]:bg-[#E9E8E6] [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:font-mono [&_code]:text-[0.9em] [&_code]:font-semibold [&_b]:bg-[linear-gradient(transparent_58%,#FFD23F_58%)] [&_b]:font-extrabold">' + s.html.split(/<br><br>|<br><b>/).map(function (p, k) { return '<p>' + HL((k && s.html.indexOf('<br><b>') > -1 && p.indexOf('</b>') > -1 && p.indexOf('<b>') === -1 ? '<b>' : '') + p) + '</p>'; }).join('') + '</div>' : '') + (s.table ? table(s.table) : '') + (s.exemple ? '<p class="mt-5 font-mono text-xs font-semibold uppercase">Exemple</p>' + pre(s.exemple) : '') + (s.attention ? '<div class="mt-5 flex gap-3 border border-[#dadce0] rounded-lg bg-[#fef7e0] p-4"><span class="font-extrabold">⚠</span><p class="font-semibold"><b>Attention.</b> ' + HL(s.attention) + '</p></div>' : '') + FIG(i) + '</section>'; }).join('');
if (C.cas && !C.resolu) h += '<section class="mt-12 border border-[#dadce0] rounded-lg bg-[#eef0fd] p-6"><p class="font-mono text-xs font-semibold uppercase">Mise en situation professionnelle</p><h2 class="mt-2 text-2xl font-extrabold">' + C.cas.titre + '</h2><p class="mt-3 text-lg font-medium leading-relaxed">' + C.cas.texte + '</p></section>';
if (C.erreurs) h += '<section class="mt-8 border border-[#dadce0] rounded-lg bg-white p-6"><h2 class="text-2xl font-extrabold">Erreurs fréquentes</h2><ul class="mt-4 grid gap-2 sm:grid-cols-2">' + C.erreurs.map(function (e) { return '<li class="flex gap-3 border border-[#dadce0] rounded-lg bg-[#f8f9fa] p-3 font-semibold"><span class="font-extrabold text-[#b3001b]">✕</span>' + esc(e) + '</li>'; }).join('') + '</ul></section>';
var EX = window.CONTENUS_EXEMPLES && window.CONTENUS_EXEMPLES[C.id];
if (EX) h += '<section class="mt-12"><p class="font-mono text-xs font-semibold uppercase">En pratique</p><h2 class="mt-2 text-3xl font-extrabold">' + EX.length + ' exemples commentés</h2><p class="mt-2 max-w-3xl text-lg font-medium">Des situations réelles, la commande ou le code, ce que l’on obtient et pourquoi.</p><div class="mt-6 grid gap-6 xl:grid-cols-2">' + EX.map(function (e, i) { return '<article class="flex flex-col border border-[#dadce0] rounded-lg bg-white"><div class="flex items-start gap-3 border-b border-[#e3e5e8] p-4"><span class="grid h-9 w-9 shrink-0 place-items-center border border-[#dadce0] rounded-lg bg-[#fef7e0] font-mono text-sm font-semibold">' + (i + 1) + '</span><div><h3 class="text-lg font-extrabold leading-tight">' + esc(e[0]) + '</h3><p class="mt-0.5 text-sm font-semibold">' + esc(e[1]) + '</p></div></div><div class="grid flex-1 gap-3 p-4"><div><p class="font-mono text-[11px] font-semibold uppercase">Commande / code</p><pre class="mt-1 overflow-x-auto border border-[#dadce0] rounded-lg bg-[#13233A] p-3 font-mono text-sm text-white">' + esc(e[2]) + '</pre></div><div><p class="font-mono text-[11px] font-semibold uppercase">Résultat</p><pre class="mt-1 overflow-x-auto whitespace-pre-wrap border border-[#dadce0] rounded-lg bg-[#E9E8E6] p-3 font-mono text-sm font-semibold">' + esc(e[3]) + '</pre></div><p class="flex gap-2 border-t border-[#e3e5e8] pt-3 font-medium leading-relaxed [&_code]:whitespace-nowrap [&_code]:border [&_code]:border-black/30 [&_code]:bg-[#E9E8E6] [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:font-mono [&_code]:text-[0.9em] [&_code]:font-semibold"><span class="font-extrabold">→</span><span>' + HL(esc(e[4])) + '</span></p></div></article>'; }).join('') + '</div></section>';
if (C.resolu) h += '<section class="mt-12 border border-[#dadce0] rounded-lg bg-white"><div class="border-b border-[#e3e5e8] bg-[#fef7e0] p-5"><p class="font-mono text-xs font-semibold uppercase">Mise en situation · incident en production résolu pas à pas</p><h2 class="mt-2 text-2xl font-extrabold">' + esc(C.resolu.enonce) + '</h2></div><ol class="divide-y divide-[#e3e5e8]">' + C.resolu.etapes.map(function (e, i) { return '<li class="grid gap-3 p-5 sm:grid-cols-[48px_200px_minmax(0,1fr)]"><span class="grid h-10 w-10 place-items-center border border-[#dadce0] rounded-lg bg-black font-mono font-semibold text-white">' + (i + 1) + '</span><p class="text-lg font-extrabold">' + e[0].replace(/^\d+\s*·\s*/, '') + '</p><pre class="overflow-x-auto whitespace-pre-wrap border border-[#dadce0] rounded-lg bg-[#E9E8E6] p-3 font-mono text-sm font-semibold">' + esc(e[1]) + '</pre></li>'; }).join('') + '</ol></section>';
if (C.memo) h += '<section class="mt-12"><div class="flex flex-wrap items-center justify-between gap-3"><h2 class="text-2xl font-extrabold">Fiche mémo</h2><button type="button" onclick="window.print()" class="border border-[#dadce0] rounded-lg bg-white px-3 py-1.5 text-sm font-extrabold hover:bg-[#f8f9fa]">Imprimer la fiche</button></div>' + table(C.memo).replace('mt-4', 'mt-4 [&_tr:not(:first-child)_td:nth-child(2)]:font-mono') + '</section>';
if (false && C.vf) h += '<section class="mt-12 border border-[#dadce0] rounded-lg bg-[#eef0fd] p-6"><h2 class="text-2xl font-extrabold">Vrai ou faux&nbsp;?</h2><p class="mt-1 font-semibold">Quatre affirmations pour vérifier que vous avez bien lu.</p><ol class="mt-5 grid gap-3">' + C.vf.map(function (v, i) { return '<li class="border border-[#dadce0] rounded-lg bg-white p-4" data-vf="' + v[1] + '"><p class="font-bold">' + HL(esc(v[0])) + '</p><div class="mt-3 flex flex-wrap items-center gap-2"><button type="button" data-r="1" class="h-9 border border-[#dadce0] rounded-lg px-4 text-sm font-extrabold hover:bg-[#f8f9fa]">Vrai</button><button type="button" data-r="0" class="h-9 border border-[#dadce0] rounded-lg px-4 text-sm font-extrabold hover:bg-[#f8f9fa]">Faux</button><span class="hidden text-sm font-semibold" data-e>' + esc(v[2]) + '</span></div></li>'; }).join('') + '</ol></section>';
h += '<section class="mt-12 border border-[#dadce0] rounded-lg bg-black p-6 text-white"><h2 class="text-2xl font-extrabold">Synthèse</h2><ul class="mt-4 grid gap-2 font-semibold">' + syn.map(function (x) { return '<li class="flex gap-3"><span class="text-[#FFD23F]">■</span>' + x + '</li>'; }).join('') + '</ul></section></article>';
h += '<aside class="grid content-start gap-4 lg:sticky lg:top-20 lg:self-start">' + (pro ? '<div class="border border-[#dadce0] rounded-lg bg-white p-4"><p class="font-extrabold">Prérequis</p><ul class="mt-2 grid gap-1 text-sm font-semibold">' + C.prerequis.map(function (o) { return '<li>· ' + o + '</li>'; }).join('') + '</ul></div>' : '') + '<div class="border border-[#dadce0] rounded-lg bg-white p-4"><p class="font-extrabold">Objectifs</p><ul class="mt-2 grid gap-2 text-sm font-semibold">' + (C.objectifs || []).map(function (o) { return '<li class="flex gap-2"><span>■</span>' + o + '</li>'; }).join('') + '</ul></div>' + (pro ? '<div class="border border-[#dadce0] rounded-lg bg-[#f8f9fa] p-4"><p class="font-extrabold">Référentiel</p><ul class="mt-2 grid gap-2 text-xs font-semibold">' + C.competences.map(function (o) { return '<li>' + o + '</li>'; }).join('') + '</ul></div>' : '') + '</aside></div>';
h += '<div data-tab-panel="qcm" class="hidden"><p class="text-lg font-semibold">Une seule bonne réponse par question. L’explication s’affiche après votre choix.</p><ol class="mt-6 grid gap-6">' + C.qcm.map(function (x, i) { return '<li class="border border-[#dadce0] rounded-lg bg-white p-5" data-q="' + i + '"><p class="text-lg font-extrabold">' + (i + 1) + '. ' + esc(x[0]) + '</p><div class="mt-3 grid gap-2 sm:grid-cols-2">' + x[1].map(function (o, j) { return '<button type="button" data-j="' + j + '" class="border border-[#dadce0] rounded-lg bg-white p-3 text-left font-semibold hover:bg-[#f8f9fa]"><span class="mr-2 font-mono">' + 'ABCD'[j] + '</span>' + esc(o) + '</button>'; }).join('') + '</div><p class="mt-3 hidden border border-[#dadce0] rounded-lg bg-[#f8f9fa] p-3 text-sm font-semibold" data-expl>' + esc(x[3]) + '</p></li>'; }).join('') + '</ol><p id="c-score" class="mt-6 text-2xl font-extrabold" aria-live="polite"></p></div>';
var niv = { 'Échauffement': '#7CF2C0', 'Application': '#FFD23F', 'Approfondissement': '#FF6FB5' };
var tds = C.td.map(function (x) { return Array.isArray(x) ? { n: 'Application', c: x[0], r: x[1] } : x; });
h += '<div data-tab-panel="td" class="hidden"><div class="flex flex-wrap gap-3 text-xs font-extrabold">' + Object.keys(niv).map(function (k) { return '<span class="flex items-center gap-2"><span class="h-3 w-3 border border-[#dadce0] rounded-lg" style="background:' + niv[k] + '"></span>' + k + '</span>'; }).join('') + '</div><ol class="mt-6 grid gap-6">' + tds.map(function (x, i) { return '<li class="border border-[#dadce0] rounded-lg bg-white p-5"><div class="flex flex-wrap items-center gap-3"><p class="text-lg font-extrabold">Exercice ' + (i + 1) + '</p><span class="border border-[#dadce0] rounded-lg px-2 py-0.5 text-xs font-extrabold" style="background:' + (niv[x.n] || '#fff') + '">' + x.n + '</span></div><p class="mt-2 text-lg font-medium">' + esc(x.c) + '</p><div class="mt-3 h-24 border-2 border-dashed border-black"></div><details class="mt-3"><summary class="cursor-pointer font-extrabold underline underline-offset-4">Voir la correction</summary>' + pre(x.r) + '</details></li>'; }).join('') + '</ol><a href="apercu-td-imprimable.html" class="mt-6 inline-flex h-11 items-center border border-[#dadce0] rounded-lg bg-white px-4 text-sm font-extrabold hover:bg-[#f8f9fa]">Version à imprimer avec cases →</a></div>';
} else {
var parts = titre.split(/\s*[:,;·]\s*|\s+et\s+/).filter(function (s) { return s.length > 1; });
var KW = { ipv6: /ipv6/i, projet: /projet|sa[ée]|scrum|agile|itil|pilpro|erp|management|gestion|lean|comptabilit|cejm|épreuve|examen|grand oral|sre|observabilit/i, maths: /math|signal|transmission|modulation|suite|matrice|probab|fourier|complexe|ensemble|trigonom|intégral|différenti|numérisation|décibel/i, fichiers: /fichier|nfs|ftp|ntp|temps|glpi|inventaire|bonding|agrégation|tssr|ais|maintenir|infrastructure/i, archi: /architecture|processeur|mémoire|matériel|composant|machine|système d’exploitation|os\b/i, iot: /iot|node-red|modbus|coap|chaîne d’information|chaîne d’énergie|objet|capteur|embarqué|électronique|microcontr|arduino|esp32|mqtt|domotique/i, voip: /voip|téléphon|sip|voix|toip|visioconf/i, pandas: /pandas|donnée|data|statistique|tableau|csv|visualis/i, ml: /éthique|biais|ai act|kafka|spark|flux temps réel|distribué|apprentissage|machine learning|\bia\b|intelligence artificielle|modèle|knn|voisins|prédict/i, neurones: /neurone|deep|ocr|vocal|image|vision|langage/i, k8s: /kubernetes|orchestr|cloud|cluster/i, supervision: /supervision|monitoring|zabbix|prometheus|snmp|journalisation|logs centralis/i, annuaire: /ldap|active directory|annuaire|gpo|samba|identit|authentification|kerberos/i, git: /\bgit\b|version|collabor/i, cicd: /ci\/cd|pipeline|intégration continue|déploiement/i, docker: /docker|conteneur|virtualisation|devops|devcloud|cloud/i, compose: /compose/i, ansible: /ansible|iac|automatis|ci\/cd|pipeline/i, binaire: /binaire|hexa|représentation|entiers|codage/i, terminal: /terminal|linux|shell|commande|debian|système|fichiers|cp, mv|cat, less|nano|vim|processus|systemd|journalctl|apt|paquets|tar|archiv|compression|cron|planification|performance|noyau|démarrage|grub|sauvegarde|rsync|lvm/i, droits: /droits|permission|utilisateur|groupe|chmod|compte/i, tubes: /bash|script|grep|journaux|log|automatis|expressions régulières|regex/i, osi: /osi|tcp\/ip|couche|encapsulation|réseau|protocole|internet/i, sql: /sql|données|base|requête|mcd|merise|relationnel|group by|agrégats|ddl|dml|create|insert|vues|procédures|triggers|transactions|acid|index|explain|normalisation|réplication/i, python: /python|programm|algorithm|développ|code|fonction|listes|tuples|dictionnaires|chaînes|récursiv|tests|pytest|tris|dichotom|complexité|piles|graphes|pandas|json|csv|types construits/i, web: /web|photographie|pixel|rvb|exif|gps|nmea|cartographie|histoire|anglais|html|css|http|site|cms|apache|php|javascript|nginx|reverse proxy|proxy|api rest|laravel|mvc|oauth|authentification|framework/i, crypto: /crypto|sécurité|cyber|chiffr|mot de passe|ssh|tls|certificat|rgpd|gpg|vpn|wireguard|ipsec|fail2ban|force brute|nmap|scan|vulnérab|cve|ids|suricata|anssi|menaces|hameçonnage|rançongiciel|iso 27001|ebios|pssi|nis2|ctf|dmz|hygiène/i, diagnostic: /diagnostic|dépannage|incident|ping|supervision|maintenance|arp|tcp et udp|ss\b|tcpdump|pcap|trames|analyse de trames/i, ipv4: /ipv4|adressage|masque|cidr|sous-réseau|vlsm|plan d/i, vlan: /vlan|802\.1q|commutation|switch|ethernet|trunk/i, dhcp: /dhcp|bail|adresse automatique/i, dns: /dns|domaine|nom de|messagerie|postfix|dkim|dmarc/i, nat: /nat|pat|passerelle|pare-feu|nftables|firewall|dmz/i, routage: /routage|routeur|route|ospf|rip|interconnex|bgp|mpls|vrrp|keepalived/i };
var PRO = ALL.filter(function (c) { return c.intro; }), vus = {}, lies = [];
[titre].concat(parts).forEach(function (p) { PRO.forEach(function (c) { if (!vus[c.id] && (c.match.test(p) || (KW[c.id] && KW[c.id].test(p)))) { vus[c.id] = 1; lies.push(c); } }); });
var carte = function (c) { return '<li><a href="{{ route('cours.fiche') }}?chapitre=' + encodeURIComponent(c.titre) + '" class="flex h-full flex-col border border-[#dadce0] rounded-lg bg-white p-5 hover:bg-[#f8f9fa]"><span class="self-start border border-[#dadce0] rounded-lg bg-[#e6f4ea] px-2 py-0.5 font-mono text-[11px] font-semibold uppercase">Module complet</span><span class="mt-3 text-xl font-extrabold leading-tight">' + esc(c.titre) + '</span><span class="mt-2 text-sm font-semibold">' + esc(c.niveau) + '</span><span class="mt-3 flex-1 font-medium leading-relaxed">' + esc(c.intro.slice(0, 260).replace(/\s\S*$/, '')) + '…</span><span class="mt-4 text-sm font-extrabold">' + c.cm.length + ' parties de cours · ' + c.qcm.length + ' questions · ' + c.td.length + ' exercices →</span></a></li>'; };
h += '<div data-tab-panel="cm">' + (lies.length ? '<p class="max-w-3xl text-xl font-medium leading-relaxed">Ce chapitre s’appuie sur ' + lies.length + ' module' + (lies.length > 1 ? 's' : '') + ' complet' + (lies.length > 1 ? 's' : '') + ' : cours détaillé, exemples commentés, incident résolu, fiche mémo, QCM et TD corrigés.</p><ul class="mt-8 grid gap-6 md:grid-cols-2">' + lies.map(carte).join('') + '</ul>' : '<div class="max-w-3xl border border-[#dadce0] rounded-lg bg-[#f8f9fa] p-6"><p class="text-xl font-extrabold">Module en cours de rédaction</p><p class="mt-2 font-semibold">Le cours complet de ce chapitre n’est pas encore publié. Retrouvez les modules déjà disponibles dans la bibliothèque.</p><a href="{{ route('bibliotheque') }}" class="mt-4 inline-flex h-11 items-center border border-[#dadce0] rounded-lg bg-white px-4 text-sm font-extrabold hover:bg-[#0b57d0] hover:text-white">Voir la bibliothèque →</a></div>') + '</div>';
tabs = [['cm', lies.length ? 'Modules du chapitre' : 'Cours'], ['tp', 'S’entraîner']];
}
var tp = C ? C.tp : { type: meta && /IDE/.test(meta.tags) ? 'IDE' : 'Lab VM', url: meta && /IDE/.test(meta.tags) ? 'apercu-ide.html' : 'apercu-labs.html', desc: 'Mettre en pratique sur une vraie machine, corrigé automatiquement.' };
h += '<div data-tab-panel="tp" class="hidden"><div class="grid gap-6 lg:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]"><div class="border border-[#dadce0] rounded-lg bg-[#13233A] p-6 text-white"><p class="font-mono text-xs font-semibold uppercase">' + tp.type + '</p><p class="mt-2 text-2xl font-extrabold">Travaux pratiques</p><p class="mt-2 font-semibold">' + tp.desc + '</p>' + (tp.etapes ? '<ol class="mt-5 grid gap-2">' + tp.etapes.map(function (e, i) { return '<li class="flex gap-3 border-2 border-white p-2 font-semibold"><span class="font-mono">' + (i + 1) + '</span>' + e + '</li>'; }).join('') + '</ol>' : '') + '<a href="' + tp.url + '" class="mt-6 inline-flex h-12 items-center border border-[#dadce0] rounded-lg bg-[#fef7e0] px-5 font-extrabold text-black">Lancer le TP →</a></div>' +
'<div class="border border-[#dadce0] rounded-lg bg-white p-6"><p class="font-mono text-xs font-semibold uppercase">Pour aller plus loin</p><ul class="mt-3 divide-y divide-[#e3e5e8]">' + ((C && C.plusLoin) || [['Ressources à la maison', 'apercu-maison.html']]).map(function (l) { return '<li class="py-3">' + (l[1] ? '<a href="' + l[1] + '"' + (/^http/.test(l[1]) ? ' target="_blank" rel="noopener"' : '') + ' class="font-bold underline underline-offset-4">' + l[0] + (/^http/.test(l[1]) ? ' ↗' : '') + '</a>' : '<span class="font-bold">' + l[0] + '</span> <span class="text-xs font-semibold">· cours à venir</span>') + '</li>'; }).join('') + '</ul></div></div></div>';
if (C && C.examen) h += '<div data-tab-panel="exam" class="hidden"><div class="border border-[#dadce0] rounded-lg bg-white"><div class="flex flex-wrap items-center justify-between gap-3 border-b border-[#e3e5e8] bg-[#ec3013] p-4 text-white"><h2 class="text-2xl font-extrabold">' + C.examen.titre.replace(/ · [0-9h ]+(min)?(?= ·)/g, '').replace(/ · \d+ h( \d+)?/g, '') + '</h2><a href="apercu-sujet.html" class="border border-[#dadce0] rounded-lg bg-white px-3 py-1 text-sm font-extrabold text-black">Programmer cet examen →</a></div><ol class="divide-y divide-[#e3e5e8]">' + C.examen.q.map(function (x, i) { return '<li class="p-5"><p class="text-lg font-bold"><span class="font-mono">' + (i + 1) + '.</span> ' + esc(x) + '</p><details class="mt-3"><summary class="cursor-pointer font-extrabold underline underline-offset-4">Éléments de correction</summary>' + pre(C.examen.r[i]) + '</details></li>'; }).join('') + '</ol></div></div>';
if (C && C.prof) h += '<div data-tab-panel="prof" class="hidden"><div class="grid gap-6 lg:grid-cols-[minmax(0,1.3fr)_minmax(0,1fr)]"><section class="border border-[#dadce0] rounded-lg bg-white"><h2 class="border-b border-[#e3e5e8] bg-[#fef7e0] p-4 text-xl font-extrabold">Déroulé de séance</h2><ol class="divide-y divide-[#e3e5e8]">' + C.prof.deroule.map(function (d, k) { return '<li class="grid grid-cols-[48px_minmax(0,1fr)] gap-4 p-4"><span class="font-mono text-sm font-semibold">' + (k + 1) + '</span><span class="font-semibold">' + d[1] + '</span></li>'; }).join('') + '</ol></section><div class="grid content-start gap-6"><section class="border border-[#dadce0] rounded-lg bg-white p-5"><h2 class="text-xl font-extrabold">Différenciation</h2><p class="mt-2 font-semibold">' + C.prof.diff + '</p></section><section class="border border-[#dadce0] rounded-lg bg-white p-5"><h2 class="text-xl font-extrabold">Évaluation</h2><p class="mt-2 font-semibold">' + C.prof.eval + '</p></section><div class="flex flex-wrap gap-3"><a href="apercu-quiz-projection.html" class="border border-[#dadce0] rounded-lg bg-white px-3 py-2 text-sm font-extrabold hover:bg-[#f8f9fa]">Projeter le QCM en quiz flash</a><a href="apercu-devoirs.html" class="border border-[#dadce0] rounded-lg bg-white px-3 py-2 text-sm font-extrabold hover:bg-[#f8f9fa]">Donner le TD en devoir</a></div></div></div></div>';
el('c-corps').innerHTML = h;
el('c-tabs').innerHTML = tabs.map(function (t, i) { return '<button type="button" data-tab="' + t[0] + '" class="h-10 border border-[#dadce0] rounded-lg px-4 ' + (i ? 'bg-white' : 'bg-[#0b57d0] text-white') + '">' + t[1] + '</button>'; }).join('');
document.querySelectorAll('[data-tab]').forEach(function (b) { b.addEventListener('click', function () { document.querySelectorAll('[data-tab]').forEach(function (x) { x.className = 'h-10 border border-[#dadce0] rounded-lg px-4 ' + (x === b ? 'bg-[#0b57d0] text-white' : 'bg-white'); }); document.querySelectorAll('[data-tab-panel]').forEach(function (p) { p.classList.toggle('hidden', p.dataset.tabPanel !== b.dataset.tab); }); window.scrollTo({ top: 0, behavior: 'smooth' }); }); });
document.querySelectorAll('[data-vf]').forEach(function (li) { li.querySelectorAll('[data-r]').forEach(function (btn) { btn.addEventListener('click', function () { var ok = btn.dataset.r === li.dataset.vf; btn.style.background = ok ? '#7CF2C0' : '#FF6FB5'; var e = li.querySelector('[data-e]'); e.classList.remove('hidden'); e.textContent = (ok ? '✓ ' : '✕ ') + e.textContent.replace(/^[✓✕] /, ''); }); }); });
var bons = 0, faits = 0;
document.querySelectorAll('[data-q]').forEach(function (li) { var x = C.qcm[+li.dataset.q]; li.querySelectorAll('[data-j]').forEach(function (b) { b.addEventListener('click', function () { if (li.dataset.done) return; li.dataset.done = 1; faits++; if (+b.dataset.j === x[2]) bons++; li.querySelectorAll('[data-j]').forEach(function (o) { var j = +o.dataset.j; o.style.background = j === x[2] ? '#7CF2C0' : (o === b ? '#FF6FB5' : '#fff'); }); li.querySelector('[data-expl]').classList.remove('hidden'); if (faits === C.qcm.length) el('c-score').textContent = 'Score : ' + bons + ' / ' + faits + (bons / faits >= .75 ? ' · notion acquise' : ' · relisez le cours'); }); }); });
})();
</script>
</main>
<footer style="background:#f8f9fa;border-top:1px solid #e3e5e8;font-family:Mulish,system-ui,sans-serif">
<div class="mx-auto grid max-w-7xl gap-10 px-5 py-14 sm:grid-cols-2 lg:grid-cols-4 lg:px-10">
<div>
<p style="margin:0;font-size:18px;font-weight:800;color:#0b1220">Syllabus</p>
<p style="margin:10px 0 0;font-size:14px;line-height:1.6;font-weight:500;color:#5f6368">Cours, labs, IDE et examens en ligne, du lycée au master.</p>
</div>
<nav aria-label="Produit"><p style="margin:0;font-size:13px;font-weight:800;color:#0b1220">Produit</p><ul style="margin:14px 0 0;padding:0;list-style:none;display:grid;gap:10px"><li><a href="{{ route('fonctionnalites') }}" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Fonctionnalités</a></li><li><a href="{{ route('cours.index') }}" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Cours gratuits</a></li><li><a href="{{ route('labs.essai') }}" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Essayer un lab</a></li><li><a href="{{ route('tarifs') }}" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Tarifs</a></li></ul></nav><nav aria-label="Outils"><p style="margin:0;font-size:13px;font-weight:800;color:#0b1220">Outils</p><ul style="margin:14px 0 0;padding:0;list-style:none;display:grid;gap:10px"><li><a href="{{ route('ressource') }}?outil=cockpit" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Tableau de bord prof</a></li><li><a href="{{ route('ressource') }}?outil=labs" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">TP sur machine Linux</a></li><li><a href="{{ route('ressource') }}?outil=ide" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Éditeur de code</a></li><li><a href="{{ route('ressource') }}?outil=quiz" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Quiz flash</a></li><li><a href="{{ route('ressource') }}?outil=sujet" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Examens</a></li><li><a href="{{ route('ressource') }}?outil=bibliotheque" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Bibliothèque du prof</a></li></ul></nav><nav aria-label="Établissements"><p style="margin:0;font-size:13px;font-weight:800;color:#0b1220">Établissements</p><ul style="margin:14px 0 0;padding:0;list-style:none;display:grid;gap:10px"><li><a href="{{ route('etablissements') }}" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Équiper une classe</a></li><li><a href="{{ route('ressource') }}?outil=vie-scolaire" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Vie scolaire</a></li><li><a href="{{ route('ressource') }}?outil=espace-etablissement" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Licences et factures</a></li><li><a href="{{ route('ressource') }}?outil=integration" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Intégration et sécurité</a></li></ul></nav><nav aria-label="Syllabus"><p style="margin:0;font-size:13px;font-weight:800;color:#0b1220">Syllabus</p><ul style="margin:14px 0 0;padding:0;list-style:none;display:grid;gap:10px"><li><a href="{{ route('aide') }}" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Aide et tutoriels</a></li><li><a href="{{ route('legal') }}" style="font-size:14px;font-weight:500;color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Mentions légales et RGPD</a></li></ul></nav>
<p style="margin:0;align-self:start;font-size:14px;font-weight:600;color:#5f6368"><span style="color:#137333">●</span> Tous les services fonctionnent</p>
</div>
<div style="border-top:1px solid #e3e5e8"><ul aria-label="Engagements" style="max-width:1200px;margin:0 auto;padding:24px 20px;list-style:none;display:flex;flex-wrap:wrap;gap:12px 40px"><li style="font-size:14px;font-weight:700;color:#0b1220">Hébergé en France</li><li style="font-size:14px;font-weight:700;color:#0b1220"><a href="{{ route('confidentialite') }}" style="color:#0b1220">Conforme au RGPD</a> <span style="font-weight:500;color:#5f6368">· données minimisées</span></li><li style="font-size:14px;font-weight:700;color:#0b1220">6 cursus <span style="font-weight:500;color:#5f6368">· du lycée au BUT</span></li><li style="font-size:14px;font-weight:700;color:#0b1220">0 € <span style="font-weight:500;color:#5f6368">· sans carte bancaire</span></li></ul>
</div>
<div style="border-top:1px solid #e3e5e8">
<div class="mx-auto flex max-w-7xl flex-wrap items-center justify-center gap-x-6 gap-y-2 px-5 py-4 lg:px-10"><nav aria-label="Informations légales"><ul class="flex flex-wrap justify-center gap-x-5 gap-y-1" style="margin:0;padding:0;list-style:none;font-size:14px;font-weight:500"><li><a href="{{ route('legal') }}#mentions" style="color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Mentions légales</a></li><li><a href="{{ route('legal') }}#cgu" style="color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">CGU</a></li><li><a href="{{ route('confidentialite') }}#confidentialite" style="color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Confidentialité et RGPD</a></li><li><a href="{{ route('confidentialite') }}#cookies" style="color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Cookies</a></li><li><a href="{{ route('confidentialite') }}#sous-traitance" style="color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Sous-traitance</a></li><li><a href="{{ route('statut') }}" style="color:#5f6368;text-decoration:none" class="hover:text-[#0b57d0]">Statut du service</a></li></ul></nav></div>
</div>
</footer>
</body>
</html>