first commit ever

This commit is contained in:
lrdlg
2026-09-07 07:49:21 +02:00
commit 0f60998ca8
18 changed files with 2568 additions and 0 deletions
BIN
View File
Binary file not shown.
+25
View File
@@ -0,0 +1,25 @@
Images à déposer dans ce dossier
================================
peripheriques.html
periph.jpg Poste de travail complet : unité centrale à gauche, écran au
centre avec webcam au-dessus, haut-parleurs de part et d'autre,
clavier et souris devant, imprimante à droite.
Paysage, environ 1600 x 1000 px.
Si le cadrage diffère, ajuster les valeurs left/top des
boutons .hs-dot dans peripheriques.html (positions en %).
vocabulaire.html
bureau.png Bureau Windows complet (icônes, fond d'écran, barre des tâches).
barre-taches.png Gros plan de la barre des tâches seule, format large.
menu-demarrer.png Menu Démarrer ouvert, bouton Démarrer entouré en rouge.
dossier.png Icône d'un dossier fermé (type « Mes documents »).
dossier-interieur.png Intérieur d'un dossier : un sous-dossier et trois fichiers
de types différents.
souris.jpg Photo ou illustration d'une souris d'ordinateur.
trackpad.jpg Main posée sur le pavé tactile d'un portable.
navigateurs.png Logos Chrome, Edge, Firefox, Opera, Safari en bande.
onglets.png Haut d'un navigateur : deux onglets, bouton +, barre d'adresse.
Tant qu'une image est absente, la page affiche un cadre hachuré indiquant
le nom du fichier attendu et ce qu'il doit contenir. Rien ne casse.
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

+128
View File
@@ -0,0 +1,128 @@
/* ==========================================================
M. Courcelle — Labo Ordinateur
Menubar + menu mobile + pied de page, injectés dans chaque page.
Un seul endroit à modifier pour toutes les pages.
========================================================== */
(function () {
/* ── Structure du menu ──
Modifier ici pour ajouter une page. Les entrées sans "href"
s'affichent en grisé (« bientôt »). */
const MENU = [
{
label: "L'Ordinateur",
items: [
{ label: "Labo Ordinateur", href: "index.html", shortcut: "index" },
{ sep: true },
{ label: "Les périphériques", href: "peripheriques.html" },
{ label: "Vocabulaire de base", href: "vocabulaire.html" }
]
},
{
label: "Dactylographie",
items: [ { label: "Le clavier" }, { label: "Exercices et jeux" } ]
},
{
label: "Cybersécurité",
items: [ { label: "Les mots de passe" }, { label: "Le phishing" } ]
}
];
const stripes = ['as1','as2','as3','as4','as5','as6']
.map(c => `<div class="${c}"></div>`).join('');
function ddItem(it) {
if (it.sep) return '<div class="mb-dd-sep"></div>';
const sc = it.shortcut ? `<span class="mb-dd-shortcut">${it.shortcut}</span>` : '';
if (!it.href) {
return `<span class="mb-dd-item dim">${it.label}<span class="mb-dd-shortcut">bientôt</span></span>`;
}
return `<a class="mb-dd-item" href="${it.href}">${it.label}${sc}</a>`;
}
const menubar = `
<div class="menubar">
<div class="apple-stripes">${stripes}</div>
<a class="mb-logo" href="index.html">M. Courcelle</a>
${MENU.map(m => `
<div class="mb-item">
<span class="mb-trigger">${m.label}</span>
<div class="mb-dropdown">${m.items.map(ddItem).join('')}</div>
</div>`).join('')}
<button class="mb-hamburger" id="mb-hamburger" aria-label="Menu">
<span></span><span></span><span></span>
</button>
<div class="mb-right">
<button class="mb-dyslexic-btn" id="mb-dyslexic-btn">
<span class="mb-dy-dot"></span>Lisibilité
</button>
</div>
</div>
<div class="mb-mobile-menu" id="mb-mobile-menu">
${MENU.map(m => `
<div class="mb-mob-section">
<div class="mb-mob-label">${m.label}</div>
${m.items.filter(i => !i.sep).map(i => i.href
? `<a class="mb-mob-item" href="${i.href}">${i.label}</a>`
: `<span class="mb-mob-item" style="color:var(--dim)">${i.label} — bientôt</span>`
).join('')}
</div>
<div class="mb-mob-sep"></div>`).join('')}
</div>`;
const footer = `
<footer>
<div class="footer-inner">
<div>
<div class="footer-logo">
<span style="color:#E03A3E">M</span><span style="color:#F58220">.</span>&nbsp;<span style="color:#FDB827">C</span><span style="color:#61BB46">o</span><span style="color:#009DDC">u</span><span style="color:#963D97">r</span><span style="color:#E03A3E">c</span><span style="color:#F58220">e</span><span style="color:#FDB827">l</span><span style="color:#61BB46">l</span><span style="color:#009DDC">e</span>
</div>
<p class="footer-copy">© 2026 M. Courcelle — Labo Ordinateur</p>
</div>
<ul class="footer-links">
<li><a href="index.html">Accueil</a></li>
<li><a href="peripheriques.html">Les périphériques</a></li>
<li><a href="vocabulaire.html">Vocabulaire de base</a></li>
</ul>
</div>
</footer>`;
/* ── Injection ── */
document.addEventListener('DOMContentLoaded', function () {
document.body.insertAdjacentHTML('afterbegin', menubar);
document.body.insertAdjacentHTML('beforeend', footer);
// Hamburger
const btn = document.getElementById('mb-hamburger');
const menu = document.getElementById('mb-mobile-menu');
btn.addEventListener('click', function () {
const open = menu.classList.toggle('open');
btn.classList.toggle('open', open);
document.body.style.overflow = open ? 'hidden' : '';
});
// Mode lisibilité (dyslexie)
const dy = document.getElementById('mb-dyslexic-btn');
if (localStorage.getItem('courcelle_lisibilite') === '1') document.body.classList.add('dyslexic');
dy.addEventListener('click', function () {
const on = !document.body.classList.contains('dyslexic');
document.body.classList.toggle('dyslexic', on);
localStorage.setItem('courcelle_lisibilite', on ? '1' : '0');
});
// Repli visuel pour les images pas encore en place
document.querySelectorAll('img[data-todo]').forEach(function (img) {
img.addEventListener('error', function () {
const box = document.createElement('div');
box.className = 'img-todo';
box.innerHTML = '<strong>Image à placer</strong>'
+ '<span>' + img.getAttribute('src') + '</span>'
+ '<span>' + img.getAttribute('data-todo') + '</span>';
img.replaceWith(box);
});
});
});
})();
+706
View File
@@ -0,0 +1,706 @@
/* ==========================================================
M. Courcelle — Labo Ordinateur
Feuille de style autonome (aucune dépendance externe)
Encodage UTF-8
========================================================== */
:root {
/* Palette beige */
--bg: #F0EFEA;
--bg2: #E8E6E0;
--bg3: #DDDBD4;
--white: #FFFFFF;
/* Texte */
--text: #1A1A1A;
--text2: #444444;
--dim: #888888;
/* Bordures et ombres */
--border: #B0ADA8;
--border2: #CCCAC4;
--shadow: 0 8px 32px rgba(0,0,0,.10), 0 2px 6px rgba(0,0,0,.06);
--shadow-sm: 0 2px 8px rgba(0,0,0,.08);
/* Couleurs arc-en-ciel */
--apple-r: #E03A3E;
--apple-o: #F58220;
--apple-y: #FDB827;
--apple-g: #61BB46;
--apple-b: #009DDC;
--apple-p: #963D97;
--accent: #009DDC;
--accent2: #0077AA;
/* Couleurs fonctionnelles */
--c-entree: #009DDC;
--c-sortie: #F58220;
--c-uc: #963D97;
--c-ok: #61BB46;
--c-err: #E03A3E;
/* Typographie : piles système, aucune police à télécharger */
--fd: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--ft: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--fm: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
--fs-xs: 0.78rem;
--fs-sm: 0.90rem;
--fs-md: 1.00rem;
--fs-lg: 1.13rem;
--fs-xl: 1.30rem;
--fs-2xl: 1.70rem;
--radius: 8px;
--radius-lg: 12px;
--transition: all .20s ease;
--menubar-h: 30px;
--labo: #E03A3E;
}
/* Mode dyslexique : sans police externe, on agit sur l'espacement */
body.dyslexic {
--fs-md: 1.10rem;
--fs-sm: 1.00rem;
}
body.dyslexic p,
body.dyslexic li,
body.dyslexic .cat-item-text,
body.dyslexic .qcm-opt {
line-height: 2.0 !important;
letter-spacing: .04em !important;
word-spacing: .10em !important;
}
/* ── Reset ── */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
background: var(--bg);
color: var(--text);
font-family: var(--ft);
font-size: var(--fs-md);
line-height: 1.65;
display: flex; flex-direction: column;
min-height: 100vh;
overflow-x: hidden;
}
img { max-width: 100%; display: block; }
a { color: var(--accent); text-decoration: none; transition: var(--transition); }
a:hover { color: var(--accent2); }
/* ==========================================================
MENUBAR
========================================================== */
.menubar {
position: sticky; top: 0; z-index: 20000;
background: rgba(255,255,254,.94);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border-bottom: 1px solid var(--border);
height: var(--menubar-h);
display: flex; align-items: center;
padding: 0 .75rem;
user-select: none;
}
.apple-stripes {
display: flex; gap: 2px; align-items: flex-end;
height: 14px; margin-right: .5rem; flex-shrink: 0;
}
.apple-stripes div { width: 3px; border-radius: 2px; }
.as1 { height: 14px; background: var(--apple-g); }
.as2 { height: 11px; background: var(--apple-y); }
.as3 { height: 13px; background: var(--apple-o); }
.as4 { height: 10px; background: var(--apple-r); }
.as5 { height: 12px; background: var(--apple-p); }
.as6 { height: 9px; background: var(--apple-b); }
.mb-logo {
font-size: .80rem; font-weight: 800; color: var(--text);
padding: 0 .5rem; line-height: var(--menubar-h);
white-space: nowrap; border-radius: 4px;
}
.mb-logo:hover { background: rgba(0,0,0,.06); color: var(--text); }
.mb-item { position: relative; height: var(--menubar-h); display: flex; align-items: center; }
.mb-trigger {
display: flex; align-items: center;
height: var(--menubar-h); padding: 0 .55rem;
font-size: .74rem; font-weight: 500;
color: var(--text); cursor: default;
border-radius: 4px; white-space: nowrap;
}
.mb-item:hover .mb-trigger { background: var(--apple-b); color: #fff; }
.mb-dropdown {
display: none;
position: absolute; top: calc(100% + 1px); left: 0;
min-width: 220px;
background: rgba(245,244,240,.98);
backdrop-filter: blur(20px);
border: 1px solid var(--border);
border-radius: 6px;
box-shadow: 0 8px 30px rgba(0,0,0,.18);
padding: .3rem 0; z-index: 20001;
}
.mb-item:hover .mb-dropdown { display: block; }
.mb-dd-item {
display: flex; align-items: center; justify-content: space-between;
padding: .3rem 1rem; font-size: .78rem; color: var(--text);
gap: 1.5rem; white-space: nowrap;
}
.mb-dd-item:hover { background: var(--apple-b); color: #fff; border-radius: 4px; margin: 0 .3rem; padding: .3rem .7rem; }
.mb-dd-item.dim { color: var(--dim); pointer-events: none; }
.mb-dd-sep { height: 1px; background: var(--border2); margin: .3rem .5rem; }
.mb-dd-shortcut { font-family: var(--fm); font-size: .66rem; color: var(--dim); }
.mb-dd-item:hover .mb-dd-shortcut { color: rgba(255,255,255,.75); }
.mb-right { margin-left: auto; display: flex; align-items: center; gap: .5rem; }
.mb-dyslexic-btn {
display: flex; align-items: center; gap: .35rem;
background: none; border: none; cursor: pointer;
font-family: var(--fm); font-size: .66rem; color: var(--dim);
padding: 0 .4rem; height: var(--menubar-h); border-radius: 3px;
}
.mb-dyslexic-btn:hover { background: rgba(0,0,0,.07); color: var(--text); }
body.dyslexic .mb-dyslexic-btn { color: var(--apple-b); }
.mb-dy-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--border); flex-shrink: 0; }
body.dyslexic .mb-dy-dot { background: var(--apple-b); }
/* Hamburger + menu mobile */
.mb-hamburger {
display: none; flex-direction: column; justify-content: center; gap: 4px;
background: none; border: none; cursor: pointer;
padding: 0 .4rem; height: var(--menubar-h); border-radius: 3px;
}
.mb-hamburger span { display: block; width: 17px; height: 1.5px; background: var(--text); border-radius: 2px; transition: transform .2s, opacity .2s; }
.mb-hamburger.open span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
.mb-hamburger.open span:nth-child(2) { opacity: 0; }
.mb-hamburger.open span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }
.mb-mobile-menu {
display: none;
position: fixed; top: var(--menubar-h); left: 0; right: 0; bottom: 0;
background: rgba(245,244,240,.98);
z-index: 19999; overflow-y: auto;
padding: .5rem 0 2rem; border-top: 1px solid var(--border);
}
.mb-mobile-menu.open { display: block; }
.mb-mob-section { padding: .75rem 1rem .25rem; }
.mb-mob-label {
font-family: var(--fm); font-size: .62rem; font-weight: 700;
letter-spacing: .12em; text-transform: uppercase;
color: var(--dim); padding: 0 .25rem;
}
.mb-mob-item { display: block; padding: .65rem .5rem; font-size: .92rem; color: var(--text); border-radius: 8px; }
.mb-mob-item:hover { background: rgba(0,0,0,.05); color: var(--text); }
.mb-mob-sep { height: 1px; background: var(--border2); margin: .5rem 1rem; }
@media (max-width: 900px) {
.mb-item { display: none; }
.mb-hamburger { display: flex; }
}
/* ==========================================================
BUREAU + FENÊTRES
========================================================== */
.page-desktop {
padding: 2rem;
flex: 1;
background:
radial-gradient(ellipse 60% 40% at 90% 10%, rgba(224,58,62,.05) 0%, transparent 60%),
var(--bg);
}
.page-window {
background: #fff;
border: 1px solid var(--border2);
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0,0,0,.09), 0 2px 6px rgba(0,0,0,.05);
overflow: hidden;
max-width: 1060px;
margin: 0 auto 1.5rem;
}
.page-win-chrome {
background: linear-gradient(to bottom, #F8F7F4, #E8E6E0);
border-bottom: 1px solid var(--border2);
padding: .5rem .9rem;
display: flex; align-items: center; gap: .5rem;
user-select: none;
}
.traffic { display: flex; gap: 5px; }
.t-r, .t-y, .t-g { width: 12px; height: 12px; border-radius: 50%; }
.t-r { background: #FF5F57; border: 1px solid #E0443E; }
.t-y { background: #FEBC2E; border: 1px solid #D9A01C; }
.t-g { background: #28C840; border: 1px solid #1BAD2E; }
.page-win-title {
flex: 1; text-align: center;
font-family: var(--fm); font-size: .74rem; font-weight: 600; color: var(--dim);
}
.page-win-body { padding: 2rem 2.5rem; }
.page-statusbar {
background: var(--bg2); border-top: 1px solid var(--border2);
padding: .38rem 1rem;
font-family: var(--fm); font-size: .68rem; color: var(--dim);
display: flex; justify-content: space-between; gap: 1rem;
}
/* ── Titres et fil d'Ariane ── */
.page-breadcrumb {
font-size: var(--fs-xs); color: var(--dim);
margin-bottom: .75rem; display: flex; gap: .4rem; align-items: center; flex-wrap: wrap;
}
.page-breadcrumb a { color: var(--text2); }
.page-breadcrumb a:hover { color: var(--text); }
.page-h1 {
font-family: var(--fd); font-size: clamp(1.6rem, 3vw, 2.2rem);
font-weight: 900; letter-spacing: -.03em; line-height: 1.1;
color: var(--text); margin-bottom: .6rem;
}
.page-h1 em { color: var(--labo); font-style: normal; }
.page-lead { font-size: var(--fs-sm); color: var(--text2); line-height: 1.75; margin-bottom: 1.25rem; max-width: 560px; }
.section-sub { font-size: var(--fs-sm); color: var(--text2); line-height: 1.7; margin-bottom: 1.5rem; max-width: 620px; }
.back-link {
display: inline-flex; align-items: center; gap: .4rem;
font-family: var(--fm); font-size: var(--fs-xs);
color: var(--text2); background: var(--bg2);
border: 1px solid var(--border2); border-radius: 8px;
padding: .4rem .9rem; margin-bottom: 1.25rem; cursor: pointer;
}
.back-link:hover { background: var(--bg3); color: var(--text); }
.rainbow-line { display: flex; height: 3px; border-radius: 2px; overflow: hidden; margin-bottom: 1.75rem; }
.rainbow-line div { flex: 1; }
/* ── Hero ── */
.hero-layout { display: flex; gap: 3rem; align-items: center; }
.hero-text { flex: 1; min-width: 0; }
.hero-visual-side { flex: 0 0 160px; display: flex; flex-direction: column; align-items: center; gap: 1rem; }
.hero-big-icon {
width: 90px; height: 90px; border-radius: 22px;
display: flex; align-items: center; justify-content: center;
font-size: 2.8rem;
background: rgba(224,58,62,.09);
box-shadow: 0 4px 18px rgba(224,58,62,.12);
}
.hero-labo-badge {
font-family: var(--fm); font-size: .64rem; font-weight: 700;
letter-spacing: .15em; text-transform: uppercase;
color: var(--labo); padding: .2rem .65rem;
border: 1px solid rgba(224,58,62,.25); border-radius: 99px;
background: rgba(224,58,62,.06);
}
.lecon-meta { display: flex; gap: 1.25rem; flex-wrap: wrap; }
.lecon-meta-item { font-family: var(--fm); font-size: var(--fs-xs); color: var(--dim); display: flex; align-items: center; gap: .35rem; }
.lecon-meta-item strong { color: var(--c-entree); }
/* ==========================================================
IMAGES : repli si le fichier n'est pas encore en place
========================================================== */
.img-todo {
display: flex; flex-direction: column; align-items: center; justify-content: center;
gap: .4rem; min-height: 180px; padding: 1.5rem;
background: repeating-linear-gradient(45deg, var(--bg2), var(--bg2) 12px, var(--bg3) 12px, var(--bg3) 24px);
border: 2px dashed var(--border); border-radius: var(--radius);
font-family: var(--fm); font-size: var(--fs-xs); color: var(--text2); text-align: center;
}
.img-todo strong { color: var(--labo); font-size: var(--fs-sm); }
.img-todo span { color: var(--dim); }
figure.lecon-figure {
margin: 1.25rem auto; max-width: 720px;
border: 1px solid var(--border2); border-radius: var(--radius);
overflow: hidden; background: var(--bg2);
}
figure.lecon-figure img { width: 100%; height: auto; }
figure.lecon-figure figcaption {
font-family: var(--fm); font-size: var(--fs-xs); color: var(--dim);
padding: .5rem 1rem; text-align: center;
}
.figure-duo { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 700px) { .figure-duo { grid-template-columns: 1fr; } }
/* ==========================================================
IMAGE INTERACTIVE (hotspots)
========================================================== */
.periph-img-wrap {
position: relative; display: block;
max-width: 860px; margin: 0 auto;
border-radius: var(--radius); overflow: hidden;
box-shadow: 0 4px 24px rgba(0,0,0,.12);
border: 1px solid var(--border2);
background: var(--bg2);
}
.periph-img-wrap img { display: block; width: 100%; height: auto; }
.hs-dot {
position: absolute; transform: translate(-50%, -50%);
width: 32px; height: 32px; border-radius: 50%;
cursor: pointer; z-index: 10;
display: flex; align-items: center; justify-content: center;
transition: transform .2s ease;
border: 2px solid rgba(255,255,255,.6);
}
.hs-dot::before { content: ''; position: absolute; inset: 0; border-radius: 50%; animation: hs-pulse 2s ease-out infinite; }
.hs-dot.entree { background: rgba(0,157,220,.85); box-shadow: 0 0 0 3px rgba(0,157,220,.25); }
.hs-dot.entree::before { background: rgba(0,157,220,.4); }
.hs-dot.sortie { background: rgba(245,130,32,.85); box-shadow: 0 0 0 3px rgba(245,130,32,.25); }
.hs-dot.sortie::before { background: rgba(245,130,32,.4); }
.hs-dot.uc { background: rgba(150,61,151,.85); box-shadow: 0 0 0 3px rgba(150,61,151,.25); }
.hs-dot.uc::before { background: rgba(150,61,151,.4); }
.hs-dot:hover { transform: translate(-50%,-50%) scale(1.2); }
.hs-dot.active { transform: translate(-50%,-50%) scale(1.3); }
.hs-dot-icon { font-size: .8rem; position: relative; z-index: 1; }
@keyframes hs-pulse {
0% { transform: scale(1); opacity: .8; }
70% { transform: scale(2.2); opacity: 0; }
100% { transform: scale(2.2); opacity: 0; }
}
.hs-infobox {
max-width: 860px; margin: .5rem auto 0;
background: var(--bg2);
border: 1px solid var(--border2); border-top: 3px solid var(--c-entree);
border-radius: 0 0 var(--radius) var(--radius);
padding: 1rem 1.25rem; display: none;
}
.hs-infobox.visible { display: block; }
.hs-infobox.cat-sortie { border-top-color: var(--c-sortie); }
.hs-infobox.cat-uc { border-top-color: var(--c-uc); }
.hs-infobox-header { display: flex; align-items: center; gap: .6rem; margin-bottom: .4rem; }
.hs-infobox-emoji { font-size: 1.4rem; flex-shrink: 0; }
.hs-infobox-name { font-family: var(--fd); font-size: var(--fs-md); font-weight: 800; color: var(--text); flex: 1; }
.hs-infobox-badge {
font-family: var(--fm); font-size: .64rem;
padding: .15rem .5rem; border-radius: 3px;
text-transform: uppercase; letter-spacing: .08em; flex-shrink: 0;
}
.badge-entree { background: rgba(0,157,220,.1); color: var(--c-entree); border: 1px solid rgba(0,157,220,.25); }
.badge-sortie { background: rgba(245,130,32,.1); color: var(--c-sortie); border: 1px solid rgba(245,130,32,.25); }
.badge-uc { background: rgba(150,61,151,.1); color: var(--c-uc); border: 1px solid rgba(150,61,151,.25); }
.hs-infobox-close { background: none; border: none; color: var(--dim); font-size: 1.1rem; cursor: pointer; padding-left: .75rem; }
.hs-infobox-close:hover { color: var(--text); }
.hs-infobox-desc { font-size: var(--fs-sm); color: var(--text2); line-height: 1.65; margin-bottom: .35rem; }
.hs-infobox-detail { font-family: var(--fm); font-size: var(--fs-xs); color: var(--dim); font-style: italic; }
.hs-hint { text-align: center; font-family: var(--fm); font-size: var(--fs-xs); color: var(--dim); margin-top: .75rem; }
/* ==========================================================
CARTES CATÉGORIES
========================================================== */
.cat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1rem; }
.cat-card {
background: var(--bg); border: 1px solid var(--border2);
border-radius: 10px; padding: 1.25rem 1.4rem;
position: relative; overflow: hidden;
}
.cat-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; }
.cat-card.entree::before { background: var(--c-entree); }
.cat-card.sortie::before { background: var(--c-sortie); }
.cat-card.uc::before { background: var(--c-uc); }
.cat-card-header { display: flex; align-items: center; gap: .75rem; margin-bottom: .85rem; }
.cat-card-icon { font-size: 1.75rem; }
.cat-card-title { font-family: var(--fd); font-size: var(--fs-sm); font-weight: 800; color: var(--text); }
.cat-card-subtitle { font-family: var(--fm); font-size: var(--fs-xs); margin-top: .1rem; }
.cat-card.entree .cat-card-subtitle { color: var(--c-entree); }
.cat-card.sortie .cat-card-subtitle { color: var(--c-sortie); }
.cat-card.uc .cat-card-subtitle { color: var(--c-uc); }
.cat-card-def { font-size: var(--fs-sm); color: var(--text2); line-height: 1.65; margin-bottom: 1rem; }
.cat-item-list { list-style: none; display: flex; flex-direction: column; gap: .4rem; }
.cat-item { display: flex; align-items: flex-start; gap: .6rem; font-size: var(--fs-sm); color: var(--text2); }
.cat-item-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; margin-top: .45em; }
.cat-item-text { flex: 1; line-height: 1.55; }
.entree .cat-item-dot { background: var(--c-entree); }
.sortie .cat-item-dot { background: var(--c-sortie); }
.uc .cat-item-dot { background: var(--c-uc); }
.cat-item strong { color: var(--text); }
/* ==========================================================
GRILLE DE CARTES (hub vocabulaire / accueil)
========================================================== */
.notion-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 1rem; }
.notion-card {
background: var(--white); border: 1px solid var(--border2);
border-radius: var(--radius-lg); padding: 1.25rem;
cursor: pointer; text-align: left; width: 100%;
font-family: var(--ft); color: inherit;
box-shadow: var(--shadow-sm);
transition: var(--transition);
position: relative; overflow: hidden;
}
.notion-card::before {
content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
background: var(--card-color, var(--accent)); opacity: 0; transition: var(--transition);
}
.notion-card:hover { transform: translateY(-3px); border-color: var(--card-color, var(--accent)); box-shadow: var(--shadow); }
.notion-card:hover::before { opacity: 1; }
.notion-card-icon { font-size: 2rem; display: block; margin-bottom: .6rem; }
.notion-card-title { font-family: var(--fd); font-size: var(--fs-md); font-weight: 700; color: var(--text); margin-bottom: .25rem; }
.notion-card-desc { font-size: var(--fs-sm); color: var(--text2); line-height: 1.5; }
.notion-card-tag {
display: inline-block; margin-top: .7rem;
font-family: var(--fm); font-size: .62rem; letter-spacing: .1em; text-transform: uppercase;
color: var(--card-color, var(--accent));
border: 1px solid var(--card-color, var(--accent));
border-radius: 4px; padding: .1rem .45rem; opacity: .8;
}
/* ==========================================================
CONTENU D'UNE CARTE
========================================================== */
.carte-title {
font-family: var(--fd); font-size: var(--fs-2xl); font-weight: 900;
color: var(--text); letter-spacing: -.02em;
padding-left: .8rem; border-left: 4px solid var(--labo);
margin-bottom: 1.25rem; display: flex; align-items: center; gap: .5rem;
}
.carte-intro { font-size: var(--fs-md); color: var(--text2); line-height: 1.8; margin-bottom: 1.25rem; }
.carte-h3 {
font-family: var(--fd); font-size: var(--fs-lg); font-weight: 800;
color: var(--accent); margin: 1.75rem 0 .9rem;
}
.carte-list { list-style: none; display: flex; flex-direction: column; gap: .55rem; margin-bottom: 1rem; }
.carte-list li { display: flex; align-items: flex-start; gap: .65rem; font-size: var(--fs-md); color: var(--text2); line-height: 1.6; }
.carte-list li::before { content: '●'; color: var(--labo); font-size: .6rem; margin-top: .55em; flex-shrink: 0; }
.carte-list strong { color: var(--text); }
code, .kbd, .term {
font-family: var(--fm); font-size: .88em;
border-radius: 5px; padding: .12em .45em;
}
.term { background: rgba(245,130,32,.10); color: var(--apple-o); border: 1px solid rgba(245,130,32,.28); }
.kbd { background: var(--bg2); color: var(--text); border: 1px solid var(--border); box-shadow: 0 1px 0 var(--border); }
.callout {
display: flex; gap: .9rem; align-items: flex-start;
padding: 1rem 1.25rem; border-radius: var(--radius);
border-left: 4px solid; margin: 1.25rem 0;
font-size: var(--fs-md); color: var(--text2); line-height: 1.7;
}
.callout .callout-icon { font-size: 1.3rem; flex-shrink: 0; }
.callout.tip { background: rgba(97,187,70,.08); border-color: var(--apple-g); }
.callout.info { background: rgba(0,157,220,.07); border-color: var(--apple-b); }
.callout.warning { background: rgba(253,184,39,.10); border-color: var(--apple-y); }
.callout strong { color: var(--text); }
/* ==========================================================
EXERCICES — commun
========================================================== */
.exo-num {
font-family: var(--fm); font-size: .64rem; font-weight: 700;
letter-spacing: .15em; text-transform: uppercase;
color: var(--labo); margin-bottom: .3rem;
}
.exo-title { font-family: var(--fd); font-size: var(--fs-md); font-weight: 800; color: var(--text); margin-bottom: .3rem; }
.exo-desc { font-size: var(--fs-sm); color: var(--text2); line-height: 1.6; margin-bottom: 1.5rem; }
.exo-btn {
display: inline-flex; align-items: center; gap: .5rem;
font-family: var(--fm); font-size: var(--fs-sm);
padding: .55rem 1.2rem; border-radius: var(--radius);
border: none; cursor: pointer; transition: filter .15s;
}
.exo-btn-primary { background: var(--labo); color: #fff; font-weight: 600; }
.exo-btn-primary:hover { filter: brightness(1.1); }
.exo-btn-reset { background: var(--bg2); color: var(--text2); border: 1px solid var(--border2); }
.exo-btn-reset:hover { background: var(--bg3); color: var(--text); }
.exo-actions { display: flex; gap: .75rem; align-items: center; flex-wrap: wrap; margin-top: 1rem; }
.exo-feedback { margin-top: 1rem; padding: .85rem 1.1rem; border-radius: var(--radius); font-size: var(--fs-sm); line-height: 1.6; display: none; }
.exo-feedback.success { background: rgba(97,187,70,.08); border: 1px solid rgba(97,187,70,.3); color: #16a34a; display: block; }
.exo-feedback.error { background: rgba(224,58,62,.07); border: 1px solid rgba(224,58,62,.25); color: var(--c-err); display: block; }
.exo-feedback.partial { background: rgba(253,184,39,.08); border: 1px solid rgba(253,184,39,.3); color: #b45309; display: block; }
/* ── Glisser-déposer ── */
.dd-items-pool {
display: flex; flex-wrap: wrap; gap: .6rem;
padding: 1rem; background: var(--bg2);
border: 1px dashed var(--border); border-radius: var(--radius);
min-height: 64px; margin-bottom: 1.25rem;
}
.dd-item, .dd-item-placed {
display: flex; align-items: center; gap: .45rem;
font-family: var(--fm); font-size: var(--fs-sm); color: var(--text);
background: #fff; border: 1px solid var(--border2);
border-radius: 6px; padding: .35rem .75rem;
cursor: grab; user-select: none;
box-shadow: 0 1px 3px rgba(0,0,0,.07);
}
.dd-item:active, .dd-item-placed:active { cursor: grabbing; opacity: .6; }
.dd-item.dragging { opacity: .4; }
.dd-item.correct { border-color: rgba(97,187,70,.6); background: rgba(97,187,70,.08); }
.dd-item.incorrect { border-color: rgba(224,58,62,.5); background: rgba(224,58,62,.07); }
.dd-item.dd-selected, .dd-item-placed.dd-selected {
border-color: var(--c-entree); background: rgba(0,157,220,.10);
box-shadow: 0 0 0 2px rgba(0,157,220,.3);
}
.dd-zones { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 1.25rem; }
.dd-zone {
min-height: 120px; padding: .75rem; border-radius: var(--radius);
border: 2px dashed; display: flex; flex-direction: column; gap: .5rem;
transition: background .15s;
}
.dd-zone-label {
font-family: var(--fd); font-size: var(--fs-xs); font-weight: 700;
letter-spacing: .08em; text-transform: uppercase; text-align: center; margin-bottom: .2rem;
}
.dd-zone.entree { border-color: rgba(0,157,220,.35); }
.dd-zone.entree .dd-zone-label { color: var(--c-entree); }
.dd-zone.sortie { border-color: rgba(245,130,32,.35); }
.dd-zone.sortie .dd-zone-label { color: var(--c-sortie); }
.dd-zone.dragover { background: rgba(0,157,220,.05); border-color: rgba(0,157,220,.6); }
.dd-zone.sortie.dragover { background: rgba(245,130,32,.05); border-color: rgba(245,130,32,.6); }
.dd-zone-empty { font-family: var(--fm); font-size: var(--fs-xs); color: var(--dim); text-align: center; margin: auto; font-style: italic; }
.dd-zone.dd-zone-ready { border-style: solid; }
.dd-select-hint { font-family: var(--fm); font-size: var(--fs-xs); color: var(--c-entree); text-align: center; margin: .5rem 0 .75rem; }
/* ── Texte à trou ── */
.tt-pool {
display: flex; flex-wrap: wrap; gap: .6rem;
padding: 1.1rem; background: var(--bg2);
border: 1px solid var(--border2); border-radius: var(--radius);
min-height: 60px; margin-bottom: 1.25rem;
}
.tt-text {
background: var(--bg2); border: 1px solid var(--border2);
border-radius: var(--radius); padding: 1.5rem;
font-size: var(--fs-md); color: var(--text2); line-height: 3.2;
}
.tt-blank {
display: inline-flex; align-items: center; justify-content: center;
min-width: 150px; height: 2.2rem; padding: 0 .6rem;
background: #fff; border: 1px solid var(--border2);
border-bottom: 2px dashed var(--apple-o);
border-radius: 6px; vertical-align: middle;
font-family: var(--fm); font-size: var(--fs-sm); color: var(--text);
cursor: pointer;
}
.tt-blank.empty::after { content: '…'; color: var(--dim); }
.tt-blank.dragover { background: rgba(0,157,220,.07); border-color: var(--c-entree); }
.tt-blank.correct { border-color: var(--apple-g); background: rgba(97,187,70,.10); border-bottom-style: solid; }
.tt-blank.incorrect { border-color: var(--apple-r); background: rgba(224,58,62,.08); border-bottom-style: solid; }
.tt-blank.ready { border-color: var(--c-entree); }
/* ── QCM ── */
.qcm-list { display: flex; flex-direction: column; gap: 1.25rem; }
.qcm-q { background: var(--bg); border: 1px solid var(--border2); border-radius: 10px; padding: 1.1rem 1.25rem; }
.qcm-q-num {
font-family: var(--fm); font-size: .64rem; font-weight: 700;
letter-spacing: .12em; text-transform: uppercase; color: var(--labo); margin-bottom: .3rem;
}
.qcm-q-enonce { font-size: var(--fs-sm); color: var(--text); line-height: 1.6; margin-bottom: .85rem; font-weight: 600; }
.qcm-opts { display: flex; flex-direction: column; gap: .45rem; }
.qcm-opt {
display: flex; align-items: flex-start; gap: .7rem;
font-size: var(--fs-sm); color: var(--text2);
cursor: pointer; padding: .5rem .65rem;
border-radius: 8px; border: 1px solid var(--border2);
background: #fff; width: 100%;
transition: background .15s, border-color .15s;
}
.qcm-opt:hover { background: var(--bg2); border-color: var(--border); }
.qcm-opt-letter {
min-width: 22px; height: 22px; border-radius: 50%;
border: 1.5px solid var(--border);
display: flex; align-items: center; justify-content: center;
font-family: var(--fm); font-size: .64rem; color: var(--dim);
flex-shrink: 0; margin-top: .05rem;
}
.qcm-opt.selected { border-color: rgba(0,157,220,.35); color: var(--text); }
.qcm-opt.selected .qcm-opt-letter { border-color: var(--c-entree); background: rgba(0,157,220,.12); color: var(--c-entree); }
.qcm-opt.correct { border-color: rgba(97,187,70,.4); background: rgba(97,187,70,.05); color: var(--text); }
.qcm-opt.correct .qcm-opt-letter { border-color: var(--c-ok); background: rgba(97,187,70,.15); color: #16a34a; }
.qcm-opt.wrong { border-color: rgba(224,58,62,.35); }
.qcm-opt.wrong .qcm-opt-letter { border-color: var(--c-err); background: rgba(224,58,62,.12); color: var(--c-err); }
.qcm-expl { margin-top: .6rem; padding: .5rem .75rem; border-radius: 6px; font-size: var(--fs-xs); line-height: 1.55; display: none; }
.qcm-expl.show { display: block; }
.qcm-expl.ok { background: rgba(97,187,70,.08); color: #16a34a; border: 1px solid rgba(97,187,70,.25); }
.qcm-expl.ko { background: rgba(224,58,62,.06); color: var(--c-err); border: 1px solid rgba(224,58,62,.2); }
.qcm-submit-row { margin-top: 1.5rem; display: flex; gap: .75rem; align-items: center; flex-wrap: wrap; }
.qcm-score { font-family: var(--fd); font-size: var(--fs-md); font-weight: 800; color: var(--text); display: none; }
.score-col-good { color: #16a34a; }
.score-col-mid { color: var(--c-entree); }
.score-col-bad { color: var(--c-err); }
/* ==========================================================
FOOTER
========================================================== */
footer { background: var(--bg2); border-top: 1px solid var(--border2); padding: 1.1rem 2rem; margin-top: auto; }
.footer-inner { max-width: 1060px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.footer-logo { font-family: var(--fd); font-size: var(--fs-lg); font-weight: 800; letter-spacing: -.02em; line-height: 1; }
.footer-copy { font-size: var(--fs-xs); color: var(--dim); }
.footer-links { display: flex; gap: 1.5rem; list-style: none; flex-wrap: wrap; }
.footer-links a { font-size: var(--fs-xs); color: var(--dim); }
.footer-links a:hover { color: var(--text); }
/* ==========================================================
RESPONSIVE
========================================================== */
@media (max-width: 768px) {
.page-desktop { padding: 1rem; }
.page-win-body { padding: 1.25rem; }
.hero-layout { flex-direction: column; }
.hero-visual-side { display: none; }
.cat-grid, .dd-zones { grid-template-columns: 1fr; }
.notion-grid { grid-template-columns: 1fr 1fr; }
.hs-dot { width: 26px; height: 26px; }
.hs-dot-icon { font-size: .7rem; }
.tt-text { line-height: 2.8; }
.footer-inner { flex-direction: column; align-items: flex-start; }
}
@media (max-width: 480px) {
.notion-grid { grid-template-columns: 1fr; }
}
/* ==========================================================
TABLEAUX DE COURS
========================================================== */
.cours-table {
width: 100%; border-collapse: collapse;
font-size: var(--fs-sm); margin: 1rem 0 1.25rem;
border: 1px solid var(--border2); border-radius: var(--radius);
overflow: hidden;
}
.cours-table th {
background: var(--bg2); color: var(--text);
font-family: var(--fd); font-size: var(--fs-xs); font-weight: 800;
text-align: left; padding: .6rem .9rem;
border-bottom: 1px solid var(--border2);
}
.cours-table td {
padding: .55rem .9rem; color: var(--text2);
border-bottom: 1px solid var(--border2); line-height: 1.55;
}
.cours-table tr:last-child td { border-bottom: none; }
.cours-table tr:hover td { background: var(--bg); color: var(--text); }
.cours-table strong { color: var(--text); }
/* Schéma entrée → traitement → sortie */
.flux {
display: flex; align-items: stretch; gap: .75rem;
margin: 1.25rem 0; flex-wrap: wrap;
}
.flux-etape {
flex: 1; min-width: 150px;
border: 1px solid var(--border2); border-radius: 10px;
padding: 1rem; text-align: center; background: var(--bg);
position: relative;
}
.flux-etape::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; }
.flux-etape.e::before { background: var(--c-entree); }
.flux-etape.t::before { background: var(--c-uc); }
.flux-etape.s::before { background: var(--c-sortie); }
.flux-icone { font-size: 1.8rem; display: block; margin-bottom: .4rem; }
.flux-titre {
font-family: var(--fd); font-size: var(--fs-sm); font-weight: 800;
color: var(--text); margin-bottom: .25rem;
}
.flux-etape.e .flux-titre { color: var(--c-entree); }
.flux-etape.t .flux-titre { color: var(--c-uc); }
.flux-etape.s .flux-titre { color: var(--c-sortie); }
.flux-desc { font-size: var(--fs-xs); color: var(--text2); line-height: 1.5; }
.flux-fleche {
display: flex; align-items: center; color: var(--dim);
font-size: 1.3rem; flex: 0 0 auto;
}
@media (max-width: 700px) { .flux-fleche { display: none; } }