/* ============================================================
   PAGES.CSS — monde 3D + pages de contenu (thème « glass »)
   Chargé après glass.css (qui définit les jetons, le verre et les composants de base).
   Sections : 1 Monde 3D et navigation douce · 2 Pages de contenu
   ============================================================ */

/* 1. MONDE 3D : fenêtre du drone derrière chaque « hero », transitions de pages
   ============================================================ */
/* Le monde est au moins aussi haut que l'écran ; la scène est composée pour la hauteur du hero (--hero-h, posée par app.js) et le reste du
   canvas est masqué au repos : c'est la « barre » de fond de page qu'on voit sous le hero. Pendant un changement de page, app.js pose
   .ext (le masque s'estompe : le fond s'efface en fondu et le monde apparaît en plein écran) puis .back (le fond revient en fondu). */
@property --ext { syntax: '<number>'; inherits: false; initial-value: 0; }
.world { position: absolute; top: 0; left: 0; width: 100%; height: 100svh; height: max(100svh, var(--hero-h, 100svh)); z-index: 0; overflow: hidden; opacity: 0;
  clip-path: inset(0 0 calc(100% - var(--hero-h, 100%)) 0); transition: opacity var(--t-slow) var(--ease); }
.world.ext { --ext: 1; clip-path: none;
  -webkit-mask: linear-gradient(#000, #000) top / 100% var(--hero-h, 100%) no-repeat, linear-gradient(rgb(0 0 0 / var(--ext)), rgb(0 0 0 / var(--ext))) 0 0 / 100% 100% no-repeat;
  mask: linear-gradient(#000, #000) top / 100% var(--hero-h, 100%) no-repeat, linear-gradient(rgb(0 0 0 / var(--ext)), rgb(0 0 0 / var(--ext))) 0 0 / 100% 100% no-repeat;
  transition: opacity var(--t-slow) var(--ease), --ext .62s cubic-bezier(.4, 0, .3, 1) .06s; }
.world.ext.back { --ext: 0; transition: opacity var(--t-slow) var(--ease), --ext .55s var(--ease); }
.world canvas { display: block; width: 100%; height: 100%; touch-action: pan-y; }
.world-on .world { opacity: 1; }
.world-on .hero-stage { display: none; }

/* Le hero laisse passer les clics vers le canvas (dalles cliquables), sauf sur ses liens et boutons */
.hero--world { position: relative; z-index: 1; pointer-events: none; }
.hero--world a, .hero--world button { pointer-events: auto; }
:root { --bar: clamp(3.4rem, 8.5svh, 5.2rem); }                  /* hauteur de la bande de fond de page qui dépasse sous le hero de l'accueil */
.hero--world:not(.hero--page) { min-height: calc(100svh - var(--bar)); }   /* l'accueil laisse voir cette bande, comme les autres pages : on devine qu'on peut défiler */
.hero--page { min-height: min(74svh, 42rem); padding-top: 7rem; }

/* Indice de défilement de l'accueil : un mot et un trait fin dans la bande sous le hero, rien d'autre (ni flèche qui rebondit, ni halo) */
.statement { position: relative; }
.scroll-cue { position: absolute; z-index: 2; top: 0; left: var(--gutter); height: var(--bar); display: inline-flex; align-items: center; gap: .9rem;
  font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-2); transition: color .25s ease; }
.scroll-cue::after { content: ""; width: 1px; height: 1.8rem; background: linear-gradient(currentColor, currentColor) 0 0 / 100% 40% no-repeat, var(--line); }
.scroll-cue:hover, .scroll-cue:focus-visible { color: var(--ink); }
.scenes .scroll-cue::after { animation: cue-slide 2.6s cubic-bezier(.65, 0, .35, 1) infinite; }
@keyframes cue-slide { from { background-position: 0 -40%; } to { background-position: 0 140%; } }
.hero--page.hero--tall { min-height: min(84svh, 54rem); }       /* projets : plus de place pour que le mur de dalles reste lisible */
.hero--page.hero--tall h1 { font-size: clamp(2.8rem, 1rem + 6.4vw, 5.8rem); }   /* titre un peu plus petit : le mur de dalles gagne la place libérée à droite */
.hero--page h1 { font-size: clamp(2.8rem, 1rem + 8vw, 7rem); }
.hero--project h1 { font-size: clamp(2.4rem, 1rem + 6.2vw, 5.6rem); line-height: .95; }
.hero--world .lead { max-width: 30rem; }          /* texte à gauche, monde 3D à droite : mesure courte */
.crumbs { font-size: .95rem; color: var(--ink-2); margin-bottom: 1rem; }   /* vrai fil d'Ariane : phrase normale, pas une étiquette en capitales espacées */
.crumbs a:hover { color: var(--red-ink); }

.hub-links { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 2rem; }
.hero--world .hub-links { max-width: 30rem; }
.hub-link { padding: .75rem 1.2rem; border-radius: 99px; font-weight: 500; font-size: .98rem; }
.hub-link:hover, .hub-link:focus-visible { background: var(--ink); color: #fff; border-color: var(--ink); }
/* À l'accueil, les cinq destinations sont déjà les dalles du monde et la barre de navigation : les pastilles ne servent que sans 3D */
.world-on #contenu[data-scene="home"] .hub-links { display: none; }

/* Transition de contenu lors d'une navigation douce (le monde 3D, lui, reste en place) */
/* Changement de page en trois temps (router.js) : 1. l'ancien contenu s'efface doucement pendant que la page remonte ;
   2. le nouveau contenu attend, invisible et figé, pendant que le drone s'envole ; 3. le texte apparaît quand le drone approche. */
#contenu.is-leaving { opacity: 0; transform: translateY(-16px); transition: opacity .72s cubic-bezier(.4, 0, .3, 1), transform .72s var(--ease); pointer-events: none; }
#contenu.is-held { opacity: 0; pointer-events: none; }
#contenu.is-held * { animation-play-state: paused !important; }
#contenu.is-entering { animation: page-enter .6s ease both; }
@keyframes page-enter { from { opacity: 0; } }

@media (max-width: 760px) {
  /* texte lisible par-dessus la 3D sur petit écran */
  .world-on .hero--world .hero-copy::before { content: ""; position: absolute; inset: -5rem -2rem -6.2rem; z-index: -1; pointer-events: none;
    background: linear-gradient(to top, rgba(241,239,244,.94) 38%, rgba(241,239,244,0)); }
}

/* 2. PAGES DE CONTENU : projets, étude de cas, compétences, drones, à propos
   ============================================================ */
.badge { padding: .25rem .7rem; border-radius: 99px; border: 1px solid var(--line); font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2); }
.regard-copy .regard-actions { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 1.6rem; }
.regard-copy .regard-actions .btn { margin-top: 0; }

/* lignes « libellé / texte » réutilisables */
.rows { border-top: 1px solid var(--line); margin-top: 2rem; }
.rows .row, .deliver .row { display: grid; grid-template-columns: 1fr 1.3fr; gap: 1.5rem; align-items: baseline; padding: 1.8rem 0; border-bottom: 1px solid var(--line); }
/* Titre en grille : le numéro (ou l'étiquette) occupe la première colonne, le titre la seconde. Un titre long passe à la ligne
   dans sa colonne (jamais sous le numéro), le sous-titre s'aligne sous le titre, et la première ligne du titre partage sa
   ligne de base avec la première ligne du texte à droite. `.rows--tags` : étiquettes en mots (« En cours »…), colonne plus large. */
.rows dt, .deliver dt { display: grid; grid-template-columns: var(--lw, 3.4rem) minmax(0, 1fr); gap: 0; align-items: baseline; line-height: 1.05; font-size: clamp(1.5rem, 1rem + 1.6vw, 2.6rem); font-weight: 600; letter-spacing: -.035em; text-wrap: balance; }
.rows dt .label, .deliver dt .label { min-width: 0; white-space: nowrap; }
.rows dt small, .deliver dt small { grid-column: 2; display: block; margin-top: .55rem; font-family: var(--mono); font-size: var(--fs-label); font-weight: 400; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2); }
.rows--tags { --lw: 8.6rem; }
.rows dd { color: var(--ink-2); max-width: 34rem; }
.rows dd a, .deliver dd a { color: var(--red-ink); border-bottom: 1px solid currentColor; }
.wrap > .lead { margin-top: 1rem; }
.wrap > p { max-width: 38rem; }                  /* paragraphes de section : une mesure lisible (≈ 70 caractères) même sur grand écran */

/* étude de cas */
.cs-grid { display: grid; grid-template-columns: 1.15fr 1fr; gap: clamp(2rem, 5vw, 5rem); align-items: start; }
.cs-visual { border-radius: var(--radius-lg); overflow: hidden; background: var(--bg-deep); aspect-ratio: 16 / 10; box-shadow: 0 30px 80px rgba(40,40,70,.14); }
.cs-img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* la photo du projet est un lien vers le projet lui-même ; le badge est toujours visible (aucun effet au survol qui bouge ou masque) */
.cs-open { position: relative; display: block; width: 100%; height: 100%; }
.cs-open:focus-visible { outline-offset: -6px; border-radius: inherit; }
.cs-open-badge { position: absolute; right: 1rem; bottom: 1rem; max-width: calc(100% - 2rem); padding: .7rem 1.15rem; border-radius: 999px;
  font-weight: 600; font-size: .95rem; line-height: 1.1; color: var(--ink); background: rgba(255,255,255,.86);
  -webkit-backdrop-filter: blur(14px) saturate(1.4); backdrop-filter: blur(14px) saturate(1.4);
  box-shadow: 0 10px 28px rgba(30,30,60,.25), inset 0 0 0 1px rgba(255,255,255,.7); transition: background .2s ease; }
.cs-open:hover .cs-open-badge, .cs-open:focus-visible .cs-open-badge { background: #fff; }
.cs-video-file { width: 100%; height: 100%; display: block; background: #000; object-fit: contain; }
.cs-video .cs-visual { max-width: 56rem; margin-top: 1.6rem; }
.cs-art { width: 100%; height: 100%; min-height: 14rem; display: grid; place-items: end start; padding: 1.4rem; color: rgba(255,255,255,.92);
  background: radial-gradient(80% 90% at 75% 20%, var(--c2), transparent 70%), linear-gradient(140deg, var(--c1), #121214); }
/* repli sans capture ni vidéo (travaux sans page publique) : verre pastel aux couleurs du projet, titre et contexte en toutes lettres */
.cs-art--soft { display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-start; gap: .7rem; color: var(--ink);
  background: linear-gradient(140deg, #f3e9f4, #e7e5f0); }
@supports (background: color-mix(in srgb, red 50%, white)) {
  .cs-art--soft { background: radial-gradient(80% 90% at 80% 15%, color-mix(in srgb, var(--c2) 46%, #fff), transparent 70%),
                              linear-gradient(140deg, color-mix(in srgb, var(--c2) 18%, #fff), color-mix(in srgb, var(--c1) 8%, #efede8)); }
}
.cs-art-kind { font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-2); }
.cs-art-title { font-size: clamp(1.8rem, 1rem + 2.4vw, 3rem); font-weight: 600; letter-spacing: -.04em; line-height: 1; max-width: 16ch; text-wrap: balance; }
.cs-desc { font-size: var(--fs-lead); margin-top: 1rem; }
.cs-note { margin-top: 1.2rem; color: var(--ink-2); font-size: .95rem; }
.facts { border-top: 1px solid var(--line); margin-top: 2rem; }
.fact { display: grid; grid-template-columns: 14rem 1fr; gap: 1.5rem; padding: 1.1rem 0; border-bottom: 1px solid var(--line); }
.fact dt, .spec dt { font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-2); padding-top: .25rem; }
.fact a { color: var(--red-ink); border-bottom: 1px solid currentColor; }
.cs-ai-text { font-size: var(--fs-lead); max-width: 50rem; margin-top: .8rem; }
.cs-ai-text a { color: var(--red-ink); border-bottom: 1px solid currentColor; white-space: nowrap; }
.pn-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.pn { display: grid; gap: .4rem; padding: 1.4rem 1.6rem; border-radius: var(--radius-md); }
.pn b { font-size: clamp(1.3rem, 1rem + 1.4vw, 2rem); letter-spacing: -.03em; line-height: 1.1; }
.pn:last-child { text-align: right; }

/* vidéo YouTube (façade : rien n'est chargé avant le clic) */
.yt-facade { position: relative; width: 100%; height: 100%; background: #000; cursor: pointer; overflow: hidden; }
.yt-facade img { width: 100%; height: 100%; object-fit: cover; transform: scale(1.12); }   /* la miniature 4:3 de YouTube a des bandes noires : on les rogne */
.yt-facade iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.yt-play { position: absolute; inset: 0; display: grid; place-items: center; background: rgba(0,0,0,.22); }
.yt-play-icon { width: 4.5rem; height: 4.5rem; border-radius: 50%; background: rgba(255,255,255,.92); position: relative; }
.yt-play-icon::after { content: ""; position: absolute; left: 54%; top: 50%; transform: translate(-50%, -50%); border-style: solid; border-width: .8rem 0 .8rem 1.3rem; border-color: transparent transparent transparent #1d1d1f; }

/* compétences */
.skills { margin-top: 2.5rem; border-top: 1px solid var(--line); }
.skill { display: grid; grid-template-columns: 1fr 1.5fr; gap: 2rem; padding: 2.2rem 0; border-bottom: 1px solid var(--line); }
.skill-head { display: flex; flex-direction: column; align-items: flex-start; gap: .6rem; }
.skill-head h3 { font-size: clamp(1.8rem, 1rem + 2.6vw, 3.4rem); letter-spacing: -.04em; }
.skill-body p { color: var(--ink-2); max-width: 40rem; }
.points { list-style: none; margin-top: 1rem; display: grid; gap: .4rem; }
.points li::before { content: "— "; color: var(--red-ink); }
.tool-list { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: 0 2.5rem; border-top: 1px solid var(--line); margin-top: 2rem; }
.tool-list li { padding: 1.3rem 0; border-bottom: 1px solid var(--line); display: grid; gap: .25rem; align-content: start; }
.tool-list b { font-size: 1.4rem; letter-spacing: -.02em; }
.tool-list p { color: var(--ink-2); font-size: .95rem; }

/* drones */
.drone-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 5rem); align-items: center; }
.drone--alt .drone-info { order: 2; }
.drone-info h2 { margin: 0 0 .4rem; }
.drone-role { margin: 0 0 1.2rem; color: var(--ink-2); font-weight: 500; }
.specs { border-top: 1px solid var(--line); margin-top: 2rem; }
.spec { display: grid; grid-template-columns: 11rem 1fr; gap: 1rem; padding: .85rem 0; border-bottom: 1px solid var(--line); }
.drone-media .cs-art { aspect-ratio: 4 / 3; border-radius: var(--radius-lg); }
.drone-photo { margin: 0; border-radius: var(--radius-lg); overflow: hidden; background: var(--bg-deep); aspect-ratio: 4 / 3; box-shadow: 0 30px 80px rgba(40,40,70,.16); }
.drone-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.drone-photo + .gallery { margin-top: .8rem; }
.drone-art span { font-size: clamp(1.6rem, 4vw, 2.6rem); font-weight: 600; letter-spacing: -.03em; }
.gallery { display: grid; grid-template-columns: repeat(2, 1fr); gap: .8rem; }
.gallery img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius-md); }

/* à propos / IA */
.about-grid { display: grid; grid-template-columns: 1.3fr 1fr; gap: clamp(2rem, 6vw, 6rem); align-items: center; }
.about-text h2 { margin: 1rem 0 1.4rem; font-size: clamp(2rem, 1rem + 3.2vw, 4rem); }
.about-text p { margin-top: 1.1rem; max-width: 40rem; }
.about-photo img { width: 100%; height: auto; border-radius: var(--radius-lg); box-shadow: 0 30px 80px rgba(40,40,70,.18); }
.cv { display: grid; grid-template-columns: 1.6fr 1fr; gap: 3rem; align-items: center; }
.cv h2 { margin: 1rem 0; }
.cv .lead { margin-bottom: 1.8rem; }             /* de l'air entre le texte et le bouton « Télécharger » */
.cv-qr { justify-self: center; text-align: center; display: grid; gap: .8rem; }
.cv-qr img { background: #fff; padding: .7rem; border-radius: var(--radius-md); }
.quote { font-size: clamp(1.6rem, 1rem + 2.6vw, 3.4rem); font-weight: 500; letter-spacing: -.03em; line-height: 1.1; margin: 2.5rem 0; max-width: 24ch; }
.stats { list-style: none; display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 1rem; margin: 2rem 0; }
.stats li { border-top: 2px solid var(--ink); padding-top: .8rem; }
.stats b { display: block; font-size: clamp(1.5rem, 1rem + 1.8vw, 2.6rem); letter-spacing: -.03em; }
.stats span { color: var(--ink-2); font-size: .92rem; }

/* Aperçu « animations réduites » forcé avec ?reduced=1 : mêmes règles que le réglage du système */
.force-reduced *, .force-reduced *::before, .force-reduced *::after { animation: none !important; transition-duration: .01ms !important; }
.force-reduced.js .ln > span { transform: none; }
.force-reduced.js .rv { opacity: 1; transform: none; }
.force-reduced .finale-bg { animation: none; }

/* contact : le hero est maintenant en haut, la grille en dessous */
.contact-page { padding: 0; }
.contact-page .contact-grid { padding: var(--section) var(--gutter); }

@media (max-width: 860px) {
  .cs-grid, .drone-grid, .about-grid, .cv, .skill, .pn-grid { grid-template-columns: 1fr; }
  .rows .row, .deliver .row { grid-template-columns: 1fr; gap: .6rem; }
  .fact, .spec { grid-template-columns: 1fr; gap: .2rem; }
  .drone--alt .drone-info { order: 0; }
  .pn:last-child { text-align: left; }
}
@media (max-width: 560px) {
  /* petit écran : l'étiquette en mots passe au-dessus du titre */
  .rows--tags dt { grid-template-columns: minmax(0, 1fr); row-gap: .35rem; }
  .rows--tags dt small { grid-column: 1; }
}

/* 3. COULEUR : les cinq accents « heure dorée » (mêmes teintes que le verre du monde 3D)
   ============================================================ */
/* pastilles de technologies : une teinte par rang */
.tags li:nth-child(5n+1) { background: var(--coral-soft);   border-color: rgba(255,107,91,.4);   color: var(--coral-ink); }
.tags li:nth-child(5n+2) { background: var(--sky-soft);     border-color: rgba(74,163,255,.4);   color: var(--sky-ink); }
.tags li:nth-child(5n+3) { background: var(--mint-soft);    border-color: rgba(34,199,160,.45);  color: var(--mint-ink); }
.tags li:nth-child(5n+4) { background: var(--lilac-soft);   border-color: rgba(155,123,255,.45); color: var(--lilac-ink); }
.tags li:nth-child(5n)   { background: var(--apricot-soft); border-color: rgba(255,171,64,.5);   color: var(--apricot-ink); }

/* listes numérotées (méthode, langages, outils, chiffres) : un accent par rang */
.rows .row:nth-child(5n+1), .skill:nth-child(5n+1), .tool-list li:nth-child(5n+1), .stats li:nth-child(5n+1) { --acc: var(--coral);   --acc-ink: var(--coral-ink); }
.rows .row:nth-child(5n+2), .skill:nth-child(5n+2), .tool-list li:nth-child(5n+2), .stats li:nth-child(5n+2) { --acc: var(--apricot); --acc-ink: var(--apricot-ink); }
.rows .row:nth-child(5n+3), .skill:nth-child(5n+3), .tool-list li:nth-child(5n+3), .stats li:nth-child(5n+3) { --acc: var(--sky);     --acc-ink: var(--sky-ink); }
.rows .row:nth-child(5n+4), .skill:nth-child(5n+4), .tool-list li:nth-child(5n+4), .stats li:nth-child(5n+4) { --acc: var(--mint);    --acc-ink: var(--mint-ink); }
.rows .row:nth-child(5n),   .skill:nth-child(5n),   .tool-list li:nth-child(5n),   .stats li:nth-child(5n)   { --acc: var(--lilac);   --acc-ink: var(--lilac-ink); }
.rows dt .label, .skill .label, .tool-list li .label { color: var(--acc-ink, var(--ink-2)); font-weight: 600; }
.stats li { border-top-color: var(--acc, var(--ink)); }
.tool-list li { border-bottom-color: color-mix(in srgb, var(--acc, var(--line)) 45%, var(--line)); }
.skill .badge { background: color-mix(in srgb, var(--acc, #fff) 16%, #fff); border-color: color-mix(in srgb, var(--acc, var(--line)) 50%, #fff); color: var(--acc-ink, var(--ink-2)); }

/* liens de destination du hero : un point coloré, comme la dalle de verre correspondante dans le monde 3D */
.hub-link { display: inline-flex; align-items: center; gap: .55rem; }
.hub-link::before { content: ""; width: .55rem; height: .55rem; border-radius: 50%; background: var(--dot, var(--coral)); flex: none; }
.hub-link:nth-child(1) { --dot: var(--coral); }
.hub-link:nth-child(2) { --dot: var(--apricot); }
.hub-link:nth-child(3) { --dot: var(--sky); }
.hub-link:nth-child(4) { --dot: var(--mint); }
.hub-link:nth-child(5) { --dot: var(--lilac); }
.hub-link:hover::before, .hub-link:focus-visible::before { background: #fff; }

/* « Mes drones » : le choix du drone guide (deux boutons à bascule). Cachés sans WebGL : sans monde 3D il n'y a pas de guide. */
.hero--page.hero--guide { min-height: min(90svh, 54rem); }      /* texte plus long (choix du drone) : la 3D garde sa place au-dessus du texte sur téléphone */
.guide-block { margin-top: 2rem; }
.guide-title { margin: 0 0 .7rem; font-weight: 500; color: var(--ink-2); }
.guide-switch { margin-top: 0; }
.guide-switch .hub-link { font-family: inherit; color: var(--ink); cursor: pointer; }
.guide-switch .hub-link[aria-pressed="true"] { background: var(--ink); color: #fff; border-color: var(--ink); }
.guide-switch .hub-link[aria-pressed="true"]::before { background: #fff; }
.guide-switch .hub-link:disabled { opacity: .55; cursor: default; }
.guide-note { margin: .9rem 0 0; max-width: 30rem; font-size: .95rem; color: var(--ink-2); text-wrap: pretty; }
.world-off .guide-block { display: none; }
