/* ============================================================
   jjoly.eu — thème dark cyber/terminal
   Zéro dépendance externe : system fonts, pas de tracker.
   ============================================================ */
:root {
  --bg: #0a0e14;
  --bg-alt: #0f141d;
  --panel: #121926;
  --border: #1e2836;
  --text: #c9d4e3;
  --heading: #eef3fa;
  --nav-bg: rgba(10, 14, 20, 0.85);
  --on-accent: #05130c;
  --shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
  --text-dim: #7d8ba1;
  --accent: #00e68a;
  --accent-dim: rgba(0, 230, 138, 0.12);
  --amber: #ffb454;
  --red: #f07178;
  --mono: "SF Mono", SFMono-Regular, ui-monospace, "JetBrains Mono", Menlo, Consolas, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
}

/* Thème clair pour qui a réglé son système ainsi. Le dark cyber reste l'identité
   du site ; cette variante ne fait que redéfinir les variables, aucune règle n'est
   dupliquée. Contrastes vérifiés WCAG AA (5,3:1 à 15,6:1). */
@media (prefers-color-scheme: light) {
  :root {
    --bg: #f7f9fc;
    --bg-alt: #eef2f8;
    --panel: #ffffff;
    --border: #d5dde8;
    --text: #1c2430;
    --heading: #0f1620;
    --nav-bg: rgba(247, 249, 252, 0.88);
    --on-accent: #ffffff;
    --shadow: 0 12px 32px rgba(15, 22, 32, 0.10);
    --text-dim: #586475;
    --accent: #00784a;
    --accent-dim: rgba(0, 120, 74, 0.10);
    --amber: #8a5a00;
    --red: #b3252c;
  }
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--accent); color: var(--bg); }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---------- Nav ---------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.9rem clamp(1rem, 5vw, 3rem);
  background: var(--nav-bg);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.nav-logo {
  font-family: var(--mono);
  font-size: 0.95rem;
  color: var(--text);
}
.nav-logo .prompt { color: var(--accent); }
.nav-links { display: flex; gap: 1.4rem; list-style: none; }
.nav-links a {
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--text-dim);
}
.nav-links a:hover { color: var(--accent); text-decoration: none; }

/* Sélecteur de langue : volontairement discret et jamais masqué sur mobile —
   c'est le seul lien qui ne mène nulle part ailleurs sur le site. */
.lang-switch {
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.1rem 0.45rem;
  letter-spacing: 0.05em;
}
.lang-switch:hover { border-color: var(--accent); color: var(--accent); }

/* ---------- Layout ---------- */
.section {
  max-width: 1060px;
  margin: 0 auto;
  padding: clamp(3.5rem, 8vw, 6rem) clamp(1rem, 5vw, 2rem);
}
.section-title {
  font-family: var(--mono);
  font-size: 1.15rem;
  color: var(--accent);
  margin-bottom: 2.2rem;
}
.section-title::before { content: "## "; color: var(--text-dim); }

/* ---------- Hero ---------- */
.hero {
  min-height: calc(92vh - 60px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: 1060px;
  margin: 0 auto;
  padding: 2rem clamp(1rem, 5vw, 2rem);
}
.hero-kicker {
  font-family: var(--mono);
  color: var(--accent);
  font-size: 0.9rem;
  margin-bottom: 1rem;
}
.hero h1 {
  font-size: clamp(2.1rem, 6vw, 3.6rem);
  line-height: 1.1;
  color: var(--heading);
  letter-spacing: -0.02em;
}
.hero h2 {
  font-size: clamp(1.2rem, 3.5vw, 1.9rem);
  color: var(--text-dim);
  font-weight: 500;
  margin-top: 0.5rem;
}
.hero p.lead {
  max-width: 640px;
  margin-top: 1.4rem;
  color: var(--text-dim);
  font-size: 1.05rem;
}
.hero-actions { margin-top: 2.2rem; display: flex; gap: 1rem; flex-wrap: wrap; }

.btn {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.88rem;
  padding: 0.7rem 1.3rem;
  border: 1px solid var(--accent);
  border-radius: 6px;
  color: var(--accent);
  transition: background 0.2s, transform 0.15s;
}
.btn:hover { background: var(--accent-dim); text-decoration: none; transform: translateY(-2px); }
.btn.ghost { border-color: var(--border); color: var(--text-dim); }
.btn.ghost:hover { border-color: var(--text-dim); background: transparent; }

/* ---------- Terminal ---------- */
.terminal {
  margin-top: 3rem;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  max-width: 640px;
  box-shadow: var(--shadow);
}
.terminal-bar {
  display: flex;
  gap: 7px;
  padding: 0.65rem 0.9rem;
  background: var(--bg-alt);
  border-bottom: 1px solid var(--border);
}
.terminal-bar span { width: 11px; height: 11px; border-radius: 50%; }
.terminal-bar .r { background: var(--red); }
.terminal-bar .y { background: var(--amber); }
.terminal-bar .g { background: var(--accent); }
.terminal-body {
  padding: 1.1rem 1.2rem;
  font-family: var(--mono);
  font-size: 0.85rem;
  line-height: 1.9;
}
.terminal-body .cmd::before { content: "jj@jjoly.eu:~$ "; color: var(--accent); }
.terminal-body .out { color: var(--text-dim); }
.cursor {
  display: inline-block;
  width: 8px; height: 15px;
  background: var(--accent);
  vertical-align: text-bottom;
  animation: blink 1.1s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

/* ---------- Cards / grids ---------- */
.grid {
  display: grid;
  gap: 1.1rem;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1.4rem;
  transition: border-color 0.2s, transform 0.2s;
}
.card:hover { border-color: var(--accent); transform: translateY(-3px); }
.card h3 {
  font-family: var(--mono);
  font-size: 0.98rem;
  color: var(--heading);
  margin-bottom: 0.7rem;
}
.card h3 .icon { color: var(--accent); margin-right: 0.4rem; }
.card p { color: var(--text-dim); font-size: 0.92rem; }
.card ul { list-style: none; margin-top: 0.6rem; }
.card ul li {
  color: var(--text-dim);
  font-size: 0.9rem;
  padding-left: 1.1rem;
  position: relative;
  margin-bottom: 0.3rem;
}
.card ul li::before { content: "▸"; color: var(--accent); position: absolute; left: 0; }

/* ---------- Tags ---------- */
.tags { display: flex; flex-wrap: wrap; gap: 0.45rem; margin-top: 1rem; }
.tag {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--accent);
  background: var(--accent-dim);
  border-radius: 4px;
  padding: 0.18rem 0.55rem;
}

/* ---------- Timeline ---------- */
.timeline { position: relative; padding-left: 1.6rem; }
.timeline::before {
  content: "";
  position: absolute;
  left: 5px; top: 6px; bottom: 6px;
  width: 2px;
  background: var(--border);
}
.tl-item { position: relative; padding-bottom: 2.2rem; }
.tl-item:last-child { padding-bottom: 0; }
.tl-item::before {
  content: "";
  position: absolute;
  left: -1.6rem; top: 7px;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--bg);
  border: 2px solid var(--accent);
}
.tl-date {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--amber);
}
.tl-item h3 { color: var(--heading); font-size: 1.05rem; margin: 0.2rem 0; }
.tl-item .place { color: var(--text-dim); font-size: 0.88rem; font-style: italic; }
.tl-item ul { list-style: none; margin-top: 0.7rem; }
.tl-item ul li {
  color: var(--text-dim);
  font-size: 0.92rem;
  padding-left: 1.1rem;
  position: relative;
  margin-bottom: 0.35rem;
}
.tl-item ul li::before { content: "▸"; color: var(--accent); position: absolute; left: 0; }

/* ---------- Projets ---------- */
.project-card { display: flex; flex-direction: column; }
.project-card .live {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}
.project-card .live::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse 2s infinite;
}
@keyframes pulse { 50% { opacity: 0.3; } }
.project-card .links { margin-top: auto; padding-top: 1rem; font-family: var(--mono); font-size: 0.82rem; }

/* ---------- Page projet ---------- */
.project-page { max-width: 780px; }
.project-page h1 {
  font-size: clamp(1.7rem, 5vw, 2.5rem);
  color: var(--heading);
  margin-bottom: 0.4rem;
}
.project-page .subtitle { color: var(--text-dim); font-size: 1.05rem; margin-bottom: 2rem; }
.project-page h2 {
  font-family: var(--mono);
  font-size: 1.05rem;
  color: var(--accent);
  margin: 2.4rem 0 0.9rem;
}
.project-page h2::before { content: "## "; color: var(--text-dim); }
.project-page p { color: var(--text); margin-bottom: 1rem; }
.project-page ul { margin: 0 0 1rem 1.3rem; color: var(--text); }
.project-page li { margin-bottom: 0.4rem; }
.project-page pre {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem 1.2rem;
  font-family: var(--mono);
  font-size: 0.82rem;
  overflow-x: auto;
  color: var(--text-dim);
  margin-bottom: 1rem;
}
.back-link { font-family: var(--mono); font-size: 0.85rem; }

/* ---------- Contact / footer ---------- */
.contact-box {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 2rem;
  text-align: center;
}
.contact-box p { color: var(--text-dim); max-width: 520px; margin: 0 auto 1.5rem; }
.contact-links { display: flex; justify-content: center; gap: 1rem; flex-wrap: wrap; }

footer {
  border-top: 1px solid var(--border);
  padding: 1.6rem;
  text-align: center;
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--text-dim);
}
footer .heart { color: var(--red); }

/* ---------- Reveal on scroll ----------
   ⚠️ L'apparition au scroll est pilotée par main.js (IntersectionObserver, qui
   ajoute .visible). Si le JS ne charge pas — blocage, erreur réseau, extension —
   un `opacity: 0` inconditionnel rendrait TOUT LE CONTENU INVISIBLE.
   La règle est donc conditionnée à `scripting: enabled` : sans JavaScript, rien
   n'est masqué et la page reste entièrement lisible. */
@media (scripting: enabled) {
  .reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.55s ease, transform 0.55s ease; }
}
.reveal.visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .cursor, .project-card .live::before { animation: none; }
}

@media (max-width: 640px) {
  .nav-links { gap: 0.9rem; }
  /* La barre ne tient pas en entier sur un petit écran. On masque les entrées
     secondaires — des ancres de la même page, atteignables en faisant défiler —
     et jamais ./contact, qui est le lien le plus utile depuis un téléphone.
     (L'ancienne règle `nth-child(n+5)` masquait justement ./contact : le
     masquage dépendait de la position, donc de tout ajout dans le menu.) */
  .nav-links li.nav-secondaire { display: none; }
}

/* ---------- Notes techniques ---------- */
.note-list { list-style: none; margin: 2rem 0 0; padding: 0; }
.note-item {
  border-top: 1px solid var(--border);
  padding: 1.6rem 0;
  margin: 0;
}
.note-item h2 {
  font-family: var(--sans, inherit);
  font-size: 1.15rem;
  color: var(--heading);
  margin: 0 0 0.3rem;
}
.note-item h2::before { content: none; }
.note-item h2 a { color: inherit; text-decoration: none; }
.note-item h2 a:hover { color: var(--accent); }
.note-item p { margin-bottom: 0.4rem; }
.note-meta {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--text-dim);
  margin-bottom: 1.4rem;
}

/* ---------- Accessibilité ----------
   Focus clavier visible partout : sans cette règle, un utilisateur au clavier
   ne sait pas où il se trouve (WCAG 2.4.7). */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}

/* Lien d'évitement : masqué jusqu'à ce qu'il reçoive le focus, il permet de
   sauter la navigation pour aller droit au contenu (WCAG 2.4.1). */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  background: var(--accent);
  color: var(--on-accent);
  padding: 0.7rem 1.2rem;
  font-family: var(--mono);
  font-weight: 600;
  border-radius: 0 0 8px 0;
}
.skip-link:focus {
  left: 0;
}

/* ---------- Pages d'erreur ----------
   Ces règles remplacent les anciens attributs style= inline : la CSP du site
   interdit tout style inline (pas de 'unsafe-inline'). */
.err-page {
  align-items: flex-start;
  justify-content: center;
  /* pas de 100vh : le contenu de rattrapage rendrait le pied de page
     inatteignable sans défilement inutile */
  min-height: auto;
  padding-top: clamp(3rem, 10vh, 6rem);
  padding-bottom: 3rem;
}
.err-code {
  font-family: var(--mono);
  font-size: clamp(3rem, 12vw, 6rem);
  color: var(--accent);
}
.err-title { color: var(--heading); }
footer .foot-links { margin-top: 0.4rem; }

/* Bloc de rattrapage des pages d'erreur : une impasse doit toujours proposer
   une sortie. Marqué <nav> pour être atteignable par raccourci de lecteur
   d'écran. */
.err-links {
  margin-top: 2.6rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--border);
  max-width: 640px;
}
.err-links h2 {
  font-family: var(--mono);
  font-size: 0.9rem;
  color: var(--text-dim);
  margin-bottom: 0.9rem;
}
.err-links ul { list-style: none; }
.err-links li {
  color: var(--text-dim);
  font-size: 0.93rem;
  padding-left: 1.1rem;
  position: relative;
  margin-bottom: 0.5rem;
}
.err-links li::before { content: "\25B8"; color: var(--accent); position: absolute; left: 0; }

/* ---------- Preuves vivantes (W4) ----------
   Contenu régénéré au build par outils/preuves.py. Aucune requête client :
   la pastille d'état n'est pas un moniteur, c'est le rendu d'un constat daté. */
.preuves {
  margin-top: 2.6rem;
  padding-top: 1.8rem;
  border-top: 1px solid var(--border);
}
.preuves > h3 {
  font-family: var(--mono);
  font-size: 0.95rem;
  color: var(--accent);
  margin-bottom: 1rem;
}
.preuves-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
  margin-bottom: 0.8rem;
}
.preuves-table caption {
  caption-side: bottom;
  text-align: left;
  color: var(--text-dim);
  font-size: 0.82rem;
  line-height: 1.6;
  padding-top: 0.9rem;
}
.preuves-table th,
.preuves-table td {
  text-align: left;
  padding: 0.55rem 0.7rem 0.55rem 0;
  border-bottom: 1px solid var(--border);
  vertical-align: baseline;
}
.preuves-table thead th {
  font-family: var(--mono);
  font-size: 0.76rem;
  font-weight: 500;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.preuves-table tbody th { font-weight: 600; color: var(--heading); }
.preuves-table code { font-family: var(--mono); color: var(--accent); font-size: 0.86rem; }
.preuves-table tbody td:last-child { color: var(--text-dim); white-space: nowrap; }

/* La pastille est décorative : l'état est déjà écrit en toutes lettres à côté,
   donc rien à annoncer pour un lecteur d'écran. */
.etat {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-right: 0.5rem;
  vertical-align: baseline;
}
.etat.ok { background: var(--accent); }
.etat.ko { background: var(--red); }

.preuves-chiffres { list-style: none; margin: 0.4rem 0 0.9rem; }
.preuves-chiffres li {
  color: var(--text-dim);
  font-size: 0.95rem;
  padding-left: 1.1rem;
  position: relative;
  margin-bottom: 0.4rem;
}
.preuves-chiffres li::before { content: "\25B8"; color: var(--accent); position: absolute; left: 0; }
.preuves-chiffres strong { color: var(--heading); font-family: var(--mono); }

/* ---------- Page /stack ---------- */
.stack-list { list-style: none; margin: 1.4rem 0 2.4rem; padding: 0; }
.stack-list > li {
  border-left: 2px solid var(--border);
  padding: 0 0 0 1.3rem;
  margin-bottom: 2rem;
}
.stack-list > li:hover { border-left-color: var(--accent); }
.stack-list h3 {
  font-family: var(--mono);
  font-size: 1rem;
  color: var(--heading);
  margin-bottom: 0.5rem;
}
.stack-list p { margin-bottom: 0.7rem; }
.stack-list p:last-child { margin-bottom: 0; }

/* Les renoncements sont le vrai contenu de la page : ils sont mis en retrait
   visuel, pas en note de bas de page. */
.ecarte, .consequence {
  font-size: 0.92rem;
  color: var(--text-dim);
  border-left: 2px solid var(--border);
  padding-left: 0.9rem;
}
.ecarte strong { color: var(--amber); }
.consequence strong { color: var(--red); }

/* ---------- CV ----------
   Cette page n'a pas de PDF jumeau : son rendu imprimé EST le PDF. D'où des
   règles @media print spécifiques plus bas dans ce fichier. */
.cv { max-width: 800px; }
.cv-astuce {
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 0 6px 6px 0;
  padding: 0.9rem 1.1rem;
  margin-bottom: 2.4rem;
  font-size: 0.88rem;
  color: var(--text-dim);
}
.cv-astuce kbd {
  font-family: var(--mono);
  font-size: 0.82rem;
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 0.05rem 0.35rem;
  color: var(--text);
}
.cv-tete { border-bottom: 1px solid var(--border); padding-bottom: 1.3rem; }
.cv-tete h1 { font-size: clamp(1.9rem, 5vw, 2.6rem); color: var(--heading); line-height: 1.15; }
.cv-titre { color: var(--text-dim); font-size: 1.02rem; margin-top: 0.3rem; }
.cv-contact {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  margin-top: 0.9rem;
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--text-dim);
}

.cv-bloc { margin-top: 2.2rem; }
.cv-bloc > h2 {
  font-family: var(--mono);
  font-size: 0.9rem;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 1rem;
}
.cv-poste { margin-bottom: 1.6rem; }
.cv-poste:last-child { margin-bottom: 0; }
.cv-poste h3 { color: var(--heading); font-size: 1.05rem; }
.cv-type { color: var(--text-dim); font-weight: 400; font-size: 0.9rem; }
.cv-meta { font-family: var(--mono); font-size: 0.8rem; color: var(--amber); margin-bottom: 0.5rem; }

.cv-bloc ul { list-style: none; }
.cv-bloc ul li {
  color: var(--text-dim);
  font-size: 0.93rem;
  padding-left: 1.1rem;
  position: relative;
  margin-bottom: 0.35rem;
}
.cv-bloc ul li::before { content: "\25B8"; color: var(--accent); position: absolute; left: 0; }
.cv-projets li, .cv-formation li { margin-bottom: 0.7rem; }
.cv-projets strong, .cv-formation strong { color: var(--heading); }

.cv-competences { margin: 0; }
.cv-competences dt {
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--heading);
  margin-top: 0.8rem;
}
.cv-competences dt:first-child { margin-top: 0; }
.cv-competences dd { margin: 0.2rem 0 0; color: var(--text-dim); font-size: 0.9rem; }

/* ---------- Impression / « Enregistrer en PDF » ----------
   Un portfolio se retrouve souvent imprimé ou converti en PDF par un
   recruteur. Sans cette feuille, le thème sombre sort en aplats d'encre
   illisibles et tous les liens perdent leur destination.
   Principes : fond blanc, texte noir, URLs des liens en note, et suppression
   du chrome de navigation qui n'a aucun sens sur papier. */
@media print {
  :root {
    --bg: #ffffff;
    --bg-alt: #ffffff;
    --panel: #ffffff;
    --border: #999999;
    --text: #000000;
    --heading: #000000;
    --text-dim: #333333;
    --accent: #000000;
    --accent-dim: transparent;
    --amber: #000000;
    --red: #000000;
    --nav-bg: transparent;
  }

  body {
    background: #ffffff;
    color: #000000;
    font-size: 11pt;
    line-height: 1.45;
  }

  /* Éléments sans valeur sur papier */
  .nav,
  .skip-link,
  .hero-actions,
  .cursor,
  .terminal-bar,
  footer .foot-links,
  .back-link {
    display: none !important;
  }

  /* Sans cette règle, les blocs animés s'impriment vides (opacity: 0). */
  .reveal {
    opacity: 1 !important;
    transform: none !important;
  }

  .hero { min-height: auto; padding-top: 0; }
  .section { padding-top: 1.2rem; padding-bottom: 1.2rem; max-width: none; }

  .card,
  .terminal,
  .note-item {
    border: 1px solid #999999;
    box-shadow: none;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  h1, h2, h3 { break-after: avoid; page-break-after: avoid; }

  /* Un lien imprimé sans son URL est un cul-de-sac : on la note à la suite.
     Ancres internes et mailto: restent lisibles tels quels, on les exclut. */
  a[href^="http"]::after {
    content: " <" attr(href) ">";
    font-family: var(--mono);
    font-size: 9pt;
    color: #333333;
    word-break: break-all;
  }
  a[href$=".html"]::after {
    content: " <jjoly.eu/" attr(href) ">";
    font-family: var(--mono);
    font-size: 9pt;
    color: #333333;
  }
  a[href^="#"]::after,
  a[href^="mailto:"]::after,
  .nav a::after,
  .tag::after { content: ""; }

  .tag { border: 1px solid #999999; background: transparent; }


  /* --- CV --- Le rendu imprimé de /cv.html tient lieu de PDF : pas de fichier
     jumeau à maintenir. L'encadré d'explication, inutile sur papier, disparaît ;
     les URLs des liens de contact aussi, puisqu'elles sont déjà écrites en
     toutes lettres. */
  .cv-astuce { display: none !important; }
  .cv { max-width: none; }
  .cv-tete { border-bottom: 1.5pt solid #000000; }
  .cv-bloc { margin-top: 1.1rem; break-inside: auto; }
  .cv-bloc > h2 {
    border-bottom: 0.5pt solid #999999;
    padding-bottom: 0.15rem;
    margin-bottom: 0.5rem;
  }
  .cv-poste, .cv-projets li, .cv-formation li {
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .cv-contact { gap: 0.2rem 0.9rem; }
  .cv-contact a::after,
  .cv-projets a::after,
  .cv-bloc a::after { content: "" !important; }
  .cv-bloc ul li { margin-bottom: 0.15rem; }

  @page { margin: 1.6cm; }
}
