/* Feuille de style unique, écrite à la main. Style chaleureux et en relief, mode clair et mode sombre.
   Rien d'externe ni d'incorporé (CSP) : dégradés et ombres en CSS, texture et pictogrammes en
   fichiers locaux (/texture.png, le dossier /icones). Sections : 1 variables et polices, 2 base,
   3 typographie, 4 en-tête, 5 boutons, 6 bandeaux, 7 accueil et liste des outils, 8 page d'un outil,
   9 code en ligne, 10 mouvement et petits écrans. */

/* ===== 1. Variables et polices ===== */
/* Polices servies depuis /fonts/ (licence OFL, fichiers LICENSE à côté). Seul le sous-ensemble
   latin est déclaré, il couvre le français. font-display: swap affiche d'abord la pile système.
   Les graisses 400 et 700 suffisent : le gras du site est toujours 700. */
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/atkinson-hyperlegible-next/static/atkinson-hyperlegible-next-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/atkinson-hyperlegible-next/static/atkinson-hyperlegible-next-latin-700-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/atkinson-hyperlegible-next/static/atkinson-hyperlegible-next-latin-400-italic.woff2") format("woff2");
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/atkinson-hyperlegible-next/static/atkinson-hyperlegible-next-latin-700-italic.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/jetbrains-mono/static/jetbrains-mono-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/jetbrains-mono/static/jetbrains-mono-latin-700-normal.woff2") format("woff2");
}


/* Toutes les couleurs qui changent selon le thème passent par des variables. Le mode clair est défini
   ici. Le mode sombre, dessiné et non inversé, redéfinit les mêmes variables plus bas, deux fois
   (suivre le système tant qu'aucun choix n'est posé, puis choix explicite). Contrastes calculés dans
   le compte rendu de la refonte et dans CLAUDE.md. */
:root {
  --fond: #F5EEDD;          /* crème chaud, sous la texture */
  --panneau: #FFFBF2;
  --texte: #2D2822;         /* brun gris très foncé */
  --texte2: #5C5144;
  --bordure: #D5C6A3;
  --lien: #17586A;
  --focus: #17586A;
  --rouille: #A5470F;       /* orange en texte sur fond clair */
  --selection: #F3C79E;
  /* Bleu pétrole : navigation courante (identique dans les deux modes) et bandeaux. */
  --petrole-clair: #2A7586; --petrole: #1C5D6B; --petrole-fonce: #144854;
  --bandeau-haut: #2A7586; --bandeau-milieu: #1C5D6B; --bandeau-bas: #144854; --bandeau-bord: #0F3A44;
  /* Orange (identique dans les deux modes) : boutons et accents. */
  --orange-haut: #F0954F; --orange-bas: #D96F2B; --sur-orange: #2B1A0E;
  /* Cartes et panneaux. */
  --carte-haut: #FFFFFF; --carte-bas: #FBF3E2;
  --entete-haut: #FFFBF2; --entete-bas: #F0E6CE;
  --nav-survol-fond: rgba(255, 255, 255, .7); --nav-survol-texte: #1C5D6B;
  /* Relief : reflet clair d'un pixel en haut, ombres douces, effet gravé des titres. */
  --reflet: rgba(255, 255, 255, .8);
  --liseret: inset 0 1px 0 var(--reflet);
  --ombre: 0 1px 2px rgba(80, 55, 20, .14), 0 3px 8px rgba(80, 55, 20, .10);
  --ombre-haute: 0 2px 4px rgba(80, 55, 20, .16), 0 8px 18px rgba(80, 55, 20, .16);
  --ombre-fine: 0 1px 2px rgba(80, 55, 20, .12);
  --gravure: 0 1px 0 rgba(255, 255, 255, .8);
  /* Code en ligne, lignes de séparation, champs de saisie (bordure à 3 de contraste ou plus), messages. */
  --ligne-alt: #F8F0DE; --ligne-bord: #E5D9BC;
  --champ-bord: #7A6C5A; --erreur: #A12A1C; --succes: #2E6B1F;
  --fond-code: #EDE3CB; --code-ligne-bord: #D5C6A3; --code-ligne-txt: #3A2F20;
  /* Logo de l'en-tête : version foncée en clair, version claire en sombre, choisie par CSS. */
  --logo-clair-affiche: block; --logo-sombre-affiche: none;
  /* Bouton de thème : l'icône montre le mode vers lequel on bascule. */
  --icone-bascule: url("/icones/lune.svg");
  /* Terminal décoratif de l'accueil, panneau sombre #1A2438 identique dans les deux modes. Contrastes sur ce fond :
     commande 6,79 · chaîne 6,81 · nombre 7,94 · texte 12,63. */
  --bloc-fond: #1A2438;
  --code-texte: #E4E8EF;
  --code-commande: #7DB2D4;
  --code-chaine: #8BB875;
  --code-nombre: #DDB45A;
  /* Échelle d'espacement fixe : 4, 8, 12, 16, 24, 32, 48 px. */
  --esp-4: .25rem; --esp-8: .5rem; --esp-12: .75rem; --esp-16: 1rem;
  --esp-24: 1.5rem; --esp-32: 2rem; --esp-48: 3rem;
  --rayon: 10px;
  --police-texte: "Atkinson Hyperlegible Next", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --police-code: "JetBrains Mono", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  color-scheme: light;
}

/* Mode sombre. Sans choix posé par theme.js, il suit prefers-color-scheme (aussi sans JavaScript).
   Avec un choix, l'attribut data-theme de la balise html décide. Les deux blocs sont identiques. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --fond: #1B1612;          /* brun chaud très foncé */
    --panneau: #2A231D;
    --texte: #EFE6D6;         /* crème */
    --texte2: #BCAF9C;
    --bordure: #4A3E33;
    --lien: #7CC3D3;
    --focus: #7CC3D3;
    --rouille: #F0A56B;
    --selection: #6B4A2B;
    --bandeau-haut: #1E5361; --bandeau-milieu: #16444F; --bandeau-bas: #0D2F38; --bandeau-bord: #0A242B;
    --carte-haut: #30281F; --carte-bas: #2A231D;
    --entete-haut: #2D251E; --entete-bas: #231C16;
    --nav-survol-fond: rgba(255, 255, 255, .08); --nav-survol-texte: #F3E9D8;
    --reflet: rgba(255, 255, 255, .07);
    --ombre: 0 1px 2px rgba(0, 0, 0, .5), 0 3px 8px rgba(0, 0, 0, .35);
    --ombre-haute: 0 2px 4px rgba(0, 0, 0, .55), 0 8px 18px rgba(0, 0, 0, .45);
    --ombre-fine: 0 1px 2px rgba(0, 0, 0, .45);
    --gravure: 0 1px 0 rgba(0, 0, 0, .6);
    --ligne-alt: #2F2720; --ligne-bord: #43382E;
    --champ-bord: #8F8068; --erreur: #F2A59B; --succes: #A9D18E;
    --fond-code: #3A2F25; --code-ligne-bord: #5A4A3B; --code-ligne-txt: #EBDDC6;
    --logo-clair-affiche: none; --logo-sombre-affiche: block;
    --icone-bascule: url("/icones/soleil.svg");
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --fond: #1B1612;          /* brun chaud très foncé */
  --panneau: #2A231D;
  --texte: #EFE6D6;         /* crème */
  --texte2: #BCAF9C;
  --bordure: #4A3E33;
  --lien: #7CC3D3;
  --focus: #7CC3D3;
  --rouille: #F0A56B;
  --selection: #6B4A2B;
  --bandeau-haut: #1E5361; --bandeau-milieu: #16444F; --bandeau-bas: #0D2F38; --bandeau-bord: #0A242B;
  --carte-haut: #30281F; --carte-bas: #2A231D;
  --entete-haut: #2D251E; --entete-bas: #231C16;
  --nav-survol-fond: rgba(255, 255, 255, .08); --nav-survol-texte: #F3E9D8;
  --reflet: rgba(255, 255, 255, .07);
  --ombre: 0 1px 2px rgba(0, 0, 0, .5), 0 3px 8px rgba(0, 0, 0, .35);
  --ombre-haute: 0 2px 4px rgba(0, 0, 0, .55), 0 8px 18px rgba(0, 0, 0, .45);
  --ombre-fine: 0 1px 2px rgba(0, 0, 0, .45);
  --gravure: 0 1px 0 rgba(0, 0, 0, .6);
  --ligne-alt: #2F2720; --ligne-bord: #43382E;
  --champ-bord: #8F8068; --erreur: #F2A59B; --succes: #A9D18E;
  --fond-code: #3A2F25; --code-ligne-bord: #5A4A3B; --code-ligne-txt: #EBDDC6;
  --logo-clair-affiche: none; --logo-sombre-affiche: block;
  --icone-bascule: url("/icones/soleil.svg");
}

/* ===== 2. Base ===== */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  display: flex; flex-direction: column; min-height: 100vh; margin: 0;
  background: var(--fond) url("/texture.png");
  color: var(--texte);
  font: 1rem/1.6 var(--police-texte);
}
main { flex: 1; }
/* Contenu centré, 1100 px au plus, marge de 16 px sur téléphone. */
.cadre { max-width: 1100px; margin: 0 auto; padding: 0 var(--esp-16); }
/* Pas de pied de page : les 48 px sous le contenu laissent l'air en bas de page. */
main.cadre { width: 100%; padding-top: var(--esp-32); padding-bottom: var(--esp-48); }
::selection { background: var(--selection); color: var(--texte); }
a { color: var(--lien); text-decoration-thickness: 1px; text-underline-offset: .22em; }
a:hover { color: var(--rouille); text-decoration-thickness: 2px; }
a:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: 3px; }
img { max-width: 100%; }
.vide { color: var(--texte2); }
/* L'attribut hidden doit toujours l'emporter sur un display posé par une classe (grille de .outil, par exemple). */
[hidden] { display: none !important; }

/* ===== 3. Typographie ===== */
/* Texte jamais tassé. Sur fond clair, titres avec un léger effet gravé (ombre claire en dessous). */
h1, h2, h3 { font-weight: 700; text-shadow: var(--gravure); }
h1 { margin: 0 0 var(--esp-16); font-size: 2rem; line-height: 1.2; letter-spacing: -.02em; overflow-wrap: anywhere; }
h2 { margin: var(--esp-32) 0 var(--esp-12); font-size: 1.5rem; line-height: 1.3; letter-spacing: -.01em; }
h3 { margin: var(--esp-24) 0 var(--esp-8); font-size: 1.125rem; line-height: 1.4; }
p, ul, ol { margin: 0 0 var(--esp-16); }

/* ===== 4. En-tête et navigation ===== */
/* En-tête clair, liseré blanc en haut, ombre douce en bas. Navigation en pastilles. */
.entete {
  background: linear-gradient(var(--entete-haut), var(--entete-bas));
  border-bottom: 1px solid var(--bordure);
  box-shadow: var(--liseret), var(--ombre-fine);
  position: relative;
  z-index: 2;
}
.entete .cadre { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--esp-8) var(--esp-24); padding-top: var(--esp-8); padding-bottom: var(--esp-8); }
.nom { display: block; border-radius: 6px; }
.nom img { height: 36px; width: auto; }
/* Deux versions du logo, une seule affichée selon le thème (variables, donc le bouton est suivi). */
.logo-mode-clair { display: var(--logo-clair-affiche); }
.logo-mode-sombre { display: var(--logo-sombre-affiche); }
.entete-droite { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: var(--esp-8) var(--esp-12); }
/* Bouton de thème : masqué tant que theme.js n'a pas posé data-js sur html (sans JavaScript, le mode
   automatique s'applique). Le pictogramme est un masque SVG local coloré par currentColor. */
.bascule {
  display: none;
  align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0;
  background: linear-gradient(var(--carte-haut), var(--carte-bas));
  border: 1px solid var(--bordure);
  border-radius: 50%;
  box-shadow: var(--liseret), var(--ombre-fine);
  color: var(--texte);
  cursor: pointer;
}
html[data-js] .bascule { display: inline-flex; }
.bascule::before {
  content: ""; width: 22px; height: 22px; background: currentColor;
  -webkit-mask: var(--icone-bascule) center / 22px 22px no-repeat;
  mask: var(--icone-bascule) center / 22px 22px no-repeat;
}
.bascule:hover { color: var(--rouille); border-color: var(--rouille); }
.bascule:active { transform: translateY(1px); box-shadow: inset 0 2px 4px rgba(0, 0, 0, .25); }
.bascule:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.entete nav { display: flex; flex-wrap: wrap; gap: var(--esp-8); }
.entete nav a {
  padding: var(--esp-8) var(--esp-16);
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--texte);
  font-size: .9375rem;
  font-weight: 700;
  text-decoration: none;
}
.entete nav a:hover { background: var(--nav-survol-fond); border-color: var(--bordure); color: var(--nav-survol-texte); }
/* Page courante : pastille pleine bleue, légèrement bombée. */
.entete nav a[aria-current="page"] {
  background: linear-gradient(var(--petrole-clair), var(--petrole));
  border-color: var(--petrole-fonce);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3), 0 1px 2px rgba(20, 72, 84, .35);
  color: #FFFFFF;
  text-shadow: 0 1px 0 rgba(0, 0, 0, .25);
}

/* ===== 5. Boutons ===== */
/* Bouton orange bombé : dégradé vertical, liseré clair, ombre pleine dessous. Texte foncé (4,98 minimum).
   Au clic, il s'enfonce. */
.bouton {
  display: inline-block;
  padding: var(--esp-12) var(--esp-24);
  background: linear-gradient(var(--orange-haut), var(--orange-bas));
  border: 1px solid #B85A1C;
  border-radius: var(--rayon);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), 0 2px 0 #A44E16, 0 4px 8px rgba(80, 55, 20, .25);
  color: var(--sur-orange);
  font-weight: 700;
  text-decoration: none;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .3);
}
.bouton:hover { color: var(--sur-orange); filter: brightness(1.06); }
.bouton:active { transform: translateY(2px); box-shadow: inset 0 2px 4px rgba(80, 40, 10, .35), 0 0 0 #A44E16; }
.bouton:focus-visible { outline-color: var(--focus); }

/* ===== 6. Bandeaux ===== */
/* Grand bandeau bleu pétrole : dégradé vertical, fines rayures diagonales, liseré clair en haut, ombre dessous. */
.bandeau {
  background:
    repeating-linear-gradient(135deg, rgba(255, 255, 255, .035) 0 2px, transparent 2px 9px),
    linear-gradient(var(--bandeau-haut), var(--bandeau-milieu) 60%, var(--bandeau-bas));
  border-bottom: 1px solid var(--bandeau-bord);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 4px 10px rgba(40, 30, 10, .28);
  color: #FFFFFF;
}
.bandeau h1, .bandeau h2 { color: #FFFFFF; text-shadow: 0 1px 2px rgba(0, 0, 0, .35); }
.bandeau h1 code { background: rgba(255, 255, 255, .16); border-color: rgba(255, 255, 255, .35); color: #FFFFFF; }
.bandeau a { color: #FFFFFF; }
.bandeau a:focus-visible { outline-color: #FFFFFF; }
.bandeau-petit { padding: var(--esp-32) 0 var(--esp-24); }
.bandeau-petit h1 { margin: 0; }
.bandeau-grand { padding: var(--esp-48) 0; }
.bandeau-grille { display: grid; gap: var(--esp-32); align-items: center; }
/* Sans phrase de présentation, l'illustration (terminal ou image) occupe seule le bandeau et se centre.
   En flex pour que le centrage ne dépende pas de la largeur des pistes de la grille. */
.bandeau-seul { display: flex; justify-content: center; }
.bandeau-seul .bandeau-visuel { width: 100%; max-width: 28rem; }
.bandeau-seul .terminal, .bandeau-seul .illustration { margin: 0 auto; }
/* Masqué à l'écran, lu par les lecteurs d'écran (h1 de l'accueil). */
.sr-seul { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* Colonne gauche du bandeau d'accueil : logo en grand, phrase d'accroche, bouton. Centrée sous 1000 px. */
.bandeau-texte { display: flex; flex-direction: column; align-items: center; gap: var(--esp-24); text-align: center; }
.bandeau h1.bandeau-marque { margin: 0; line-height: 0; text-shadow: none; }
.bandeau-marque img { display: block; height: 80px; width: auto; }
/* Accroche : 26 px, graisse moyenne (500, rendue en 400 tant que la police 500 n'est pas fournie), crème, ombre
   gravée légère des titres du bandeau. Texte « grand » : 3 de contraste suffiraient, on en a plus de 4,5. */
.presentation { max-width: 24em; color: #FFF8EA; font-size: 1.625rem; font-weight: 500; line-height: 1.3; text-shadow: 0 1px 2px rgba(0, 0, 0, .35); }
.presentation p { margin: 0 0 var(--esp-12); }
.presentation > :last-child { margin-bottom: 0; }
.illustration { display: block; margin: 0 auto; height: auto; border-radius: var(--rayon); box-shadow: var(--ombre-haute); }
/* Fenêtre de terminal décorative de l'accueil, faite en HTML et CSS. */
.terminal {
  max-width: 28rem;
  margin: 0 auto;
  background: var(--bloc-fond);
  border: 1px solid #0E1522;
  border-radius: var(--rayon);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), 0 14px 28px rgba(0, 0, 0, .38);
  overflow: hidden;
  transform: rotate(-1.2deg);
}
.terminal-barre { display: flex; gap: var(--esp-8); padding: var(--esp-12) var(--esp-16); background: linear-gradient(#37456A, #28334F); border-bottom: 1px solid #0E1522; }
.terminal-barre span { width: 12px; height: 12px; border-radius: 50%; background: #E0624F; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35); }
.terminal-barre span:nth-child(2) { background: #E5B341; }
.terminal-barre span:nth-child(3) { background: #5BB85D; }
.terminal-corps { padding: var(--esp-16) var(--esp-24); color: var(--code-texte); font: .875rem/1.7 var(--police-code); }
.terminal-corps p { margin: 0; overflow-wrap: anywhere; }
.t-invite { color: var(--code-nombre); }
.t-cmd { color: var(--code-commande); }
.t-ok { color: var(--code-chaine); }
.curseur { display: inline-block; width: .6em; height: 1.1em; vertical-align: text-bottom; background: #D9814F; }

/* ===== 7. Accueil et liste des outils ===== */
.rubrique-titre { margin: 0 0 var(--esp-16); font-size: 1.25rem; }
/* Cartes d'outils : une colonne sur téléphone, autant de colonnes de 18 rem au moins que la largeur le permet. Le lien
   du titre est étiré sur toute la carte (::after), donc toute la carte est cliquable. */
.cartes { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr)); gap: var(--esp-16); margin: 0; padding: 0; list-style: none; }
.carte {
  position: relative; display: flex; align-items: flex-start; gap: var(--esp-16);
  padding: var(--esp-16) var(--esp-24);
  background: linear-gradient(var(--carte-haut), var(--carte-bas));
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  box-shadow: var(--liseret), var(--ombre);
}
.carte:hover { border-color: var(--orange-bas); box-shadow: var(--liseret), var(--ombre-haute); }
.carte-corps { min-width: 0; }
/* Pictogramme : petite tuile orange bombée (même orange dans les deux modes), trait brun foncé du texte sur l'orange. */
.carte-icone {
  flex: none; display: flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  background: linear-gradient(var(--orange-haut), var(--orange-bas)); border: 1px solid #B85A1C; border-radius: var(--rayon);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
}
.carte-icone img { display: block; width: 26px; height: 26px; }
.carte-titre { margin: 0 0 var(--esp-8); font-size: 1.125rem; line-height: 1.35; letter-spacing: 0; }
.carte-titre a { color: var(--texte); text-decoration: none; overflow-wrap: anywhere; }
.carte-titre a::after { content: ""; position: absolute; inset: 0; border-radius: var(--rayon); }
.carte-titre a:focus-visible { outline: none; }
.carte-titre a:focus-visible::after { outline: 3px solid var(--focus); outline-offset: 2px; }
.carte:hover .carte-titre a { color: var(--rouille); }
.carte-desc { margin: 0; color: var(--texte2); font-size: .9375rem; }

/* ===== 8. Page d'un outil ===== */
/* Message affiché seulement sans JavaScript (<noscript>). */
.avis-js { margin: 0; padding: var(--esp-12) var(--esp-16); background: linear-gradient(var(--carte-haut), var(--carte-bas)); border: 1px solid var(--bordure); border-left: 4px solid var(--orange-bas); border-radius: var(--rayon); }
.outil { display: grid; gap: var(--esp-24); }
/* Panneau : même relief que les cartes. */
.panneau { padding: var(--esp-24); background: linear-gradient(var(--carte-haut), var(--carte-bas)); border: 1px solid var(--bordure); border-radius: var(--rayon); box-shadow: var(--liseret), var(--ombre); }
.panneau h2 { margin: 0 0 var(--esp-8); font-size: 1.25rem; }
/* Champs : empilés sur téléphone, côte à côte dès 40 rem. Texte de saisie en 16 px (pas de zoom automatique sur iOS). */
.champs { display: grid; gap: var(--esp-16); }
.champ { min-width: 0; }
.champ label { display: block; margin-bottom: var(--esp-4); font-weight: 700; }
.champ input {
  width: 100%; padding: var(--esp-8) var(--esp-12);
  background: var(--panneau); border: 1px solid var(--champ-bord); border-radius: 6px;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .12);
  color: var(--texte); font: 1rem/1.4 var(--police-code);
}
.champ input:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
/* Champ en erreur : bordure rouge plus épaisse (le texte du message dit aussi l'erreur, la couleur seule ne la porte pas). */
.champ input[aria-invalid="true"] { padding: calc(var(--esp-8) - 1px) calc(var(--esp-12) - 1px); border: 2px solid var(--erreur); }
.aide { margin: var(--esp-4) 0 0; color: var(--texte2); font-size: .875rem; }
.erreur { margin: var(--esp-4) 0 0; color: var(--erreur); font-size: .9375rem; font-weight: 700; }
.erreur:empty { margin: 0; }
@media (min-width: 40rem) { .champs { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; } }
/* Résultats : une ligne par valeur, libellé au-dessus sur téléphone, en colonne dès 40 rem. */
.resultats { margin: 0; }
.resultat { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--esp-4) var(--esp-12); padding: var(--esp-12) 0; border-top: 1px solid var(--ligne-bord); }
.resultat:first-child { border-top: 0; padding-top: 0; }
.resultat:last-child { padding-bottom: 0; }
.resultat dt { grid-column: 1 / -1; color: var(--texte2); font-size: .875rem; font-weight: 700; }
.resultat dd { margin: 0; min-width: 0; }
.resultat .valeur { display: block; width: fit-content; max-width: 100%; padding: 0; background: none; border: 0; color: var(--texte); font-size: 1rem; overflow-wrap: anywhere; }
@media (min-width: 40rem) {
  .resultat { grid-template-columns: 14rem minmax(0, 1fr) auto; }
  .resultat dt { grid-column: auto; }
}
/* Bouton « Copier » de chaque résultat, même discrétion que celui des blocs de code : contour fin, texte du site.
   Zone cliquable un peu plus grande que le dessin (::after). */
.copier {
  position: relative; min-width: 4.5rem; height: 32px; padding: 0 var(--esp-12);
  background: transparent; border: 1px solid var(--champ-bord); border-radius: 6px;
  color: var(--texte); font: 400 .875rem/1 var(--police-texte); letter-spacing: .02em; text-align: center; cursor: pointer;
}
.copier::after { content: ""; position: absolute; inset: -6px; }
.copier:hover, .copier:focus-visible { border-color: var(--rouille); color: var(--rouille); }
.copier:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.copier.copie, .copier.copie:hover { border-color: var(--succes); color: var(--succes); }
.copier.echec, .copier.echec:hover { border-color: var(--erreur); color: var(--erreur); }
/* Convertisseur de permissions : le formulaire empile ses panneaux, la grille de cases est un vrai tableau (en-têtes
   de colonnes et de lignes, lisible par un lecteur d'écran), chaque case est entourée d'une zone cliquable de 44 px. */
.formulaire { display: grid; gap: var(--esp-24); }
.jeu { min-width: 0; margin: 0; padding: 0; border: 0; }
.jeu legend { padding: 0; margin: 0 0 var(--esp-8); font-size: 1.25rem; font-weight: 700; }
.grille { width: 100%; border-collapse: collapse; }
.grille th, .grille td { padding: var(--esp-4); text-align: center; }
.grille thead th { color: var(--texte2); font-size: .8125rem; font-weight: 700; }
.grille tbody th { color: var(--texte); font-size: .9375rem; text-align: left; }
.grille tbody tr + tr > * { border-top: 1px solid var(--ligne-bord); }
.case { display: flex; align-items: center; justify-content: center; min-height: 44px; cursor: pointer; }
.case input, .option input { width: 1.375rem; height: 1.375rem; margin: 0; accent-color: var(--focus); cursor: pointer; }
.case input:focus-visible, .option input:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.separe { margin-top: var(--esp-16); padding-top: var(--esp-16); border-top: 1px solid var(--ligne-bord); }
.separe legend { font-size: 1rem; }
.options { display: flex; flex-wrap: wrap; gap: var(--esp-8) var(--esp-24); }
.option { display: inline-flex; align-items: center; gap: var(--esp-8); min-height: 44px; cursor: pointer; font-family: var(--police-code); }
/* Assistant cron : préréglages en boutons, phrase en clair en évidence, tableau de détail dans un cadre qui défile
   si besoin (sans jamais élargir la page), prochaines exécutions en liste numérotée, notes en liste dans un seul cadre. */
.sous-titre { margin: var(--esp-16) 0 var(--esp-8); font-size: .875rem; font-weight: 700; color: var(--texte2); }
.prereglages { display: flex; flex-wrap: wrap; gap: var(--esp-8); }
.prereglage {
  min-height: 36px; padding: 0 var(--esp-12);
  background: transparent; border: 1px solid var(--champ-bord); border-radius: 6px;
  color: var(--texte); font: 400 .9375rem/1 var(--police-texte); cursor: pointer;
}
.prereglage:hover { border-color: var(--rouille); color: var(--rouille); }
.prereglage:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.prereglage:active { transform: translateY(1px); }
.phrase { margin: 0 0 var(--esp-16); font-size: 1.25rem; font-weight: 700; line-height: 1.35; overflow-wrap: anywhere; }
.panneau h3 { margin: var(--esp-24) 0 var(--esp-8); font-size: 1rem; }
.defile { max-width: 100%; overflow-x: auto; }
.detail { width: 100%; border-collapse: collapse; }
.detail th, .detail td { padding: var(--esp-8) var(--esp-12) var(--esp-8) 0; border-top: 1px solid var(--ligne-bord); text-align: left; vertical-align: top; }
.detail thead th { border-top: 0; color: var(--texte2); font-size: .8125rem; }
.detail tbody th { font-size: .9375rem; }
.detail td:last-child { overflow-wrap: anywhere; }
.executions { margin: 0 0 var(--esp-8); padding-left: var(--esp-32); }
.executions li + li { margin-top: var(--esp-4); }
.executions li::marker { color: var(--rouille); font-weight: 700; }
/* .note.notes : la règle .note, plus bas, poserait sinon son propre retrait. */
.note.notes { margin: var(--esp-24) 0 0; padding: var(--esp-8) var(--esp-12) var(--esp-8) var(--esp-32); }
.notes li + li { margin-top: var(--esp-4); }
/* Explication des préfixes /31 et /32, et phrase en clair du convertisseur de permissions. */
.note { margin: var(--esp-16) 0 0; padding: var(--esp-8) var(--esp-12); background: var(--ligne-alt); border-left: 4px solid var(--orange-bas); border-radius: 0 6px 6px 0; }
@media print { .copier { display: none; } }

/* ===== 9. Code en ligne ===== */
/* Valeurs des résultats : chasse fixe, pas de ligatures (un point ou un tiret doit rester le caractère tapé). */
code {
  display: inline-block; max-width: 100%;
  padding: .05em .4em;
  background: var(--fond-code);
  border: 1px solid var(--code-ligne-bord);
  border-radius: 5px;
  color: var(--code-ligne-txt);
  font-family: var(--police-code); font-variant-ligatures: none;
  font-size: .875em; line-height: 1.45;
  overflow-wrap: anywhere;
}

/* ===== 10. Mouvement et petits écrans ===== */
/* Transitions très courtes, sur la couleur et l'ombre seulement, coupées si l'utilisateur le demande. */
@media (prefers-reduced-motion: no-preference) {
  a, .carte, .bouton, .bascule, .copier {
    transition: color .12s, background-color .12s, border-color .12s, box-shadow .12s, opacity .12s;
  }
}
/* Bandeau d'accueil en deux colonnes : à partir de 1000 px. */
@media (min-width: 62.5rem) {
  .bandeau-grille:not(.bandeau-seul) { grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); }
  /* À partir de 1000 px : texte à gauche, aligné à gauche et centré en hauteur face au terminal, à droite. */
  .bandeau-texte { align-items: flex-start; text-align: left; }
  .bandeau-grille:not(.bandeau-seul) .terminal, .bandeau-grille:not(.bandeau-seul) .illustration { margin: 0 0 0 auto; }
}
@media (max-width: 40rem) {
  h1 { font-size: 1.6rem; }
  .bandeau-grand { padding: var(--esp-32) 0; }
  .terminal { transform: none; }
  /* En-tête sur téléphone : le logo (86 px de large) et la navigation tiennent sur une seule ligne. */
  .entete .cadre { column-gap: var(--esp-12); }
  .entete nav a { padding: var(--esp-8) var(--esp-12); }
  .entete-droite { gap: var(--esp-8); }
  .carte { padding: var(--esp-16); }
  .panneau { padding: var(--esp-16); }
}