@font-face {
  font-family: "Bricolage";
  src: url("assets/bricolage-latin.woff2") format("woff2");
  font-weight: 200 800;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("assets/inter-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}

/* Variables, base typographique, boutons et barre : voir agents/layout.css, partagé avec le cours. */
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { overflow-x: hidden; }
h1, h2, h3 { margin: 0; }
a { color: inherit; }
img { max-width: 100%; display: block; }

.saut { position: absolute; left: -999px; }
.saut:focus { left: 1rem; top: 1rem; z-index: 100; background: var(--bleu-vif); color: var(--encre); padding: 0.5rem 0.75rem; border-radius: var(--rayon-s); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Canevas fixe : le nom reste en place pendant que la caméra le traverse. */
.particules { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; transition: opacity 0.3s; }
main, .pied, .index-cv { position: relative; z-index: 1; }

/* Index du CV, à la place du plan des modules dans le cours. */
.index-cv { display: none; }
@media (min-width: 83rem) and (min-height: 44rem) {
  .index-cv {
    position: fixed; left: 1.25rem; top: 50%; transform: translateY(-50%); z-index: 40;
    display: flex; flex-direction: column;
  }
  .index-cv a {
    padding: 0.3rem 0 0.3rem 0.75rem; border-left: 2px solid var(--trait);
    font-size: 0.875rem; line-height: 1.4; color: var(--doux); text-decoration: none; transition: color 0.15s ease-out, border-color 0.15s ease-out;
  }
  .index-cv a:hover { color: #fff; }
  .index-cv a[aria-current] { color: #fff; border-left-color: var(--bleu-vif); }
}

/* Accueil : les particules sont le seul moment spectaculaire du site. */
.accueil {
  position: relative; min-height: calc(100svh - var(--hauteur-barre)); display: grid; place-items: center; text-align: center;
  padding: 3rem var(--gouttiere); overflow: hidden;
}
.accueil-contenu { position: relative; }
.statut-accueil { margin: 0 0 1.25rem; font-size: 0.9375rem; color: var(--texte); text-wrap: balance; }
.pastille { display: inline-block; width: 8px; height: 8px; margin-right: 0.5rem; border-radius: 50%; background: #a6d189; vertical-align: 0.08em; }
.accueil h1 { font-size: clamp(2.5rem, 7vw, 4.5rem); line-height: 1; font-weight: 800; color: #fff; }
/* Avec WebGL, le titre HTML garde sa place et son texte pour les lecteurs d'écran, mais c'est le canevas qui le dessine. */
.webgl .accueil h1 { color: transparent; }
/* Hauteur fixe d'une ligne : le texte tapé ne fait pas bouger la page. */
.fonction { margin: 1.25rem 0 0.25rem; min-height: 1.7em; white-space: nowrap; font-size: clamp(1rem, 2.2vw, 1.3rem); color: var(--bleu-vif); font-weight: 500; }
.curseur { display: inline-block; width: 2px; height: 1.1em; margin-left: 3px; vertical-align: -0.18em; background: var(--bleu-vif); animation: clignote 1s steps(1) infinite; }
@keyframes clignote { 50% { opacity: 0; } }
.lieu { margin: 0; color: var(--doux); font-size: 0.9375rem; text-wrap: balance; }
.actions-accueil { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.75rem; margin-top: 2rem; }
.precision { margin: 0.9rem auto 0; max-width: 40ch; color: var(--doux); font-size: 0.875rem; line-height: 1.5; text-wrap: balance; }

/* Sections : une largeur, titres à gauche, comme dans le cours. */
.section { max-width: calc(var(--large) + 2 * var(--gouttiere)); margin-inline: auto; padding-block: 5rem 1rem; padding-inline: var(--gouttiere); }
.titre { font-size: clamp(1.6rem, 3.5vw, 2.3rem); font-weight: 800; margin-bottom: 1.25rem; }
.intro-stack, .intro-projets { max-width: var(--mesure); margin: 0 0 2.25rem; color: var(--doux); text-wrap: pretty; }
.intro-stack a { color: var(--bleu-vif); }
.sous-titre { margin: 3rem 0 1.25rem; font-size: 1.5rem; font-weight: 700; }

.carte { padding: 1.4rem; border-radius: var(--rayon); background: var(--carte); border: 1px solid var(--trait); }

.profil { display: grid; grid-template-columns: 17rem 1fr; gap: 3rem; align-items: start; }
.portrait { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--rayon); outline: 1px solid rgba(255, 255, 255, 0.1); outline-offset: -1px; }
.texte { max-width: var(--mesure); }
.texte p { margin: 0 0 1rem; color: #c3c8e0; text-wrap: pretty; }

.chiffres { display: grid; grid-template-columns: repeat(3, 1fr); margin: 3rem 0 0; border-block: 1px solid var(--trait); }
.chiffres div { padding: 1.5rem 1.25rem; }
.chiffres div:first-child { padding-left: 0; }
.chiffres div + div { border-left: 1px solid var(--trait); }
.chiffres dt { font: 800 2.1rem/1 "Bricolage", sans-serif; color: #fff; font-variant-numeric: tabular-nums; }
.chiffres dt small { font-size: 1.125rem; font-weight: 600; color: var(--doux); margin-left: 0.25rem; }
.chiffres dd { margin: 0.5rem 0 0; font-size: 0.875rem; line-height: 1.5; color: var(--doux); }
.chiffres-brain { margin: 0 0 2rem; }

/* Technologies : le bleu mesure le niveau, il ne décore pas les catégories. */
.legende { display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem; margin: -1rem 0 2rem; font-size: 0.8125rem; color: var(--doux); }
.legende span { display: inline-flex; align-items: center; gap: 0.5rem; }
.points { display: inline-flex; gap: 3px; }
.points i { width: 6px; height: 6px; border-radius: 50%; background: rgba(146, 152, 188, 0.25); }
.points i.plein { background: var(--structure); }
.grille-competences { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
.carte-tete { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; }
.icone { display: grid; place-items: center; flex: none; width: 2.25rem; height: 2.25rem; border-radius: var(--rayon-s); color: var(--bleu-vif); background: rgba(130, 214, 232, 0.1); }
.icone svg { width: 18px; height: 18px; }
.carte-tete h3 { font-size: 1.125rem; }
.maitrise { display: grid; grid-template-columns: 1fr auto; gap: 0.35rem; margin-bottom: 1.1rem; font-size: 0.8125rem; line-height: 1.3; }
.maitrise span { color: var(--doux); }
.maitrise strong { font-variant-numeric: tabular-nums; }
.maitrise i { grid-column: 1 / -1; height: 3px; border-radius: 3px; background: rgba(146, 152, 188, 0.15); overflow: hidden; }
.maitrise i::before {
  content: ""; display: block; height: 100%; width: var(--valeur); border-radius: inherit; background: var(--structure);
  transform-origin: left; transform: scaleX(0); transition: transform 0.8s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.maitrise.vu i::before { transform: none; }
.carte.vedette { grid-column: 1 / -1; border-color: var(--trait-fort); }
.carte.vedette .items { grid-template-columns: repeat(3, 1fr); }
.items { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem 0.9rem; }
.items li { font-size: 0.875rem; line-height: 1.4; }
.items li .points { display: flex; margin-top: 0.25rem; }
.carte .resume { margin: 1rem 0 0; font-size: 0.875rem; line-height: 1.5; color: var(--doux); text-wrap: pretty; }

/* Méthode et Brain : une vraie suite d'étapes, donc numérotée. */
.boucle { list-style: none; margin: 0 0 1.75rem; padding: 0; display: grid; grid-template-columns: repeat(5, 1fr); gap: 0.75rem; }
.boucle li { position: relative; display: grid; align-content: start; gap: 0.25rem; padding: 1rem; border-radius: var(--rayon-m); background: var(--carte); border: 1px solid var(--trait); }
.boucle li:not(:last-child)::after { content: "→"; position: absolute; right: -0.375rem; top: 50%; z-index: 1; transform: translate(50%, -50%); color: var(--bleu-vif); font-size: 0.875rem; }
.boucle li:last-child { border-color: var(--trait-fort); }
.boucle li:last-child::after { content: "↺ boucle"; position: absolute; right: 0.75rem; top: 1rem; font-size: 0.75rem; line-height: 1.4; color: var(--bleu-vif); }
.boucle .numero { font: 700 1.25rem/1.2 "Bricolage", sans-serif; color: var(--structure); font-variant-numeric: tabular-nums; }
.boucle strong { font-size: 1rem; }
.boucle li > span:last-child { font-size: 0.8125rem; line-height: 1.5; color: var(--doux); }

.grille-qualites { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; }
.qualite { display: flex; flex-direction: column; align-items: flex-start; }
.qualite h3 { margin: 0.9rem 0 0.4rem; font-size: 1.125rem; }
.qualite p { margin: 0; font-size: 0.875rem; line-height: 1.55; color: var(--doux); text-wrap: pretty; }
.qualite code {
  margin-top: auto; translate: 0 0.75rem; margin-bottom: 0.75rem; padding: 0.15rem 0.4rem; border-radius: 6px; font: 0.75rem/1.5 ui-monospace, monospace;
  color: var(--texte); background: rgba(146, 152, 188, 0.1);
}

.depart { display: grid; grid-template-columns: 13rem 1fr; gap: 0.6rem 1.5rem; margin: 0; padding: 1.1rem 1.4rem; border-radius: var(--rayon-m); border: 1px solid var(--trait); background: var(--carte); }
.depart-titre { margin: 0; font-size: 0.9375rem; font-weight: 600; color: #fff; }
.depart ul { margin: 0; padding: 0 0 0 1.1rem; display: grid; grid-template-columns: 1fr 1fr; gap: 0.3rem 1.75rem; font-size: 0.875rem; line-height: 1.5; color: var(--doux); }
.depart li::marker { color: var(--bleu-vif); }

/* Parcours */
.frise { list-style: none; margin: 0; padding: 0 0 0 1.6rem; border-left: 1px solid var(--trait); }
.frise > li { position: relative; max-width: var(--mesure); padding-bottom: 2.25rem; }
.frise > li::before { content: ""; position: absolute; left: calc(-1.6rem - 6px); top: 0.45rem; width: 11px; height: 11px; border-radius: 50%; background: var(--nuit); border: 2px solid var(--bleu-vif); }
.frise .quand { margin: 0; font-size: 0.875rem; font-weight: 500; color: var(--structure); font-variant-numeric: tabular-nums; }
.frise .quand span { color: var(--doux); font-weight: 400; margin-left: 0.6rem; }
.frise h3 { font-size: 1.2rem; margin: 0.35rem 0 0.1rem; }
.frise .poste { margin: 0 0 0.6rem; color: var(--doux); font-size: 0.9375rem; }
.frise ul { margin: 0; padding-left: 1.1rem; color: #c3c8e0; font-size: 0.9375rem; }
.frise ul li { padding-bottom: 0.3rem; text-wrap: pretty; }
.frise ul li::marker { color: var(--bleu-vif); }

/* Projets */
.grille-projets { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
.projet { display: flex; flex-direction: column; overflow: hidden; padding: 0; }
.projet .visuel { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: var(--nuit-2); }
.projet .visuel img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
.projet .statut {
  position: absolute; top: 0.75rem; left: 0.75rem; display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.2rem 0.55rem; border-radius: 6px; font-size: 0.75rem; font-weight: 500; line-height: 1.5;
  background: rgba(15, 17, 32, 0.86); color: var(--texte);
}
.projet .statut::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--doux); }
.projet .statut.live::before { background: #a6d189; }
.projet .statut.prive::before { background: #fbbf24; }
.projet .statut.client::before { background: #fb923c; }
.projet .corps { display: flex; flex: 1; flex-direction: column; padding: 1.1rem 1.25rem 1.25rem; }
.projet .categorie { margin-bottom: 0.35rem; font-size: 0.8125rem; line-height: 1.4; color: var(--doux); }
.projet h3 { font-size: 1.25rem; margin: 0 0 0.5rem; }
.projet p { margin: 0 0 0.9rem; font-size: 0.875rem; line-height: 1.55; color: var(--doux); text-wrap: pretty; }
.jetons { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.35rem; }
.jetons li { padding: 0.1rem 0.5rem; border-radius: 6px; font-size: 0.75rem; line-height: 1.6; color: #c3c8e0; background: rgba(146, 152, 188, 0.1); }
.projet .bouton { margin-top: auto; }
.projet .jetons + .bouton { margin-top: 1.1rem; }
.projet .jetons:has(+ .bouton) { margin-bottom: auto; }
.formation { margin-top: 3rem; }
.formation h3 { font-size: 1.25rem; margin-bottom: 0.75rem; }
.langues-parlees { margin: 0.75rem 0 0; color: var(--doux); font-size: 0.875rem; }

/* Contact : barre fixe en bas de l'écran, avec l'appel vers le cours à droite. */
:root { --hauteur-contact: 4.75rem; }
body:has(.contact-fixe) { padding-bottom: var(--hauteur-contact); }
.contact-fixe {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45; height: var(--hauteur-contact);
  display: flex; align-items: center; gap: 1rem;
  padding-inline: max(var(--gouttiere), calc((100% - var(--large)) / 2));
  background: rgba(15, 17, 32, 0.9); backdrop-filter: blur(12px); border-top: 1px solid var(--trait);
}
.contact-titre { flex: none; margin: 0; font-size: 1.0625rem; color: #fff; white-space: nowrap; }
.liens-contact { display: flex; gap: 0.5rem; min-width: 0; }
.liens-contact a {
  display: flex; align-items: center; gap: 0.6rem; min-width: 0; padding: 0.4rem 0.8rem; border-radius: var(--rayon-m); text-decoration: none;
  background: var(--carte); border: 1px solid var(--trait); transition: border-color 0.15s ease-out, background-color 0.15s ease-out;
}
.liens-contact a:first-child { border-color: var(--bleu-vif); }
.liens-contact a:hover { border-color: var(--bleu-vif); background: var(--surface); }
.liens-contact a span { display: block; font-size: 0.75rem; line-height: 1.3; color: var(--doux); }
.liens-contact a strong { display: block; font-size: 0.875rem; line-height: 1.3; white-space: nowrap; }
.liens-contact .icone { width: auto; height: auto; background: none; }
.liens-contact .icone svg { width: 18px; height: 18px; }
.contact-cta { flex: none; margin-left: auto; }
.contact-cta .court { display: none; }

/* Le rail répète les liens de la barre : masqué sur le CV. Le bouton Meet passe à gauche, au-dessus de la barre. */
body:has(.contact-fixe) .rail { display: none; }
body:has(.contact-fixe) .bouton-meet { right: auto; left: 20px; bottom: calc(var(--hauteur-contact) + 20px); }
body:has(.contact-fixe) .bouton-meet .bulle { right: auto; left: calc(100% + 0.75rem); transform: translateX(-6px); }
body:has(.contact-fixe) .bouton-meet:hover .bulle, body:has(.contact-fixe) .bouton-meet:focus-visible .bulle { transform: none; }

@media (max-width: 82rem) {
  .contact-titre { display: none; }
}
/* Écran moyen : les liens ne gardent que leur icône, le texte reste lu par les lecteurs d'écran. */
@media (max-width: 62rem) {
  .liens-contact a { width: 2.75rem; height: 2.75rem; padding: 0; justify-content: center; }
  .liens-contact a div { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}
@media (max-width: 40rem) {
  :root { --hauteur-contact: 4rem; }
  .contact-fixe { gap: 0.5rem; }
  .contact-cta .long { display: none; }
  .contact-cta .court { display: inline; }
}

.pied { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.25rem 1.25rem; padding: 1.75rem var(--gouttiere); font-size: 0.8125rem; color: var(--doux); border-top: 1px solid var(--trait); }

/* Mentions légales */
.legal { max-width: calc(var(--mesure) + 2 * var(--gouttiere)); margin-inline: auto; padding: 3.5rem var(--gouttiere) 5rem; }
.legal h1 { font-size: clamp(1.6rem, 3.5vw, 2.3rem); margin-bottom: 1.5rem; }
.legal h2 { font-size: 1.25rem; margin: 2rem 0 0.4rem; }
.legal a { color: var(--bleu-vif); }

@media (max-width: 62rem) {
  .grille-competences, .grille-projets, .grille-qualites { grid-template-columns: 1fr 1fr; }
  .boucle { grid-template-columns: repeat(3, 1fr); }
  .profil { grid-template-columns: 1fr; gap: 1.5rem; }
  .portrait { max-width: 12rem; }
}
@media (max-width: 40rem) {
  .grille-competences, .grille-projets, .grille-qualites { grid-template-columns: 1fr; }
  .carte.vedette .items { grid-template-columns: 1fr 1fr; }
  .boucle { grid-template-columns: 1fr; }
  .boucle li:not(:last-child)::after { content: "↓"; right: 50%; top: auto; bottom: -0.375rem; transform: translate(50%, 50%); }
  .chiffres { grid-template-columns: 1fr; }
  .chiffres div { padding-inline: 0; }
  .chiffres div + div { border-left: 0; border-top: 1px solid var(--trait); }
  .depart, .depart ul { grid-template-columns: 1fr; }
  .section { padding-top: 4.5rem; }
  .actions-accueil .bouton { width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .curseur { animation: none; }
  .maitrise i::before { transition: none; }
}
