/* HERO */
.hero { padding: 5rem 0 4rem; border-bottom: 1px solid var(--border); position: relative; }

/* Lueur du hero : deux halos aux couleurs de la marque, dérive très lente.
   Réglée à la limite du perceptible — si on la remarque, elle est trop forte.
   z-index négatif sans isolation : le halo passe derrière tout le contenu du hero
   sans créer de contexte d'empilement qui piégerait les infobulles .hero-cred. */
.hero::before {
  content: "";
  position: absolute;
  top: -8rem; bottom: -4rem; left: -18vw; right: -18vw;
  z-index: -1; pointer-events: none;
  background:
    radial-gradient(40% 44% at 34% 40%, rgba(26, 122, 85, 0.07), transparent 72%),
    radial-gradient(36% 40% at 72% 26%, rgba(26, 92, 168, 0.07), transparent 72%);
  /* seul transform est animé : composité, aucun repaint de la page au défilement */
  animation: heroDrift 46s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes heroDrift {
  from { transform: translate3d(-2%, -1%, 0) scale(1); }
  to   { transform: translate3d(2%, 1.5%, 0) scale(1.07); }
}
/* Sur mobile le hero est déjà rempli par la photo et les cartes, et c'est là que la
   batterie compte : trame et halo disparaissent. */
@media (max-width: 760px) {
  .hero::before { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hero::before { animation: none; }
}
.hero-layout { display: grid; grid-template-columns: 1fr auto; gap: 3rem; align-items: start; }

.avail {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: 'DM Mono', monospace; font-size: 11px;
  color: var(--green); background: var(--green-bg);
  border: 1px solid var(--green-bd);
  padding: 4px 12px; border-radius: 99px;
  margin-bottom: 2rem;
  animation: fadeUp 0.4s ease both;
}
.avail-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); }

.hero h1 {
  font-size: clamp(32px, 4.5vw, 50px);
  font-weight: 300; letter-spacing: -0.04em; line-height: 1.08;
  margin-bottom: 1.25rem;
  animation: fadeUp 0.4s 0.08s ease both;
}
.hero h1 strong { font-weight: 600; }
.hero-sub {
  font-size: 16px; font-weight: 300; color: var(--text2);
  line-height: 1.75; max-width: 500px; margin-bottom: 2rem;
  animation: fadeUp 0.4s 0.14s ease both;
}
.hero-actions { display: flex; gap: 10px; flex-wrap: wrap; animation: fadeUp 0.4s 0.2s ease both; }

/* PROFILE CARD */
.profile-aside { animation: fadeUp 0.4s 0.12s ease both; }
.pcard {
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: 0; padding: 1.5rem 1.75rem; min-width: 340px;
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.3s ease,
              background 0.2s ease, border-color 0.2s ease;
}
.pcard:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 36px rgba(0, 0, 0, 0.10);
  background: var(--blue-bg); border-color: var(--blue-bd);
}
/* les filets de séparation suivent, sinon ils tranchent sur le fond bleu */
.pcard:hover .prow { border-bottom-color: var(--blue-bd); }
@media (prefers-reduced-motion: reduce) {
  .pcard { transition: background 0.2s ease, border-color 0.2s ease; }
  .pcard:hover { transform: none; box-shadow: none; }
}
/* accueil, section contact : texte à gauche, carte d'infos calée à droite.
   Une grille et non un flex : avec flex-wrap la carte passait à la ligne dès que
   la colonne de texte atteignait sa largeur naturelle. */
.contact-split {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 3rem; align-items: start;
}
@media (max-width: 760px) {
  .contact-split { grid-template-columns: 1fr; gap: 2.5rem; }
  .contact-split .pcard { justify-self: stretch; min-width: 0; }
}
.pcard-title {
  font-family: 'DM Mono', monospace; font-size: 10px;
  color: var(--text3); letter-spacing: 0.1em;
  text-transform: uppercase; margin-bottom: 1rem;
}
.prow {
  display: flex; justify-content: space-between; align-items: center;
  gap: 1.5rem;                 /* sans quoi libellé et valeur se touchent sur les lignes longues */
  padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 13px;
}
.prow-val { white-space: nowrap; }
.prow:last-child { border-bottom: none; }
.prow-label { color: var(--text2); font-weight: 300; white-space: nowrap; }
.prow-val { font-family: 'DM Mono', monospace; font-size: 12px; font-weight: 500; color: var(--text); }
.prow-val.green { color: var(--green); }

/* STACK */
.stack-grid { display: flex; flex-direction: column; gap: 1.25rem; }
.stack-row { display: flex; flex-direction: column; gap: 0.4rem; }
.stack-lbl {
  font-family: 'DM Mono', monospace; font-size: 10px;
  color: var(--text3); text-transform: uppercase; letter-spacing: 0.08em;
}

/* SERVICES */
.svcs {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: 1px; background: var(--border);
  border: 1px solid var(--border); border-radius: var(--r3); overflow: hidden;
}
.svc { background: var(--bg2); padding: 1.75rem; transition: background 0.15s; }
.svc:hover { background: var(--bg3); }
.svc-num { font-family: 'DM Mono', monospace; font-size: 10px; color: var(--text3); margin-bottom: 1rem; }
.svc h3 { font-size: 15px; font-weight: 500; letter-spacing: -0.01em; margin-bottom: 0.5rem; }
.svc .tagline { font-size: 12px; color: var(--text3); font-family: 'DM Mono', monospace; margin-bottom: 0.75rem; }
.svc p { font-size: 13.5px; color: var(--text2); line-height: 1.65; font-weight: 300; }
.svc-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 1rem; }
.stag {
  font-family: 'DM Mono', monospace; font-size: 10.5px;
  padding: 2px 8px; border: 1px solid var(--border);
  border-radius: 3px; color: var(--text3);
}

/* PÉRIMÈTRE */
.perimetre { margin-top: 2.5rem; padding-top: 2rem; border-top: 1px solid var(--border); }
.perimetre-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.6rem 2rem; }
.perimetre-item {
  display: flex; align-items: baseline; gap: 0.6rem;
  font-size: 13px; color: var(--text2); line-height: 1.6; font-weight: 300;
}
.perimetre-dot {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--green); flex-shrink: 0; margin-top: 7px;
}

@media (max-width: 640px) { .perimetre-grid { grid-template-columns: 1fr; } }

/* MISSIONS */
.missions {
  display: flex; flex-direction: column;
  border: 1px solid var(--border); border-radius: var(--r3);
  overflow: hidden; background: var(--bg2);
}
.mission { padding: 1.75rem; border-bottom: 1px solid var(--border); transition: background 0.15s; }
.mission:last-child { border-bottom: none; }
.mission:hover { background: var(--bg3); }
.mission-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; margin-bottom: 0.4rem; flex-wrap: wrap;
}
.mission-co { font-size: 15px; font-weight: 500; }
/* Étiquette de rôle : un libellé, pas une action — donc angles vifs.
   Seules les pilules cliquables de la carte stack gardent leur forme ronde. */
.mission-badge {
  font-family: 'DM Mono', monospace; font-size: 10.5px;
  color: var(--text2); background: var(--bg3);
  border: 1px solid var(--border2); padding: 3px 10px;
  border-radius: 0; white-space: nowrap;
}
.mission-period { font-family: 'DM Mono', monospace; font-size: 11px; color: var(--text3); margin-bottom: 0.85rem; }
.mission-lead { font-size: 14px; color: var(--text2); line-height: 1.55; margin-bottom: 0.85rem; max-width: 68ch; }
.mission ul { list-style: none; display: flex; flex-direction: column; gap: 13px; max-width: 68ch; }
.mission li {
  font-size: 13.5px; color: var(--text2); line-height: 1.65;
  padding-left: 1.1rem; position: relative; font-weight: 300;
}
.mission li strong { font-weight: 500; color: var(--text); }
.mission li::before { content: '—'; position: absolute; left: 0; color: var(--text3); font-size: 11px; top: 2px; }

/* MISSIONS — timeline verticale alternée (career timeline) */
.timeline { position: relative; }
.timeline::before {
  content: ''; position: absolute; left: 50%; top: 6px; bottom: 6px;
  width: 2px; background: var(--border); transform: translateX(-50%);
}
.tl-entry { position: relative; margin-bottom: 2.5rem; }
.tl-entry:last-child { margin-bottom: 0; }

/* pastille / nœud (année de début), centrée sur l'axe */
.tl-marker {
  position: absolute; left: 50%; top: 1.6rem; z-index: 2;
  width: 44px; height: 44px; transform: translateX(-50%);
  border-radius: 50%;
  background: var(--bg2); border: 1px solid var(--blue);
  box-shadow: 0 0 0 4px var(--bg);
  display: grid; place-items: center;
  font-family: 'DM Mono', monospace; font-size: 11px; font-weight: 500;
  color: var(--blue); letter-spacing: -0.02em;
}

/* carte d'expérience, alternée gauche / droite */
.timeline .mission {
  position: relative;
  width: calc(50% - 2.75rem);
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: 0; padding: 1.5rem 1.75rem;
  transition: background 0.15s, border-color 0.15s;
}
.timeline .mission:hover { background: var(--blue-bg); border-color: var(--blue-bd); }
.tl-entry:nth-child(odd) .mission { margin-left: 0; }
.tl-entry:nth-child(even) .mission { margin-left: calc(50% + 2.75rem); }

/* connecteur horizontal carte → axe */
.timeline .mission::after {
  content: ''; position: absolute; top: calc(1.6rem + 21px);
  width: 2.75rem; height: 2px; background: var(--border);
}
.tl-entry:nth-child(odd) .mission::after { right: -2.75rem; }
.tl-entry:nth-child(even) .mission::after { left: -2.75rem; }

/* indicateur "voir les réalisations" (label + chevron) — la carte entière est cliquable */
.mission-toggle {
  margin-top: 0.9rem; padding: 4px 0;
  display: inline-flex; align-items: center; gap: 7px;
  font-family: 'DM Mono', monospace; font-size: 12px;
  color: var(--blue); transition: color 0.15s;
}
.mission-toggle::after {
  content: '›'; font-size: 15px; line-height: 1;
  transform: rotate(90deg); transition: transform 0.2s;
}
.mission-toggle.open::after { transform: rotate(-90deg); }

/* La carte est le bouton : curseur, survol, focus clavier */
.timeline .mission.is-toggle {
  cursor: pointer;
  transition: box-shadow 0.2s ease, border-color 0.2s ease, background 0.15s ease;
}
.timeline .mission.is-toggle:hover { border-color: var(--border2); box-shadow: 0 6px 22px rgba(0, 0, 0, 0.06); }
.timeline .mission.is-toggle:hover .mission-toggle { color: var(--li-dark); }
.timeline .mission.is-toggle:focus-visible { outline: 2px solid var(--text); outline-offset: 3px; }

/* appel à cliquer : la CARTE pulse (halo) + le chevron rebondit tant que c'est replié */
.timeline .mission.is-toggle:not(.open) { animation: cardInvite 1.5s ease-in-out infinite; }
.timeline .mission.is-toggle:not(.open) .mission-toggle::after { animation: missionChevron 1.6s ease-in-out infinite; }
.timeline .mission.is-toggle:hover { animation: none; }               /* stop au survol → ombre de survol nette */
.tl-entry:nth-child(2) .mission.is-toggle:not(.open) { animation-delay: 0.4s; }
.tl-entry:nth-child(3) .mission.is-toggle:not(.open) { animation-delay: 0.8s; }

@keyframes cardInvite {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(0, 0, 0, 0), 0 0 0 0 rgba(0, 0, 0, 0);
    border-color: var(--border);
  }
  50% {
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.16), 0 0 0 6px var(--bg3);
    border-color: var(--text3);
  }
}
@keyframes missionChevron {
  0%, 100% { transform: rotate(90deg) translateX(0); }
  50%      { transform: rotate(90deg) translateX(5px); }
}
@media (prefers-reduced-motion: reduce) {
  .timeline .mission.is-toggle, .mission-toggle::after { animation: none !important; }
}
.timeline .mission ul { margin-top: 0.9rem; }
.timeline .mission ul[hidden] { display: none; }

/* TECHMAP — carte radiale interactive des technologies (techmap.js) */
.techmap { position: relative; width: 100%; max-width: 820px; margin: 1.5rem auto 0; }
/* sur grand écran : full-bleed pour aérer la carte radiale */
@media (min-width: 1000px) {
  .techmap.is-enhanced {
    width: min(94vw, 1160px); max-width: none;
    left: 50%; transform: translateX(-50%);
    margin: 2.5rem 0 4.5rem;   /* respiration : les anneaux qui débordent en haut/bas ne percutent rien */
  }
}
/* invite au clic : le nœud central n'est cliquable que là où la carte radiale se construit */
.techmap-hint {
  display: none;
  font-family: 'DM Mono', monospace; font-size: 12px;
  color: var(--text3); margin-top: -1.75rem;
}
@media (min-width: 1000px) { .techmap-hint { display: block; } }

/* RECHERCHE DANS LA STACK (stack-search.js) */
.stack-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1.5rem 2rem; flex-wrap: wrap;
}
.stack-head .section-sub { margin-bottom: 0; }
/* dans l'en-tête, le sous-titre ne pousse plus : l'invite reprend une marge normale */
.stack-head .techmap-hint { margin-top: 0.5rem; }
.stack-search { position: relative; display: flex; align-items: center; flex: none; }
.stack-search svg {
  position: absolute; left: 12px; width: 15px; height: 15px;
  color: var(--text3); pointer-events: none;
}
.stack-search input {
  font-family: 'DM Mono', monospace; font-size: 12.5px; color: var(--text);
  background: var(--bg2); border: 1px solid var(--border2); border-radius: 0;
  padding: 9px 12px 9px 34px; width: 250px; max-width: 100%;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.stack-search input::placeholder { color: var(--text3); }
.stack-search input:focus {
  outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-bg);
}
.stack-results { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 1.5rem; }
.stack-results[hidden] { display: none; }
.stack-res-count {
  font-family: 'DM Mono', monospace; font-size: 10px;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--text3);
  margin-right: 4px;
}
.stack-hit {
  display: inline-flex; align-items: baseline; gap: 8px;
  font-size: 13px; padding: 5px 11px; border-radius: var(--r);
  background: var(--blue-bg); border: 1px solid var(--blue-bd); color: var(--blue);
}
.stack-hit em {
  font-style: normal; font-family: 'DM Mono', monospace;
  font-size: 10px; color: var(--text3);
}
.stack-empty { font-size: 13.5px; color: var(--text2); line-height: 1.6; max-width: 540px; }
/* la preuve suit sa pastille : elle casse la ligne pour rester lisible */
.stack-proof {
  flex-basis: 100%; margin: -2px 0 4px 2px;
  font-family: 'DM Mono', monospace; font-size: 11px; color: var(--text3);
}
.stack-proof a { color: var(--blue); text-decoration: none; border-bottom: 1px solid var(--blue-bd); }
.stack-proof a:hover { border-bottom-color: var(--blue); }
.stack-off { display: none !important; }               /* repli filtré (sans carte radiale) */
/* infobulle de preuve au survol d'une pastille de la carte radiale */
.techmap-tip {
  position: absolute; z-index: 30; pointer-events: none;
  transform: translate(-50%, -100%);
  padding: 6px 10px; border-radius: var(--r);
  background: var(--text); color: var(--bg2);
  font-family: 'DM Mono', monospace; font-size: 10.5px; line-height: 1.5;
  max-width: 240px; text-align: center;
  opacity: 0; transition: opacity 0.15s ease;
}
.techmap-tip.on { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .techmap-tip { transition: none; } }
/* carte radiale : mise en valeur purement visuelle, l'état interne de techmap.js n'est pas touché */
.techmap-pole.search-dim { opacity: 0.22; }
.techmap-pill.in.search-dim { opacity: 0.18; }
.techmap-pill.in.search-hit {
  background: var(--blue-bg); border-color: var(--blue-bd); color: var(--blue); z-index: 10;
}
.techmap.is-enhanced .techmap-data { display: none; }         /* fallback masqué une fois enrichi */
.techmap-stage { position: relative; width: 100%; overflow: visible; }

.techmap-links { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.techmap-spoke { stroke: var(--border2); stroke-width: 1; opacity: 0; transition: opacity 0.3s ease; }
.techmap.cats-open .techmap-spoke { opacity: 1; }
.techmap-link-item {
  stroke: var(--border2); stroke-width: 1;
  opacity: 0; transition: opacity 0.3s ease;
}
.techmap-link-item.in { opacity: 1; }

.techmap-center {
  position: absolute; z-index: 3; cursor: pointer;
  width: 152px; height: 152px; border-radius: 50%;
  display: grid; place-items: center; text-align: center;
  background: var(--li); color: #FFFFFF; border: none;
  font-family: 'DM Mono', monospace; font-size: 16px; letter-spacing: 0.1em;
  text-transform: uppercase;
  transform: translate(-50%, -50%);
  animation: techBob 2.4s ease-in-out infinite;          /* respiration : incite au clic */
  transition: box-shadow 0.2s ease;
}
.techmap-center::after {                                  /* halo pulsé autour du nœud */
  content: ''; position: absolute; inset: -3px; border-radius: 50%;
  border: 2px solid var(--li); pointer-events: none;
  animation: techPulse 2s ease-out infinite;
}
/* Survol : le nœud se creuse d'un cran, respire plus vite, et le mot remonte pour
   laisser place au verbe qui annonce le prochain clic (déployer / replier). */
.techmap-center:hover,
.techmap-center:focus-visible {
  box-shadow: 0 0 0 12px var(--blue-bg);
  animation: techBobHover 1.1s ease-in-out infinite;
}
.techmap-center:hover::after,
.techmap-center:focus-visible::after { animation-duration: 1.2s; }

.techmap-center-w { transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1); }
.techmap-center-cta {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, 14px);
  font-size: 9.5px; letter-spacing: 0.16em; text-transform: uppercase;
  opacity: 0; pointer-events: none;
  transition: opacity 0.22s ease, transform 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
.techmap-center:hover .techmap-center-w,
.techmap-center:focus-visible .techmap-center-w { transform: translateY(-10px); }
.techmap-center:hover .techmap-center-cta,
.techmap-center:focus-visible .techmap-center-cta { opacity: 0.9; transform: translate(-50%, 6px); }
/* le nœud STACK garde sa respiration + son halo en continu, même carte déployée */

@keyframes techBobHover {
  0%, 100% { transform: translate(-50%, -50%) scale(1.06); }
  50%      { transform: translate(-50%, -50%) scale(1.12); }
}

@keyframes techBob {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50%      { transform: translate(-50%, -50%) scale(1.06); }
}
@keyframes techPulse {
  0%   { transform: scale(1);   opacity: 0.5; }
  70%  { opacity: 0; }
  100% { transform: scale(1.75); opacity: 0; }
}

.techmap-pole {
  position: absolute; z-index: 2;
  transform: translate(-50%, -50%) scale(0.6);
  opacity: 0; pointer-events: none;                 /* masqué tant que le centre n'est pas ouvert */
  cursor: pointer; white-space: nowrap;
  padding: 7px 13px; border-radius: 99px;
  border: 1px solid var(--border2); background: var(--bg2); color: var(--text);
  font-family: 'DM Mono', monospace; font-size: 11.5px;
  transition: opacity 0.3s ease, transform 0.3s ease, background 0.15s, border-color 0.15s, color 0.15s;
}
.techmap.cats-open .techmap-pole {
  opacity: 1; pointer-events: auto;
  transform: translate(-50%, -50%) scale(1);
}
/* Pas d'invite pulsée sur les pôles : le clic central déploie déjà tout,
   il n'y a plus rien à aller chercher catégorie par catégorie. */
.techmap-pole:hover { background: var(--bg3); }
.techmap-pole.active { background: var(--text); border-color: var(--text); color: var(--bg2); }
.techmap.has-open .techmap-pole.dim { opacity: 0.35; }        /* focus visuel : atténue les autres */

.techmap-branch { position: absolute; inset: 0; pointer-events: none; }
.techmap-pill {
  position: absolute; z-index: 1;
  transform: translate(-50%, -50%) scale(0.7); transform-origin: center;
  opacity: 0; pointer-events: none; white-space: nowrap;
  padding: 3px 9px; border-radius: 7px;
  border: 1px solid var(--border); background: var(--bg3); color: var(--text2);
  font-family: 'DM Mono', monospace; font-size: 10.5px;
  transition: opacity 0.3s ease, transform 0.3s ease,
              background 0.15s ease, box-shadow 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.techmap-pill.in {
  opacity: 1; transform: translate(-50%, -50%) scale(1); pointer-events: auto;
}
/* survol : la pill passe au premier plan pour être lisible malgré les chevauchements */
.techmap-pill.in:hover {
  z-index: 20; color: var(--text);
  background: var(--bg2); border-color: var(--text3);
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.14);
}

@media (prefers-reduced-motion: reduce) {
  .techmap-pill, .techmap-link-item { transition-duration: 0.001s; }
  .techmap-pill { transition-delay: 0s !important; }
  .techmap-center, .techmap-center::after, .techmap-pole { animation: none !important; }
  /* le verbe apparaît quand même au survol, mais sans glissement */
  .techmap-center-w, .techmap-center-cta { transition: none; }
}

@media (max-width: 780px) {
  .timeline::before { left: 21px; }
  .tl-marker { left: 21px; }
  .timeline .mission { width: auto; margin-left: 58px !important; }
  .timeline .mission::after { display: none; }
}

/* ABOUT */
.about-wrap { display: grid; grid-template-columns: 200px 1fr; gap: 3rem; align-items: start; }
.about-links--col .about-link { white-space: normal; word-break: break-all; align-items: flex-start; }
.about-ava-lg {
  width: 80px; height: 80px; border-radius: 50%;
  border: 1px solid var(--border2);
  object-fit: cover; display: block; margin-bottom: 0.75rem;
}
.about-handle-lg { font-family: 'DM Mono', monospace; font-size: 11px; color: var(--text3); margin-top: 4px; }
.lang-row { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 0.6rem; }
.about-right p { font-size: 14.5px; color: var(--text2); line-height: 1.8; margin-bottom: 1rem; font-weight: 300; }
.about-right p strong { color: var(--text); font-weight: 500; }
.about-timeline {
  position: relative;
  display: flex; flex-direction: column; gap: 8px; margin: 1.25rem 0;
  padding: 1rem 1.25rem; background: var(--bg3);
  border-radius: 0;                    /* angles vifs : un tracé, pas une carte */
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.3s ease, background 0.2s ease;
}
/* Cadre bleu tracé en deux moitiés : ::before dessine le haut puis la droite,
   ::after le bas puis la gauche — le trait fait le tour du bloc. */
.about-timeline::before,
.about-timeline::after {
  content: ""; position: absolute; pointer-events: none;
  width: 100%; height: 100%;           /* par défaut le cadre est entier, sans animation */
}
.about-timeline::before {
  top: 0; left: 0;
  border-top: 2px solid var(--blue); border-right: 2px solid var(--blue);
}
.about-timeline::after {
  bottom: 0; right: 0;
  border-bottom: 2px solid var(--blue); border-left: 2px solid var(--blue);
}
/* Le tracé n'a lieu que là où le scroll-reveal est actif. Sans JS, sans
   IntersectionObserver ou en mouvement réduit, le cadre est déjà complet :
   la bordure ne dépend jamais du script pour exister. */
html.reveal-on .about-timeline::before,
html.reveal-on .about-timeline::after { width: 0; height: 0; }
html.reveal-on .about-timeline.reveal-in::before {
  width: 100%; height: 100%;
  transition: width 0.5s ease-out, height 0.45s ease-out 0.5s;
}
html.reveal-on .about-timeline.reveal-in::after {
  width: 100%; height: 100%;
  transition: width 0.5s ease-out 0.95s, height 0.45s ease-out 1.45s;
}
.about-timeline:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 36px rgba(0, 0, 0, 0.10);
  background: var(--bg2);
}
.tl-head {
  display: flex; justify-content: flex-end;
  padding: 0 8px; margin: 0 -8px 2px;
  font-family: 'DM Mono', monospace; font-size: 10px; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--text3);
}
.tl-item {
  display: grid; grid-template-columns: 38px 1fr auto; column-gap: 1rem; align-items: baseline;
  padding: 3px 8px; margin: -3px -8px; border-radius: 0;
  transition: background 0.2s ease;
}
.tl-item:hover { background: var(--blue-bg); }
.tl-date { font-family: 'DM Mono', monospace; font-size: 11px; color: var(--blue); font-weight: 500; }
.tl-text { font-size: 13px; color: var(--text2); line-height: 1.5; transition: color 0.2s ease; }
.tl-exp {
  font-family: 'DM Mono', monospace; font-size: 11px;
  color: var(--text3); text-align: right; white-space: nowrap;
  transition: color 0.2s ease;
}
.tl-item:hover .tl-text, .tl-item:hover .tl-exp { color: var(--blue); }
.tl-total {
  display: grid; grid-template-columns: 38px 1fr auto; column-gap: 1rem; align-items: baseline;
  margin: 6px -8px -3px; padding: 9px 8px 0;
  border-top: 1px solid var(--border2);
}
.tl-total-label { grid-column: 2; font-size: 13px; font-weight: 500; color: var(--text); }
.tl-total-val {
  font-family: 'DM Mono', monospace; font-size: 11px; font-weight: 500;
  color: var(--blue); text-align: right; white-space: nowrap;
}
.tl-text a {
  color: inherit; text-decoration: none;
  border-bottom: 1px solid var(--blue-bd);
  transition: color 0.15s ease, border-color 0.15s ease;
}
.tl-text a:hover { color: var(--blue); border-bottom-color: var(--blue); }
@media (prefers-reduced-motion: reduce) {
  .about-timeline, .tl-item, .tl-text, .tl-exp { transition: none; }
  .about-timeline:hover { transform: none; box-shadow: none; }
}
/* écrans étroits : la durée repasse sous l'intitulé plutôt que de comprimer la colonne */
@media (max-width: 560px) {
  .tl-item, .tl-total { grid-template-columns: 38px 1fr; }
  .tl-exp, .tl-total-val { grid-column: 2; text-align: left; margin-top: 2px; }
  .tl-head { display: none; }
}

/* CONTACT */
.contact-layout {
  display: flex; align-items: center; gap: 3rem; flex-wrap: wrap;
}

/* ABOUT STRIP (bas de page) */
.about-strip {
  display: grid; grid-template-columns: auto 1fr auto;
  gap: 1.5rem; align-items: center;
  border: 1px solid var(--border); border-radius: var(--r3);
  background: var(--bg2); padding: 1.5rem 2rem;
}
.about-ava-sm {
  width: 52px; height: 52px; border-radius: 50%;
  border: 1px solid var(--border2);
  object-fit: cover; flex-shrink: 0;
}
.about-name { font-size: 14px; font-weight: 500; margin-bottom: 2px; }
.about-handle { font-family: 'DM Mono', monospace; font-size: 11px; color: var(--text3); margin-bottom: 0.4rem; }
.about-bio-sm { font-size: 13px; color: var(--text2); line-height: 1.6; font-weight: 300; max-width: 500px; }
.about-langs-sm { display: flex; gap: 5px; margin-top: 0.5rem; flex-wrap: wrap; }

@media (max-width: 640px) {
  .hero-layout { grid-template-columns: 1fr; }
  .profile-aside { display: none; }
  .svcs { grid-template-columns: 1fr; }
  .about-wrap { grid-template-columns: 1fr; }
  .about-strip { grid-template-columns: auto 1fr; }
  .about-links { display: none; }
}

/* rappel des liens dans la section contact : nettement détachés des boutons */
.contact-split .hero-contact { margin-top: 2.5rem; row-gap: 10px; }

/* Langues : drapeaux + infobulle de niveau au survol */
.lang-flags { display: inline-flex; gap: 8px; }
.lang-flag { position: relative; font-size: 15px; line-height: 1; cursor: default; }
.lang-flag::after {
  content: attr(data-tip);
  position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%);
  padding: 5px 9px; border-radius: var(--r);
  background: var(--text); color: var(--bg2);
  font-family: 'DM Mono', monospace; font-size: 10.5px; line-height: 1.4;
  white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity 0.15s ease;
}
.lang-flag:hover::after, .lang-flag:focus-visible::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .lang-flag::after { transition: none; } }
