/* ══════════════════════════════════════════════════════════════════
   Intro 3D temps réel — iPhone en three.js posé sur une table.
   Reprise du lot de design « Motion 3D », intégrée comme intro de la
   vitrine. Seules les règles .mo-* sont reprises : la remise à zéro, le
   body, les boutons et la section finale du prototype sont déjà couverts
   par index.html et feraient double emploi.
   ══════════════════════════════════════════════════════════════════ */

/* Le lot de design nommait sa palette --ambre/--or ; le site porte les
   mêmes teintes sous --vert/--vert-mid/--cuivre. On fait le pont ici,
   plutôt que de renommer dans tout le fichier d'origine. */
:root {
    --ambre:      var(--vert);
    --ambre-mid:  var(--vert-mid);
    --ambre-deep: var(--cuivre);
    --or:         var(--vert);
}

/* Aiguillage des deux intros. Par défaut la version CSS, la 3D seulement
   si le script d'entrée a jugé l'appareil capable (classe .intro-3d). */
#ixIntro3d { display: none; }
html.intro-3d #ixIntro3d { display: block; }
html.intro-3d #ixIntro,
html.intro-3d #ixCue { display: none; }

.mo-track{height:1100svh;position:relative}
.mo-snap{position:absolute;left:0;width:1px;height:1px;scroll-snap-align:start;pointer-events:none}
.mo-stage{position:sticky;top:0;height:100svh;overflow:hidden}
#gl{position:absolute;inset:0;width:100%;height:100%;display:block}
.mo-vig{position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse 78% 72% at 50% 48%, transparent 0%, oklch(0.08 0.006 60 / 0.55) 100%)}
.mo-grain{position:absolute;inset:0;pointer-events:none;opacity:0.4;background-image:radial-gradient(oklch(0.95 0.02 90 / 0.05) 0.5px, transparent 0.5px);background-size:22px 22px}

.mo-intro{position:absolute;left:50%;top:15svh;transform:translateX(-50%);text-align:center;z-index:8;width:min(90vw,780px);pointer-events:none;will-change:opacity,transform}
.mo-intro .im{font-family:var(--mono);font-size:11px;letter-spacing:0.3em;text-transform:uppercase;color:var(--ambre);margin-bottom:20px}
.mo-intro h1{font-size:clamp(30px,4.6vw,58px);font-weight:600;line-height:1.05;letter-spacing:-0.04em;text-wrap:balance;background:linear-gradient(180deg, var(--blanc) 55%, oklch(0.72 0.012 170) 100%);-webkit-background-clip:text;background-clip:text;color:transparent}

.mo-cap{position:absolute;top:50%;transform:translateY(-50%);width:min(31vw,352px);z-index:8;pointer-events:none;opacity:0;will-change:transform,opacity}
.mo-cap.gauche{left:max(4vw, calc(50vw - 600px))}
.mo-cap.droite{right:max(4vw, calc(50vw - 600px));text-align:right}
.mo-cap .veil{position:absolute;inset:-30px -38px;z-index:-1;border-radius:28px;background:radial-gradient(ellipse 62% 58% at var(--vx,20%) 50%, oklch(0.10 0.012 60 / 0.82) 0%, oklch(0.10 0.012 60 / 0.45) 52%, transparent 100%);filter:blur(6px)}
.mo-cap.droite .veil{--vx:80%}
.mo-cap .k{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:0.2em;text-transform:uppercase;color:var(--ambre);margin-bottom:14px;display:inline-flex;align-items:center;gap:10px}
.mo-cap.gauche .k::before,.mo-cap.droite .k::after{content:"";width:26px;height:1px;background:oklch(0.82 0.15 73 / 0.5)}
.mo-cap h2{font-size:clamp(23px,2.7vw,35px);font-weight:600;line-height:1.14;letter-spacing:-0.028em;text-wrap:balance;margin-bottom:13px;color:oklch(0.985 0.004 170);text-shadow:0 1px 2px oklch(0.10 0.01 60 / 0.9), 0 3px 28px oklch(0.10 0.01 60 / 0.75)}
.mo-cap p{font-size:14.5px;color:oklch(0.80 0.010 170);line-height:1.7;text-shadow:0 1px 2px oklch(0.10 0.01 60 / 0.85), 0 2px 18px oklch(0.10 0.01 60 / 0.8)}

.mo-prog{position:fixed;right:24px;top:50%;transform:translateY(-50%);z-index:900;display:flex;flex-direction:column;align-items:center;gap:12px;opacity:0;transition:opacity 500ms var(--ease);pointer-events:none}
.mo-prog.on{opacity:1}
.mo-prog .line{width:1.5px;height:120px;background:oklch(0.96 0.01 170 / 0.12);border-radius:2px;position:relative;overflow:hidden}
.mo-prog .fill{position:absolute;top:0;left:0;right:0;height:0%;background:linear-gradient(180deg, var(--or), var(--ambre-mid));border-radius:2px}
.mo-prog .num{font-family:var(--mono);font-size:9.5px;letter-spacing:0.14em;color:var(--gris-2)}
.mo-prog .num b{color:var(--ambre);font-weight:600}
.mo-cue{position:fixed;bottom:26px;left:50%;transform:translateX(-50%);z-index:900;display:flex;flex-direction:column;align-items:center;gap:9px;font-family:var(--mono);font-size:9.5px;letter-spacing:0.22em;text-transform:uppercase;color:var(--gris-2);transition:opacity 500ms;pointer-events:none}
.mo-cue::after{content:"";width:1px;height:34px;background:linear-gradient(to bottom, var(--ambre), transparent);animation:moCue 1.8s var(--ease) infinite}
@keyframes moCue{0%{transform:scaleY(0);transform-origin:top;opacity:1}70%{transform:scaleY(1);transform-origin:top;opacity:1}100%{transform:scaleY(1);opacity:0}}
.mo-cue.off{opacity:0}
/* ── Attente du chargement ───────────────────────────────────────
   La scène demande three.js puis le modèle du plat : plusieurs secondes
   sur une connexion moyenne, pendant lesquelles le visiteur n'avait qu'un
   fond noir et une ligne grise minuscule. On affiche donc un vrai état
   d'attente, présent dès la première peinture (il est écrit en dur dans
   index.html) et nourri par la progression réelle du téléchargement. */
.mo-load{position:absolute;left:50%;bottom:11svh;transform:translateX(-50%);z-index:9;width:min(86vw,340px);text-align:center;transition:opacity 600ms var(--ease),transform 600ms var(--ease)}
.mo-load.off{opacity:0;transform:translateX(-50%) translateY(8px);pointer-events:none}
/* Voile : dès que three.js est prêt, la scène s'affiche derrière ce bloc et
   le texte se retrouve sur le bois clair de la table. Même remède que pour
   les légendes de chapitre. */
.mo-load::before{content:"";position:absolute;inset:-26px -40px;z-index:-1;border-radius:26px;background:radial-gradient(ellipse 60% 58% at 50% 50%, oklch(0.10 0.012 60 / 0.88) 0%, oklch(0.10 0.012 60 / 0.52) 55%, transparent 100%);filter:blur(6px)}
.mo-load-txt{font-family:var(--mono);font-size:10.5px;letter-spacing:0.2em;text-transform:uppercase;color:oklch(0.94 0.006 170);margin-bottom:13px;text-shadow:0 1px 2px oklch(0.10 0.01 60 / 0.9)}
.mo-load-barre{position:relative;height:3px;border-radius:3px;background:oklch(0.96 0.01 170 / 0.18);overflow:hidden;box-shadow:0 1px 3px oklch(0.10 0.01 60 / 0.6)}
.mo-load-barre span{position:absolute;inset:0 auto 0 0;width:0%;border-radius:2px;background:linear-gradient(90deg, var(--ambre-mid), var(--ambre));transition:width 260ms var(--ease)}
/* Tant que le poids total est inconnu, la barre fait des allers-retours :
   elle dit « ça travaille » sans mentir sur l'avancement. */
.mo-load-barre.indetermine span{width:34%;animation:moAttente 1.5s var(--ease) infinite;transition:none}
@keyframes moAttente{0%{left:-34%}100%{left:100%}}
.mo-load-note{margin-top:12px;font-size:12.5px;line-height:1.55;color:oklch(0.80 0.010 170);text-shadow:0 1px 2px oklch(0.10 0.01 60 / 0.85)}
.mo-load.echec .mo-load-txt{color:var(--ambre)}
.mo-load.echec .mo-load-barre{display:none}

@media (max-width:900px){
.mo-cap{top:auto;bottom:6svh;transform:none;width:min(88vw,430px);text-align:center !important}
.mo-cap.gauche,.mo-cap.droite{left:50%;right:auto;transform:translateX(-50%)}
.mo-cap.gauche .k::before,.mo-cap.droite .k::after{display:none}
.mo-cap h2{font-size:20px}.mo-cap p{font-size:12.5px}
.mo-cap .veil{inset:-22px -26px}
.mo-intro{top:9svh}.mo-prog{right:12px}
}
