/* ==========================================================================
   Ryan Flocard — portfolio en 5 vues
   Mobile d'abord (375 px), puis élargissements. Sections :
   01 Polices · 02 Jetons · 03 Base · 04 Accessibilité · 05 Barre et navigation
   06 Vues · 07 Accueil · 08 Projets · 09 Panneau · 10 IA & Agents
   11 Outils · 12 Contact · 13 Grands écrans · 14 Mouvement réduit
   ========================================================================== */

/* 01 · POLICES — auto-hébergées : aucun appel à un service tiers. */
@font-face {
  font-family: "Space Grotesk";
  src: url("../fonts/space-grotesk-variable.woff2") format("woff2");
  font-weight: 300 700;
  font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("../fonts/playfair-display-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("../fonts/playfair-display-400-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

/* 02 · JETONS — palette reprise du portfolio existant, contrastes AA mesurés :
   --muted 6,6:1 et --dim 5,1:1 sur --bg. */
:root {
  --bg: #09090b;
  --surface: #111116;
  --surface-2: #17171e;
  --line: rgba(255, 255, 255, 0.08);
  --line-2: rgba(255, 255, 255, 0.16);
  --text: #f4f2ee;
  --muted: #9a968f;
  --dim: #85817a;
  --accent: #cfb586;
  --accent-2: #e8d5b0;
  --accent-soft: rgba(207, 181, 134, 0.12);
  --accent-line: rgba(207, 181, 134, 0.38);

  --serif: "Playfair Display", Georgia, "Times New Roman", serif;
  --sans: "Space Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  --fs-xs: 0.75rem;
  --fs-sm: 0.875rem;
  --fs-base: 1rem;
  --fs-lg: clamp(1.125rem, 1rem + 0.5vw, 1.375rem);
  --fs-xl: clamp(1.75rem, 1.2rem + 2.6vw, 3rem);
  --fs-hero: clamp(1.9rem, 1rem + 4.4vw, 4.25rem);

  --r: 12px;
  --r-lg: 18px;
  --pad: 1.25rem;

  --bar-top: 56px;
  --bar-bottom: calc(64px + env(safe-area-inset-bottom, 0px));

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --t: 0.22s;
}

/* 03 · BASE */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; color-scheme: dark; }
body {
  min-height: 100svh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: var(--fs-base);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
/* height: auto : les attributs width/height des images servent à réserver
   la place (pas de décalage au chargement) sans figer leur hauteur. */
img, video { display: block; max-width: 100%; height: auto; }
svg { display: block; max-width: 100%; }
a { color: inherit; }
button, input, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; }
/* Le rectangle bleu natif au toucher fait doublon avec les retours :active
   déjà dessinés (léger rétrécissement, changement de bordure). */
a, button { -webkit-tap-highlight-color: transparent; }
ul, ol { list-style: none; }
h1, h2, h3 { font-weight: 400; line-height: 1.15; }
::selection { background: var(--accent); color: #000; }
svg { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* L'attribut hidden doit toujours gagner : sans cette règle, une vue en
   display: flex (l'accueil) restait affichée sous la vue active. */
[hidden] { display: none !important; }

/* 04 · ACCESSIBILITÉ */
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.skip {
  position: fixed; top: 0.5rem; left: 0.5rem; z-index: 100;
  padding: 0.75rem 1rem; border-radius: var(--r);
  background: var(--accent); color: #000; font-weight: 500;
  transform: translateY(-160%); transition: transform var(--t) var(--ease);
}
.skip:focus-visible { transform: none; }
:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 3px; border-radius: 6px; }
[tabindex="-1"]:focus { outline: none; }

/* 05 · BARRE ET NAVIGATION */
.topbar {
  position: fixed; inset: 0 0 auto; z-index: 40;
  height: var(--bar-top);
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0 var(--pad);
  border-bottom: 1px solid var(--line);
}
/* Le flou est porté par un pseudo-élément et non par la barre elle-même :
   un backdrop-filter sur .topbar en ferait le bloc conteneur de la nav
   (position: fixed), qui se collerait alors en haut au lieu du bas. */
.topbar::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: rgba(9, 9, 11, 0.82);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
.logo {
  font-family: var(--serif); font-size: 1.35rem; text-decoration: none;
  min-width: 44px; min-height: 44px; display: inline-flex; align-items: center;
}
.logo span { color: var(--accent); }
.topbar-id { font-size: var(--fs-sm); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-id span { color: var(--dim); }

/* Navigation fixée en bas sur mobile : cinq cibles de 64 px de haut. */
.views-nav {
  position: fixed; inset: auto 0 0; z-index: 40;
  height: var(--bar-bottom);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: rgba(13, 13, 17, 0.94);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  border-top: 1px solid var(--line);
}
.views-nav a {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  min-height: 44px;
  font-size: 0.6875rem; letter-spacing: 0.01em; text-decoration: none;
  color: var(--dim);
  transition: color var(--t) var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.views-nav svg { width: 22px; height: 22px; transition: transform var(--t) var(--ease); }
.views-nav a[aria-current="page"] { color: var(--accent); }
.views-nav a[aria-current="page"]::before {
  content: ""; position: absolute; top: 0; left: 30%; right: 30%; height: 2px;
  background: var(--accent); border-radius: 0 0 2px 2px;
}
.views-nav a:active svg { transform: scale(0.88); }

/* 06 · VUES */
main { padding: var(--bar-top) 0 var(--bar-bottom); outline: none; }
.view {
  position: relative;
  min-height: calc(100svh - var(--bar-top) - var(--bar-bottom));
  padding: 1.5rem var(--pad) 2rem;
  max-width: 1240px; margin: 0 auto;
}
/* Avec JS, la vue active est connue dès le premier rendu (data-route, posé
   par le script inline du <head>) : aucune autre vue n'est peinte, donc
   aucun décalage quand app.js s'exécute. */
.js[data-route] [data-view] { display: none; }
.js[data-route="accueil"] [data-view="accueil"] { display: flex; }
.js[data-route="projets"] [data-view="projets"],
.js[data-route="ia"] [data-view="ia"],
.js[data-route="outils"] [data-view="outils"],
.js[data-route="contact"] [data-view="contact"] { display: block; }

/* Sans JS, les vues se suivent ; avec JS, une seule est montrée (attribut hidden). */
.view + .view { border-top: 1px solid var(--line); }
.js .view + .view { border-top: 0; }
.view.is-entering { animation: entre 0.32s var(--ease) both; }
@keyframes entre { from { opacity: 0; transform: translateY(10px); } }

.view-head { margin-bottom: 1.25rem; }
.view-head h1 { font-family: var(--serif); font-size: var(--fs-xl); letter-spacing: -0.02em; }
.view-head p { color: var(--muted); margin-top: 0.4rem; max-width: 58ch; }

.eyebrow {
  font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--accent); font-weight: 500;
}

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 1.4rem; border-radius: 999px;
  font-weight: 500; text-decoration: none; white-space: nowrap;
  transition: transform var(--t) var(--ease), background-color var(--t) var(--ease), border-color var(--t) var(--ease);
}
.btn:active { transform: scale(0.97); }
.btn-primary { background: var(--accent); color: #0b0b0d; }
.btn-primary:hover { background: var(--accent-2); }
.btn-ghost { border: 1px solid var(--line-2); }
.btn-ghost:hover { border-color: var(--accent); }

/* Indicateur de tendance : même composant partout (accueil, cartes, panneau). */
.trend-icon {
  flex: none; width: 1.15em; height: 1.15em; border-radius: 50%;
  background: var(--accent-soft);
  position: relative;
}
.trend-icon::after {
  content: ""; position: absolute; inset: 0;
  background: var(--accent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17 17 7M9 7h8v8'/%3E%3C/svg%3E") center / 62% no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17 17 7M9 7h8v8'/%3E%3C/svg%3E") center / 62% no-repeat;
}
.trend {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-size: var(--fs-xs); color: var(--accent); font-weight: 500;
}
.trend--pending { color: var(--muted); }
.trend--pending .trend-icon { background: var(--line); }
.trend--pending .trend-icon::after {
  background: var(--muted);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='8'/%3E%3Cpath d='M12 8v4l3 2'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='8'/%3E%3Cpath d='M12 8v4l3 2'/%3E%3C/svg%3E");
}

.tags { display: flex; flex-wrap: wrap; gap: 0.35rem; }
/* > * : <li> dans le panneau, <span> dans les cartes (une liste n'est pas
   autorisée à l'intérieur d'un <button>). */
.tags > * {
  font-size: var(--fs-xs); color: var(--muted);
  padding: 0.2rem 0.55rem; border: 1px solid var(--line-2); border-radius: 6px;
}

/* 07 · ACCUEIL */
/* isolation : la vidéo en z-index -1 reste confinée à cette vue. */
.view-accueil { display: flex; align-items: center; max-width: none; overflow: hidden; isolation: isolate; }
.hero-media { position: absolute; inset: 0; z-index: -1; }
.hero-media video { width: 100%; height: 100%; object-fit: cover; opacity: 0.32; }
/* Voile de lisibilité : le texte ne passe jamais directement sur la vidéo. */
.hero-media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(9,9,11,0.55), var(--bg) 92%),
              linear-gradient(90deg, rgba(9,9,11,0.85), transparent 70%);
}
.hero { width: 100%; max-width: 1240px; margin: 0 auto; }
.hero h1 {
  font-family: var(--serif); font-size: var(--fs-hero);
  letter-spacing: -0.025em; margin: 0.6rem 0 1rem; max-width: 20ch;
}
.hero h1 em { font-style: italic; color: var(--accent); }
.hero-id { color: var(--muted); font-size: var(--fs-sm); max-width: 62ch; }
.hero-id strong { color: var(--text); font-weight: 500; }

.indicators { display: grid; gap: 0.5rem; margin: 1.5rem 0; }
.indicators li {
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.75rem 0.9rem; border-radius: var(--r);
  background: rgba(17, 17, 22, 0.72); border: 1px solid var(--line);
  font-size: var(--fs-sm); font-weight: 500;
}
.ctas { display: flex; flex-wrap: wrap; gap: 0.6rem; }

/* --- Invitation à explorer (accueil) ------------------------------------
   Tant que le visiteur n'a pas navigué (.a-navigue, posé par app.js au
   premier changement de vue), quatre signaux discrets indiquent ce qui se
   clique. En mouvement réduit, la section 14 fige tout : les indices
   restent visibles, sans animation. */
.go-arrow { display: inline-block; margin-left: 0.45rem; transition: transform var(--t) var(--ease); }
.btn-go:hover .go-arrow { transform: translateX(4px); }
.js[data-route="accueil"]:not(.a-navigue) .btn-go .go-arrow { animation: pousse 2.6s var(--ease) 1.2s infinite; }
@keyframes pousse {
  0%, 55%, 100% { transform: none; }
  20% { transform: translateX(6px); }
  35% { transform: none; }
  45% { transform: translateX(3px); }
}

.hint { margin-top: 1.3rem; font-size: var(--fs-sm); color: var(--muted); }
.hint-mobile, .hint-desktop { align-items: center; gap: 0.5rem; }
.hint-mobile { display: inline-flex; }
.hint-desktop { display: none; }
.hint-arrow { flex: none; width: 18px; height: 18px; color: var(--accent); }
.js:not(.a-navigue) .hint-down { animation: rebond 1.8s var(--ease) infinite; }
@keyframes rebond { 50% { transform: translateY(5px); } }

/* Vague sur les entrées du menu, relancée à intervalle régulier par app.js. */
.views-nav.is-calling a { animation: appel 0.7s var(--ease) both; }
.views-nav.is-calling a:nth-child(2) { animation-delay: 0.08s; }
.views-nav.is-calling a:nth-child(3) { animation-delay: 0.16s; }
.views-nav.is-calling a:nth-child(4) { animation-delay: 0.24s; }
.views-nav.is-calling a:nth-child(5) { animation-delay: 0.32s; }
@keyframes appel { 40% { transform: translateY(-4px); } }

/* Pastille fixe sur « Projets » : la destination principale. Volontairement
   sans clignotement : ce n'est pas un indicateur de donnée en direct, et la
   vague du menu porte déjà le mouvement. */
.js[data-route="accueil"]:not(.a-navigue) .views-nav a[data-route="projets"]::after {
  content: ""; position: absolute; top: 9px; right: calc(50% - 19px);
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
}

/* 08 · PROJETS */
.filters {
  display: flex; gap: 0.4rem; overflow-x: auto; scrollbar-width: none;
  margin: 0 calc(-1 * var(--pad)) 1rem; padding: 0 var(--pad) 0.2rem;
}
.filters::-webkit-scrollbar { display: none; }
.filter {
  flex: none; min-height: 44px; padding: 0 1rem; border-radius: 999px;
  border: 1px solid var(--line-2); color: var(--muted); font-size: var(--fs-sm);
  transition: color var(--t), border-color var(--t), background-color var(--t);
}
.filter:hover { color: var(--text); }
.filter[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: #0b0b0d; font-weight: 500; }

/* Mobile : liste compacte (vignette, titre, tendance). Les tags passent dans le panneau. */
.cards { display: grid; gap: 0.35rem; }
.card {
  width: 100%; text-align: left;
  display: grid; grid-template-columns: 52px 1fr; gap: 0.7rem; align-items: center;
  padding: 0.4rem 0.6rem 0.4rem 0.4rem; border-radius: var(--r);
  background: var(--surface); border: 1px solid var(--line);
  transition: border-color var(--t) var(--ease), transform var(--t) var(--ease), background-color var(--t);
}
.card:hover { border-color: var(--accent-line); }
.card:active { transform: scale(0.985); }
.card.is-new { animation: entre 0.3s var(--ease) both; }
.card-media {
  width: 52px; height: 52px; border-radius: 8px; overflow: hidden;
  background: var(--surface-2);
}
.card-media img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.card-body { display: grid; gap: 0.15rem; min-width: 0; }
.card-title {
  font-size: 0.9375rem; font-weight: 500; line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.card-resume, .card .tags { display: none; }

/* Mobile : la tendance se réduit à son icône, à droite de la carte. Son
   texte reste lu par les lecteurs d'écran et s'affiche en entier dans le
   panneau. Les cartes gagnent une ligne, et la liste tient en 1,5 écran
   malgré 14 projets. */
@media (max-width: 699px) {
  .card { position: relative; padding-right: 2.4rem; }
  .card-body .trend { position: absolute; right: 0.75rem; top: 50%; transform: translateY(-50%); }
  .card-body .trend-txt {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
}

/* Visuel de remplacement typographique (pas de capture disponible). */
.mono {
  width: 100%; height: 100%; display: grid; place-items: center;
  font-family: var(--serif); font-style: italic; color: var(--accent);
  font-size: 1.35rem;
  background:
    radial-gradient(120% 120% at 80% 0%, rgba(207,181,134,0.18), transparent 60%),
    linear-gradient(150deg, var(--surface-2), var(--bg));
}

.empty { color: var(--muted); padding: 1rem 0; }
.noscript { color: var(--muted); max-width: 70ch; }

/* 09 · PANNEAU DE DÉTAIL */
.panel {
  /* Mobile : feuille qui monte du bas. */
  margin: auto 0 0; width: 100%; max-width: 100%;
  max-height: 92svh; border: 0; border-radius: var(--r-lg) var(--r-lg) 0 0;
  background: var(--surface); color: var(--text);
  overscroll-behavior: contain;
}
.panel::backdrop { background: rgba(0, 0, 0, 0.66); }
.panel[open] { animation: monte 0.32s var(--ease); }
@keyframes monte { from { transform: translateY(24px); opacity: 0; } }
/* minmax(0, 1fr) : sans cela, la colonne prend la largeur intrinsèque des
   captures (1280 px) et le visuel déborde de l'écran. */
.panel-inner { padding: 1rem var(--pad) calc(1.5rem + env(safe-area-inset-bottom, 0px)); display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.9rem; }
.panel-close {
  position: sticky; top: 0; justify-self: end; z-index: 2;
  width: 44px; height: 44px; display: grid; place-items: center; border-radius: 50%;
  background: var(--surface-2); border: 1px solid var(--line-2);
}
.panel-close svg { width: 20px; height: 20px; }
.panel-media { margin-top: -2.8rem; }
/* Pas de text-transform ici : le nom du client s'affiche tel qu'il s'écrit
   (« Technidata » ne doit jamais apparaître en capitales). */
.panel-client { font-size: var(--fs-sm); letter-spacing: 0.02em; color: var(--accent); font-weight: 500; }
.panel h2 { font-family: var(--serif); font-size: clamp(1.4rem, 1.1rem + 1.6vw, 2rem); letter-spacing: -0.015em; }
.panel-clear { font-size: var(--fs-lg); line-height: 1.4; }
.panel-steps { display: grid; gap: 0.85rem; }
.panel-steps > div { padding-left: 0.9rem; border-left: 1px solid var(--line-2); }
.panel-steps > div:last-child { border-left-color: var(--accent); }
.panel-steps dt { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.14em; color: var(--dim); margin-bottom: 0.2rem; }
.panel-steps dd { color: var(--muted); }
.panel-steps > div:last-child dd { color: var(--text); display: flex; gap: 0.5rem; align-items: center; }
.panel-note { font-size: var(--fs-sm); color: var(--dim); font-style: italic; }
.panel-links { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.panel-links a { min-height: 44px; }

/* Cadres « navigateur » et « téléphone » autour des captures. */
.frames { position: relative; padding-bottom: 8%; }
.frame-browser {
  border-radius: 10px; overflow: hidden; border: 1px solid var(--line-2); background: #fff;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
}
.frame-browser::before {
  content: ""; display: block; height: 22px; background: #1c1c22;
  background-image: radial-gradient(circle, #4a4a52 3.5px, transparent 4px),
                    radial-gradient(circle, #4a4a52 3.5px, transparent 4px),
                    radial-gradient(circle, #4a4a52 3.5px, transparent 4px);
  background-size: 14px 22px; background-repeat: no-repeat;
  background-position: 10px 0, 24px 0, 38px 0;
}
.frame-browser img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; object-position: top; }
.frame-phone {
  position: absolute; right: 4%; bottom: 0; width: 24%;
  border-radius: 18px; overflow: hidden; border: 4px solid #1c1c22; background: #000;
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.6);
}
.frame-phone img { width: 100%; aspect-ratio: 390 / 844; object-fit: cover; object-position: top; }
.media-img { border-radius: 10px; overflow: hidden; border: 1px solid var(--line); }
.media-img img { width: 100%; height: auto; }
.media-mono { aspect-ratio: 16 / 9; border-radius: 10px; overflow: hidden; }
.media-mono .mono { font-size: 3.5rem; }

/* Vidéos : lecture au clic, muettes par défaut, rien de chargé avant. */
.panel-videos { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.6rem; }
.panel-videos figure { display: grid; gap: 0.35rem; }
.panel-videos .v-wide { grid-column: 1 / -1; }
.panel-videos video { width: 100%; border-radius: 8px; background: #000; }
.panel-videos figcaption { font-size: var(--fs-xs); color: var(--dim); }

/* 10 · IA & AGENTS */
.ia-tabs { display: flex; gap: 0.4rem; margin-bottom: 1rem; }
.ia-tab {
  flex: 1; min-height: 44px; padding: 0 0.75rem; border-radius: 999px;
  border: 1px solid var(--line-2); color: var(--muted); font-size: var(--fs-sm);
  transition: color var(--t), background-color var(--t), border-color var(--t);
}
.ia-tab[aria-selected="true"] { background: var(--accent); border-color: var(--accent); color: #0b0b0d; font-weight: 500; }

.ia-panel { display: grid; gap: 1rem; outline: none; }

/* Le flux : quatre étapes reliées, une impulsion parcourt la chaîne. */
.flow {
  position: relative; display: grid; gap: 0.45rem;
  padding: 0.9rem; border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background:
    linear-gradient(var(--line) 1px, transparent 1px) 0 0 / 22px 22px,
    linear-gradient(90deg, var(--line) 1px, transparent 1px) 0 0 / 22px 22px,
    var(--surface);
}
.node {
  position: relative; display: grid; grid-template-columns: 5.6rem 1fr; align-items: center; gap: 0.6rem;
  padding: 0.55rem 0.75rem; border-radius: 10px;
  background: var(--bg); border: 1px solid var(--line-2);
}
.node-k { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.12em; color: var(--dim); }
.node-v { font-size: var(--fs-sm); font-weight: 500; transition: opacity 0.18s var(--ease); }
/* Teinte dorée posée sur un fond opaque : en semi-transparence, la grille
   du schéma transparaissait sous l'étiquette (contraste à 3,8:1). */
.node-agent {
  border-color: var(--accent-line);
  background: linear-gradient(rgba(207, 181, 134, 0.07), rgba(207, 181, 134, 0.07)), var(--bg);
}
.node-agent .node-v { color: var(--accent); }
.node-out { border-color: var(--accent-line); }
/* Connecteur vertical entre deux étapes, avec son impulsion. */
.node + .node::before {
  content: ""; position: absolute; left: 1.4rem; top: -0.5rem; width: 1px; height: 0.5rem;
  background: var(--accent-line);
}
.node::after {
  content: ""; position: absolute; left: calc(1.4rem - 3px); top: -0.6rem;
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
  opacity: 0;
}
.node:first-child::after { display: none; }
.flow.is-running .node::after { animation: impulsion 2.4s var(--ease) infinite; }
.flow.is-running .node:nth-child(3)::after { animation-delay: 0.4s; }
.flow.is-running .node:nth-child(4)::after { animation-delay: 0.8s; }
@keyframes impulsion {
  0% { opacity: 0; transform: translateY(-4px); }
  15% { opacity: 1; }
  35% { opacity: 0; transform: translateY(6px); }
  100% { opacity: 0; }
}
.flow.is-switching .node-v { opacity: 0; }

.ia-bloc { display: grid; gap: 0.75rem; }
.ia-bloc dt { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.12em; color: var(--dim); }
.ia-bloc dd { color: var(--muted); font-size: var(--fs-sm); }
.ia-bloc .trend-line { color: var(--text); display: flex; gap: 0.5rem; align-items: center; }
.guard {
  margin-top: 1.1rem; padding: 0.85rem 1rem; border-radius: var(--r);
  border: 1px solid var(--accent-line); background: var(--accent-soft);
  font-size: var(--fs-sm);
}

/* 11 · OUTILS */
.tools { display: grid; gap: 0; }
.tools h2 { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.14em; color: var(--dim); font-family: var(--sans); }
.pills { display: flex; flex-wrap: wrap; gap: 0.4rem; }

/* Catégories en volets sur mobile : titre, aperçu des outils, chevron. */
.tools-cat { border-bottom: 1px solid var(--line); }
.tools-cat summary {
  list-style: none; cursor: pointer;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 0.75rem;
  min-height: 48px; padding: 0.55rem 0;
}
.tools-cat summary::-webkit-details-marker { display: none; }
.tools-cat summary::after {
  content: ""; grid-column: 2; grid-row: 1 / span 2;
  width: 8px; height: 8px; margin-right: 4px;
  border-right: 1.6px solid var(--muted); border-bottom: 1.6px solid var(--muted);
  transform: rotate(45deg); transition: transform var(--t) var(--ease);
}
.tools-cat[open] summary::after { transform: rotate(-135deg); }
.tools-apercu {
  grid-column: 1; font-size: var(--fs-xs); color: var(--dim); margin-top: 0.15rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tools-cat[open] .tools-apercu { display: none; }
.tools-cat .pills { padding-bottom: 0.9rem; }
.pill {
  min-height: 44px; padding: 0 0.95rem; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--surface); font-size: var(--fs-sm);
  transition: border-color var(--t), background-color var(--t), transform var(--t) var(--ease);
}
.pill:hover { border-color: var(--accent-line); }
.pill:active { transform: scale(0.96); }
.pill[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-2); }
.tool-usage {
  margin-top: 0.6rem; padding: 0.7rem 0.9rem; border-radius: var(--r);
  background: var(--surface-2); border: 1px solid var(--accent-line);
  font-size: var(--fs-sm); animation: entre 0.24s var(--ease) both;
}
.tool-usage strong { color: var(--accent); font-weight: 500; }
.tracked { margin-top: 1.25rem; font-size: var(--fs-sm); color: var(--muted); }
.tracked strong { color: var(--text); font-weight: 500; }

/* 12 · CONTACT */
.dispo { display: flex; gap: 0.6rem; align-items: baseline; }
.dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); transform: translateY(-1px); }
.contact-grid { display: grid; gap: 1.5rem; }
.form { display: grid; gap: 0.75rem; }
.field { display: grid; gap: 0.3rem; }
.field label { font-size: var(--fs-sm); color: var(--muted); }
.field input, .field textarea {
  width: 100%; min-height: 48px; padding: 0.7rem 0.85rem; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--line-2);
  transition: border-color var(--t);
}
.field textarea { resize: vertical; min-height: 104px; }
.field input:focus-visible, .field textarea:focus-visible { border-color: var(--accent); outline-offset: 1px; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form .btn { justify-self: start; }
.form-status { font-size: var(--fs-sm); min-height: 1.4em; }
.form-status.is-ok { color: var(--accent); }
.form-status.is-err { color: #f0a8a8; }
.links { display: grid; gap: 0.25rem; align-content: start; }
.links a {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  min-height: 48px; padding: 0 0.2rem; border-bottom: 1px solid var(--line);
  text-decoration: none; transition: color var(--t);
}
.links a::after { content: "↗"; color: var(--dim); transition: transform var(--t) var(--ease), color var(--t); }
.links a:hover { color: var(--accent); }
.links a:hover::after { color: var(--accent); transform: translate(2px, -2px); }
.links .meta { margin-left: auto; font-size: var(--fs-xs); color: var(--dim); }
.credits { margin-top: 2rem; font-size: var(--fs-xs); color: var(--dim); }

/* 13 · GRANDS ÉCRANS */
@media (min-width: 700px) {
  :root { --pad: 2rem; }
  .indicators { grid-template-columns: repeat(3, 1fr); }
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; }
  /* Cartes complètes : visuel, titre, phrase, trois tags, tendance.
     Format horizontal (visuel carré à gauche) : un visuel pleine largeur en
     haut faisait passer la vue Projets à près de 2,5 écrans. */
  .card { grid-template-columns: 112px minmax(0, 1fr); align-items: start; padding: 0.6rem; gap: 0.9rem; }
  .card-media { width: 112px; height: 112px; }
  .card-media .mono { font-size: 1.9rem; }
  /* Cartes de même hauteur sur une rangée, tendance alignée en bas. */
  .cards > li { display: flex; }
  .card { height: 100%; }
  .card-body { padding: 0.15rem 0.2rem 0.2rem 0; gap: 0.4rem; display: flex; flex-direction: column; height: 100%; }
  .card-body .trend { margin-top: auto; padding-top: 0.15rem; }
  .card-resume {
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
    font-size: var(--fs-sm); color: var(--muted);
  }
  .card .tags { display: flex; }
  .card:hover { transform: translateY(-3px); }
  .card:hover .card-media img { transform: scale(1.03); }
  .card-media img { transition: transform 0.5s var(--ease); }
  .contact-grid { grid-template-columns: 1.3fr 1fr; gap: 3rem; }
  .ia-bloc { grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
  .tools { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem 2rem; }
  /* Grand écran : tout est déplié, le résumé redevient un simple titre. */
  .tools-cat { border-bottom: 0; }
  .tools-cat summary { cursor: default; min-height: 0; padding: 0 0 0.5rem; display: block; }
  .tools-cat summary::after, .tools-apercu { display: none; }
  .tools-cat .pills { padding-bottom: 0; }
}

@media (min-width: 900px) {
  :root { --bar-top: 72px; --bar-bottom: 0px; }
  .topbar { gap: 1.25rem; }
  .topbar-id { margin-right: auto; }
  /* La navigation remonte dans la barre du haut. */
  .views-nav {
    position: static; height: auto; padding: 0; background: none; border: 0;
    -webkit-backdrop-filter: none; backdrop-filter: none;
    display: flex; gap: 0.25rem;
  }
  .views-nav a { flex-direction: row; gap: 0.45rem; padding: 0 0.85rem; font-size: var(--fs-sm); color: var(--muted); border-radius: 999px; min-height: 44px; }
  .views-nav a:hover { color: var(--text); }
  .views-nav svg { width: 17px; height: 17px; }
  .views-nav a[aria-current="page"] { color: var(--accent); background: var(--accent-soft); }
  .views-nav a[aria-current="page"]::before { display: none; }
  /* Invitation : la flèche pointe vers le menu, désormais en haut. */
  .hint-mobile { display: none; }
  .hint-desktop { display: inline-flex; }
  .js:not(.a-navigue) .hint-up { animation: vers-le-haut 1.8s var(--ease) infinite; }
  @keyframes vers-le-haut { 50% { transform: translateY(-5px); } }
  .js[data-route="accueil"]:not(.a-navigue) .views-nav a[data-route="projets"]::after { top: 7px; right: 7px; }
  .view { padding: 3rem var(--pad) 3rem; }

  /* Démo IA horizontale : Contexte → Agent → Outils → Livrable. */
  .flow { grid-template-columns: repeat(4, 1fr); gap: 1.4rem; padding: 1.4rem; }
  .node { grid-template-columns: 1fr; align-content: start; gap: 0.35rem; padding: 0.9rem; min-height: 6.5rem; }
  .node + .node::before { left: -1.4rem; top: 50%; width: 1.4rem; height: 1px; }
  .node::after { left: -1.15rem; top: calc(50% - 3px); }
  @keyframes impulsion {
    0% { opacity: 0; transform: translateX(-4px); }
    15% { opacity: 1; }
    35% { opacity: 0; transform: translateX(14px); }
    100% { opacity: 0; }
  }

  /* Panneau : tiroir latéral plutôt que feuille. */
  .panel {
    margin: 0 0 0 auto; height: 100svh; max-height: 100svh; width: min(620px, 92vw);
    border-radius: var(--r-lg) 0 0 var(--r-lg);
  }
  .panel[open] { animation: glisse 0.34s var(--ease); }
  @keyframes glisse { from { transform: translateX(32px); opacity: 0; } }
  .panel-inner { padding: 1.25rem 2rem 2.5rem; }
}

@media (min-width: 1100px) {
  .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Le hero ne se cale à gauche du voile que lorsqu'il y a la place. */
@media (min-width: 900px) and (min-height: 700px) {
  .indicators { margin: 2rem 0; }
}

/* 15 · ÉTUDES DE CAS (projets/*.html) — pages statiques, sans JavaScript. */
.case { max-width: 880px; margin: 0 auto; padding: 1.5rem var(--pad) 3rem; display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.5rem; }
.case-back {
  justify-self: start; min-height: 44px; display: inline-flex; align-items: center;
  color: var(--muted); text-decoration: none; font-size: var(--fs-sm);
}
.case-back:hover { color: var(--accent); }
.case h1 { font-family: var(--serif); font-size: var(--fs-xl); letter-spacing: -0.02em; margin-top: -0.75rem; }
.case h1 em { display: block; font-style: italic; color: var(--accent); font-size: 0.62em; margin-top: 0.4rem; }
.case-facts { display: grid; gap: 0.6rem; }
.case-facts dt { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.14em; color: var(--dim); }
.case-facts dd { font-size: var(--fs-sm); }
.case-visual { margin: 0; }
.case-block h2 { font-family: var(--serif); font-size: var(--fs-lg); margin-bottom: 0.6rem; }
.case-block p { color: var(--muted); max-width: 66ch; }
.case-block p + p { margin-top: 0.6rem; }
.case-lead { color: var(--text) !important; font-size: var(--fs-lg); line-height: 1.45; }
.case-steps { display: grid; gap: 0.6rem; counter-reset: etape; }
.case-steps li {
  counter-increment: etape; position: relative;
  padding: 0.9rem 1rem 0.9rem 3rem; border-radius: var(--r);
  background: var(--surface); border: 1px solid var(--line);
}
.case-steps li::before {
  content: counter(etape, decimal-leading-zero); position: absolute; left: 1rem; top: 0.95rem;
  font-family: var(--serif); color: var(--accent); font-size: var(--fs-sm);
}
.case-steps h3 { font-size: var(--fs-base); font-weight: 500; font-family: var(--sans); }
.case-steps p { font-size: var(--fs-sm); margin-top: 0.2rem; }
.case-results { display: grid; gap: 0.5rem; }
.case-results li { display: flex; gap: 0.7rem; align-items: center; font-size: var(--fs-sm); color: var(--muted); }
.case-results strong { color: var(--text); font-weight: 500; }
.res-dot { flex: none; width: 1.15em; height: 1.15em; border-radius: 50%; border: 1px solid var(--line-2); }
.case-note { font-size: var(--fs-sm); color: var(--dim); font-style: italic; }
.case-links { display: flex; flex-wrap: wrap; gap: 0.6rem; }
@media (min-width: 700px) {
  .case-facts { grid-template-columns: repeat(3, 1fr); }
  .case-steps { grid-template-columns: repeat(2, 1fr); }
}

/* 14 · MOUVEMENT RÉDUIT : plus aucune animation ni transition. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .flow .node::after { display: none; }
}
