/* ════════════════════════════════════════════════════════════════════════
   kraken_mascotte : STRUCTURE du MOTEUR de mascotte (#0023). Positions, couches
   de transform (clé anti-conflit : conteneur = position/dérive, .kr-octo-body =
   flottement, svg = échelle, .octo-pupil = regard, .octo-leg--live = tentacules),
   animations, overlays (attrape/dessin), bulle de BD, décoration de texte par stade.
   AUCUNE teinte de marque ici : les couleurs d'identité sont des TOKENS
   --kr-masc-* lus avec un DÉFAUT NEUTRE (gris, contraste AA sur le blanc de la
   bulle). Le SKIN hôte pose les vraies valeurs sur :root ; les couleurs internes
   de la créature (SVG) vivent dans SON partial, côté skin. La queue de bulle
   (.kr-tail) et la bulle (.kr-say) partagent la MÊME expression de couleur :
   elles restent assorties quel que soit le skin.
   Progressive enhancement : tout est gaté par .js (posée par kraken_mascotte.js) ;
   sans JS la mascotte reste cachée. La mono d'affichage (label, zZ) lit le token
   --kr-masc-mono si le skin le fournit, sinon un repli monospace neutre.
   ════════════════════════════════════════════════════════════════════════ */

/* ── Mascotte en OVERLAY (décision Max 07-02 : pas de réservation responsive,
   sur PC elle vit dans la marge naturelle près du contenu ; sur téléphone elle
   peut mordre légèrement sur le texte, assumé). */
:root{
  --kr-content-max: 1240px;
  --octo-col: clamp(64px, 18vw, 150px);
  --octo-edge: max(0px, calc((100vw - var(--kr-content-max)) / 2 - var(--octo-col)));
}
.kr-octopus{ position:fixed; left:var(--octo-edge); top:50%; transform:translateY(-50%);
  width:var(--octo-col); z-index:6; pointer-events:none; display:none; }
.kr-octopus svg{ width:86%; height:auto; display:block; margin:0 auto; filter:drop-shadow(0 6px 18px rgba(11,18,32,.25));
  transform-origin:right center; transition:filter .5s ease; }
.kr-octopus--deep svg{ filter:drop-shadow(0 0 16px color-mix(in srgb, var(--kr-masc-primary, #475569) 60%, transparent)) drop-shadow(0 0 34px color-mix(in srgb, var(--kr-masc-accent, #64748b) 28%, transparent)); }
.kr-octopus .octo-stage{ opacity:0; transition:opacity .45s ease; }
.kr-octopus .octo-stage.on{ opacity:1; }
.kr-octopus .octo-stage--final.on{ opacity:.88; }
.kr-octopus .octo-stage--final.on .octo-brain{ animation:kr-brain-pulse 3.2s ease-in-out infinite; }
@keyframes kr-brain-pulse{
  0%,100%{ filter:drop-shadow(0 0 2px color-mix(in srgb, var(--kr-masc-accent, #64748b) 30%, transparent)); }
  50%{ filter:drop-shadow(0 0 10px color-mix(in srgb, var(--kr-masc-accent, #64748b) 65%, transparent)); }
}
.kr-octo-arms{ position:fixed; inset:0; width:100%; height:100%; z-index:5; pointer-events:none;
  display:none; }
.kr-octo-arms path{ fill:var(--kr-masc-primary, #475569); opacity:.07; transform-origin:0 50%; transform:scaleX(0);
  transition:transform .3s linear; }
.js .kr-octopus{ display:block; }
@media (min-width:1024px){
  .js .kr-octo-arms{ display:block; }
}
@media (prefers-reduced-motion:reduce){
  .kr-octo-arms{ display:none !important; }
  .kr-octopus .octo-stage{ transition:none; }
  .kr-octopus .octo-brain{ animation:none !important; }
}

/* ── Entrée de la mascotte : perchée à droite du logo, puis saute (kraken_mascotte.js) ──
   Pendant le perchoir : au-dessus de la nav sticky (z 20 → 30) et stade kawaii
   forcé (le !important contre .octo-stage.on, posé par la logique de scroll). */
.kr-octopus.kr-octopus--perch{ z-index:30; }
.kr-octopus.kr-octopus--perch .octo-stage{ opacity:0 !important; transition:none; }
.kr-octopus.kr-octopus--perch .octo-stage:first-of-type{ opacity:1 !important; }
.kr-octopus.kr-octopus--perch svg{ filter:drop-shadow(0 3px 8px rgba(11,18,32,.22)); }

/* ── Sieste de la mascotte (kraken_mascotte.js) : zZ flottants + mascotte estompée ────
   Posée après 45 s sans interaction ; le halo blanc détache les zZ (teinte
   --kr-masc-primary) sur fond sombre comme clair (règle : jamais deux couleurs
   semblables superposées sans détachement). Réveil : shake WAAPI côté JS. */
.kr-zzz{ position:absolute; top:2%; right:-16%; width:72px; height:76px; display:none;
  font-family:var(--kr-masc-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace); font-weight:800; color:var(--kr-masc-primary, #475569); pointer-events:none;
  text-shadow:0 0 10px rgba(255,255,255,.95), 0 0 3px rgba(255,255,255,.9),
    0 2px 8px rgba(11,18,32,.35); }
.kr-octopus--sleep .kr-zzz{ display:block; }
.kr-zzz span{ position:absolute; left:0; bottom:0; opacity:0;
  animation:kr-zzz-float 3.6s ease-in-out infinite; }
.kr-zzz span:nth-child(1){ font-size:1.3rem; }
.kr-zzz span:nth-child(2){ font-size:1.9rem; left:18px; animation-delay:1.2s; }
.kr-zzz span:nth-child(3){ font-size:1.55rem; left:38px; animation-delay:2.4s; }
@keyframes kr-zzz-float{
  0%{ transform:translateY(0); opacity:0; }
  22%{ opacity:.92; }
  100%{ transform:translate(12px,-48px); opacity:0; }
}
.kr-octopus--sleep .octo-stage.on{ opacity:.72; }
.kr-octopus--sleep .octo-stage--final.on{ opacity:.6; }
.kr-octopus--sleep .octo-brain{ animation-play-state:paused; }
@media (prefers-reduced-motion:reduce){
  .kr-zzz span{ animation:none; opacity:.75; }
  .kr-zzz span:nth-child(2){ transform:translateY(-20px); }
  .kr-zzz span:nth-child(3){ transform:translateY(-40px); }
}

/* ── La mascotte parle : bulle de BD aux INTERSECTIONS entre sections ──────
   (injectée par kraken_mascotte.js, rien sans JS/feed). Le wrapper fixed est posé par
   le JS sur la jonction visible la plus haute entre deux sections (transform
   only, transition douce) : la bulle parle DEPUIS les entre-sections, jamais
   sur le contenu, donc elle vit aussi sur téléphone. Largeur pilotée par le
   JS : étroite à droite du poulpe, LARGE vers le poulpe quand la bulle est
   au-dessus/en-dessous de lui (jamais SUR lui), élargie vers la droite sur
   mobile où les sections s'écartent d'elles-mêmes (.kr-splay). La queue est
   un tentacule SVG (.kr-tail) rotaté/étiré par le JS : il VISE la mascotte en
   permanence, longueur ≈ 1/3 de la distance. Blanc + liseré (--kr-masc-primary)
   + ombre + halo = détachée sur fonds clairs ET sombres (règle : jamais deux
   couleurs semblables superposées sans liseré). */
.kr-say-wrap{ position:fixed; top:0; left:calc(var(--octo-edge) + var(--octo-col) - 12px);
  z-index:18; pointer-events:none; will-change:transform;
  transition:transform .55s cubic-bezier(.22,.8,.3,1); }
.kr-say{ position:relative; width:min(260px, calc(100vw - var(--octo-col) - 40px));
  padding:.8rem .95rem .85rem; background:#fff;
  border:1.5px solid color-mix(in srgb, var(--kr-masc-primary, #475569) 65%, transparent); border-radius:18px;
  box-shadow:0 10px 30px rgba(11,18,32,.28), 0 0 18px color-mix(in srgb, var(--kr-masc-primary, #475569) 22%, transparent);
  opacity:0; transform:translateY(8px) scale(.94); transform-origin:16% 65%;
  transition:opacity .35s ease, transform .35s var(--ease,ease); pointer-events:none; }
.kr-say.on{ opacity:1; transform:none; }
.kr-tail{ position:absolute; left:0; top:0; width:100px; height:24px;
  transform-origin:0 50%; will-change:transform;
  opacity:0; transition:opacity .35s ease; }
.kr-say-wrap--on .kr-tail{ opacity:1; }
.kr-tail svg{ display:block; width:100%; height:100%; overflow:visible; }
.kr-tail path{ fill:#fff; stroke:color-mix(in srgb, var(--kr-masc-primary, #475569) 65%, transparent); stroke-width:1.5;
  stroke-linejoin:round; vector-effect:non-scaling-stroke; }
.kr-say .who{ display:block; font-family:var(--kr-masc-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace); font-size:.6rem; font-weight:700;
  letter-spacing:.14em; text-transform:uppercase; color:var(--kr-masc-primary, #475569); margin:0 0 .3rem; }
.kr-say .txt{ margin:0; font-size:.9rem; line-height:1.45; color:var(--kr-masc-ink-text, #0f172a); min-height:2.6em; }
/* Frappe : les caractères pré-décorés se révèlent par visibility (zéro
   reflow, la bulle garde sa taille finale) ; le curseur suit le caractère
   courant en absolu (il ne pousse pas le texte). */
.kr-say .ch{ visibility:hidden; position:relative; }
.kr-say .ch.on{ visibility:visible; }
.kr-say.typing .ch.cur::after{ content:"▍"; position:absolute; left:100%; top:0; color:var(--kr-masc-accent, #64748b); }
.kr-octopus--talk .octo-stage.on .octo-brain{ animation:kr-brain-pulse 1.7s ease-in-out infinite; }
@media (max-width:767.98px){
  .kr-say{ padding:.65rem .8rem .7rem; }
  .kr-say .txt{ font-size:.83rem; min-height:2.4em; }
  .kr-say .who{ font-size:.56rem; }
  /* Les sections s'écartent d'elles-mêmes pour laisser la place à la bulle
     (margin-top posé par le JS sur la section sous la jonction choisie). */
  .kr-splay{ transition:margin-top .45s ease; }
}
@media (prefers-reduced-motion:reduce){
  .kr-say-wrap{ transition:none; }
  .kr-say{ transform:none; transition:opacity .5s ease; }
  .kr-splay{ transition:none; }
}

/* ── Décoration du texte par stade de la mascotte (spans .kw posés par le JS) ──
   Étape 1 douce (2 teintes), 2-3 de plus en plus colorée, 4 monstre :
   polices/tailles mêlées + tremblement ponctuel sur une onomatopée. La déco
   arrive PENDANT la frappe (caractères révélés à travers les spans) ; le
   tremblement part quand son mot finit de s'écrire. Les 5 teintes sont des
   tokens --kr-masc-kw-* posés par le skin ; défaut = gris neutre lisible sur le
   blanc de la bulle (contraste AA), la majorité du texte reste normale. */
.kr-say .kw-teal{ color:var(--kr-masc-kw-teal, #475569); font-weight:700; }
.kr-say .kw-rose{ color:var(--kr-masc-kw-rose, #475569); font-weight:700; }
.kr-say .kw-ind{ color:var(--kr-masc-kw-ind, #475569); font-weight:700; }
.kr-say .kw-cyan{ color:var(--kr-masc-kw-cyan, #475569); font-weight:700; }
.kr-say .kw-vio{ color:var(--kr-masc-kw-vio, #475569); font-weight:700; }
.kr-say .kw-b{ font-weight:800; }
.kr-say .kw-mono{ font-family:var(--kr-masc-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace); font-size:.92em; }
.kr-say .kw-serif{ font-family:Georgia, "Times New Roman", serif; font-style:italic; }
.kr-say .kw-disp{ font-family:"Arial Black", "Avenir Heavy", ui-sans-serif, sans-serif; letter-spacing:.02em; }
.kr-say .kw-sm{ font-size:.85em; }
.kr-say .kw-lg{ font-size:1.16em; }
.kr-say .kw-xl{ font-size:1.3em; }
.kr-say .kw-shake{ display:inline-block; animation:kr-w-shake .45s ease-in-out 3; }
@keyframes kr-w-shake{
  0%,100%{ transform:none; }
  25%{ transform:translate(-1px,.5px) rotate(-2deg); }
  75%{ transform:translate(1px,-.5px) rotate(2deg); }
}
@media (prefers-reduced-motion:reduce){
  .kr-say .kwd, .kr-say .kw-shake{ animation:none; }
}

/* Micro-vie : le kraken respire/flotte doucement dans sa gouttière (jamais sur le contenu).
   Le conteneur porte translateY(-50%) pour le centrage vertical : le keyframe le préserve. */
/* Couche de mouvement : le CONTENEUR gère la position (translateY(-50%) + dérive JS au scroll),
   .kr-octo-body flotte (respiration), le svg garde l'échelle. Trois couches = zéro conflit. */
.kr-octopus{ transition:transform .5s ease-out; }                /* dérive douce quand le scroll bouge le conteneur */
.js .kr-octo-body{ animation:kr-octo-float 5.5s ease-in-out infinite; }
.kr-octo-react{ transform-origin:50% 82%; }                       /* pivot bas : sursaut/redressement naturel (piloté en JS, transitoire) */
/* Tentacules VIVANTES : chaque patte ondule autour de son attache (transform-box fill-box), décalées
   pour un mouvement organique. Frétillement plus vif quand le poulpe te remarque (curseur proche). */
.octo-leg{ transform-box:fill-box; transform-origin:50% 0%; animation:kr-leg-wave 3.4s ease-in-out infinite; will-change:transform; }
.octo-leg:nth-child(2){ animation-delay:-.7s;  animation-duration:3.9s; }
.octo-leg:nth-child(3){ animation-delay:-1.4s; animation-duration:3.2s; }
.octo-leg:nth-child(4){ animation-delay:-2.1s; animation-duration:3.7s; }
@keyframes kr-leg-wave{ 0%,100%{ transform:rotate(-5deg); } 50%{ transform:rotate(5deg); } }
.kr-octopus--near .octo-leg{ animation-duration:1.2s !important; } /* il te remarque → les tentacules frétillent */
/* Tentacules RÉALISTES (stades 3-4) : chemins fermés remplis, onde propagée +
   effilement reconstruits chaque frame en JS. On anime « d », pas transform :
   l'ondulation CSS en bloc (kr-leg-wave) et le frétillement --near sont
   neutralisés ici. reduced-motion : le JS pose une frame statique, pas de rAF. */
.octo-leg--live{ animation:none !important; will-change:auto; }
@media (prefers-reduced-motion:reduce){ .octo-leg{ animation:none; } }
/* ATTRAPE : le poulpe jaillit une ou plusieurs VRAIES tentacules (formes pleines
   effilées qui serpentent, pointe qui s'enroule) vers des éléments, qui jouent un
   scénario (tressaillement, retournement, éjection...) puis reviennent. Le tracé
   PLEIN est reconstruit chaque frame en JS (coords px) : --kr-masc-primary semi-transparent. */
.kr-octo-grab{ position:fixed; inset:0; width:100%; height:100%; pointer-events:none; z-index:6; display:none; }
.js .kr-octo-grab{ display:block; }
.kr-grab-arm{ fill:var(--kr-masc-primary, #475569); stroke:none; opacity:0; filter:drop-shadow(0 2px 8px color-mix(in srgb, var(--kr-masc-primary, #475569) 40%, transparent)); }
.js .kr-grab-arm{ opacity:.5; }
.kr-grabbed{ animation:kr-grab-wobble .6s ease-in-out; }
@keyframes kr-grab-wobble{ 0%,100%{ transform:none; } 25%{ transform:translateY(-3px) rotate(-1.5deg); } 60%{ transform:translateY(2px) rotate(1.5deg); } }
/* attrape active aussi sur mobile (on essaie) ; seul reduced-motion la coupe */
@media (prefers-reduced-motion:reduce){ .kr-octo-grab{ display:none !important; } }
/* DESSIN : le poulpe trace un petit doodle (tracé inventé par le LLM) dans SA gouttière, jamais sur
   le contenu (zone mesurée en JS, desktop + vraie gouttière requis). L'encre se révèle par
   stroke-dashoffset (« il le dessine »), une tentacule vise la pointe courante, puis tout s'efface. */
.kr-octo-draw{ position:fixed; inset:0; width:100%; height:100%; pointer-events:none; z-index:6; display:none; }
.js .kr-octo-draw.on{ display:block; }
.kr-draw-arm{ fill:var(--kr-masc-primary, #475569); stroke:none; opacity:0; filter:drop-shadow(0 2px 8px color-mix(in srgb, var(--kr-masc-primary, #475569) 40%, transparent)); }
.kr-draw-ink{ fill:none; stroke:var(--kr-masc-accent, #64748b); stroke-width:3; stroke-linecap:round; stroke-linejoin:round; opacity:0; filter:drop-shadow(0 1px 5px color-mix(in srgb, var(--kr-masc-accent, #64748b) 55%, transparent)); }
.kr-draw-cap{ fill:var(--kr-masc-primary, #475569); font:600 12px/1.2 system-ui,-apple-system,sans-serif; opacity:0; }
@media (prefers-reduced-motion:reduce){ .kr-octo-draw{ display:none !important; } }
@keyframes kr-octo-float{ 0%,100%{ transform:translate(0,0); } 25%{ transform:translate(4px,-7px); } 50%{ transform:translate(0,-4px); } 75%{ transform:translate(-4px,-8px); } } /* nage organique (sway latéral + houle) */
.kr-octopus--sleep .kr-octo-body{ animation-duration:9s; }       /* respiration ralentie en sieste */
.kr-octopus .octo-pupil{ transition:transform .12s ease-out; }   /* le regard glisse, ne saute pas */
@media (prefers-reduced-motion: reduce){ .js .kr-octo-body{ animation:none; } }
