/*! KairSun — mascot flight (hero → navbar dock).
 * Owns: .ks-mascot-* / [data-ks-mascot-*] and #ks-companion overrides gated by
 * html.ks-mascot-ready (added by ks-mascot-flight.js). Load AFTER marketing.css.
 * !important only where marketing.css is !important (top: --header-h 124/102,
 * face 44px): ids + ready class win. Without JS the plain sticky companion
 * (marketing.css) is untouched.
 * v2 (comp3): mensaje con tipografía clamp + 2 líneas (PC) / composición alta
 * (mobile), glass épico estilo navbar en stage+inner, flash neón conic al
 * cambiar de beat, vida de vuelo (aura/trail/idle). Reduced-motion: sin flash.
 * Contract: docs/screens/60_mascota_vuelo.md */
:root {
  /* Destino más corto que antes (56/64): el flyer aterriza en un slot menor
   * y el stack fijo no se come 28-30% del viewport. El rostro se agranda
   * por recorte (object-view-box), no por caja. */
  --ks-face-min: 50px;
  --ks-face-max: 58px;
  --ks-fuse: 0px;
  --ks-header-h: var(--header-h, 64px);
}
@media (min-width: 861px) {
  :root {
    --ks-face-min: 68px;
    --ks-face-max: 76px;
  }
}

/* ---- Same glass lamina: dock pinned under the real header ---- */
/* +2px: el borde/hairline del header deja una costura de 2px a 390/768; el
 * fuselaje (--ks-fuse, medido por el JS) la rellena con el mismo vidrio. */
.ks-mascot-ready #ks-companion {
  top: calc(var(--header-h, 64px) + 2px) !important;
  z-index: 55;
}

@media (prefers-reduced-motion: no-preference) {
  .ks-mascot-ready #ks-companion {
    transition: transform var(--dur-2, 240ms) var(--ease-out, ease);
  }
}

html.ks-nav-hide.ks-mascot-ready #ks-companion {
  transform: translateY(calc(-1 * var(--header-h, 64px)));
}

.ks-mascot-ready .ks-mascot-fuse::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: calc(-1 * var(--ks-fuse, 0px));
  height: calc(var(--ks-fuse, 0px) + 3px);
  pointer-events: none;
  background: rgba(2, 13, 26, 0.94);
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .ks-mascot-ready .ks-mascot-fuse::before {
    background: rgba(2, 13, 26, 0.62);
    backdrop-filter: blur(28px) saturate(1.35);
    -webkit-backdrop-filter: blur(28px) saturate(1.35);
  }
}

/* ---- Dock reveal: bar + bigger avatar only when the mascot has landed ---- */
.ks-mascot-ready #ks-companion .ks-companion-inner {
  visibility: hidden;
  opacity: 0;
}
.ks-mascot-ready #ks-companion .ks-companion-face {
  width: clamp(var(--ks-face-min), 13vw, var(--ks-face-max)) !important;
  height: clamp(var(--ks-face-min), 13vw, var(--ks-face-max)) !important;
}
@media (min-width: 861px) {
  .ks-mascot-ready #ks-companion .ks-companion-face {
    width: clamp(var(--ks-face-min), 6.2vw, var(--ks-face-max)) !important;
    height: clamp(var(--ks-face-min), 6.2vw, var(--ks-face-max)) !important;
  }
}
/* Avatar legible: kitsune-mark.png es cuerpo entero 96×90; en cover centrado
 * la cabeza queda ~1/3. object-position apunta al rostro (fallback) y
 * object-view-box recorta la cabeza para que llene el círculo. */
.ks-mascot-ready #ks-companion .ks-companion-face {
  object-position: 62% 28%;
}
@supports (object-view-box: inset(0% 0% 0% 0%)) {
  .ks-mascot-ready #ks-companion .ks-companion-face {
    object-view-box: inset(6% 14% 50% 46%);
    object-position: 50% 50%;
  }
}
/* Stack fijo más bajo: menos alto de vidrio por fila (avatar manda). */
.ks-mascot-ready #ks-companion .ks-companion-inner {
  padding-block: 2px;
}
.ks-mascot-ready #ks-companion[data-ks-mascot-state="dock"] .ks-companion-inner {
  visibility: visible;
  opacity: 1;
}
.ks-mascot-ready #ks-companion[data-ks-mascot-state="dock"] .ks-companion-inner {
  border-bottom-color: rgba(45, 212, 191, 0.4);
  box-shadow:
    0 18px 40px rgba(0, 0, 0, 0.38),
    inset 0 -1px 0 rgba(245, 196, 81, 0.1);
}
@media (prefers-reduced-motion: no-preference) {
  .ks-mascot-ready #ks-companion .ks-companion-inner {
    transition:
      opacity var(--dur-2, 240ms) var(--ease-out, ease),
      visibility 0s linear var(--dur-2, 240ms);
  }
  .ks-mascot-ready #ks-companion[data-ks-mascot-state="dock"] .ks-companion-inner {
    transition:
      opacity var(--dur-2, 240ms) var(--ease-spring, cubic-bezier(0.2, 0.85, 0.25, 1)),
      visibility 0s;
  }
  /* Scrub-driven crossfade: never smooth per-frame values */
  .ks-mascot-ready #ks-companion[data-ks-mascot-landing="1"] .ks-companion-inner {
    visibility: visible;
    transition: none;
  }
}

/* ---- Flyer: the one mascot, moved only with transforms ---- */
.ks-mascot-flyer {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 70; /* > header 60: el flyer nunca se oculta bajo el header al aterrizar */
  pointer-events: none;
  transform-origin: 50% 50%;
  backface-visibility: hidden;
  contain: layout paint style;
  visibility: hidden;
  opacity: 0;
}
.ks-mascot-flyer[data-on="1"] {
  visibility: visible;
  will-change: transform, opacity;
}
.ks-mascot-flyer img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter:
    drop-shadow(0 18px 30px rgba(0, 0, 0, 0.45))
    drop-shadow(0 0 22px rgba(45, 212, 191, 0.18));
}

/* ---- Hero handoff: instant (flyer takes the exact same visual spot) ---- */
.ks-mascot-ready .ks-mascot-hero.ks-mascot-hero-off {
  opacity: 0 !important;
}
/* The empty stage (bloom, rim, glass pad) must leave with the mascot, or the
 * hero keeps an orphan pedestal while the flyer is mid-air. A 120ms delay lets
 * the flyer take over first; restore is instant (same pixel spot).
 * Note: `.hero-visual` already runs marketing's soft-rise with fill `both`, so
 * its opacity is animation-owned — hide via visibility, not opacity. */
.ks-mascot-ready .ks-mascot-stage-off {
  visibility: hidden;
  transition: visibility 0s linear var(--dur-1, 140ms);
}

/* ---- Reduced motion: no flyer, companion toggle only, hero never hidden ---- */
@media (prefers-reduced-motion: reduce) {
  .ks-mascot-flyer {
    display: none !important;
  }
  .ks-mascot-ready #ks-companion .ks-companion-inner,
  .ks-mascot-ready #ks-companion[data-ks-mascot-state="dock"] .ks-companion-inner {
    transition: none !important;
  }
  .ks-mascot-ready .ks-mascot-hero {
    opacity: 1 !important;
  }
  .ks-mascot-ready .ks-mascot-stage-off {
    visibility: visible;
    transition: none;
  }
}

/* ---- Footer in-view (IO de ks-mascot-flight.js): el dock fijo ya no lo tapa.
 * Al final para ganarle en cascada a [data-ks-mascot-state="dock"]; visibility
 * se hereda pero un descendiente con `visible` la revierte, por eso el inner
 * también se apaga (el fuse ::before cuelga del dock y cae con él). */
.ks-mascot-ready #ks-companion[data-ks-footer="1"],
.ks-mascot-ready #ks-companion[data-ks-footer="1"] .ks-companion-inner,
.ks-mascot-ready #ks-companion[data-ks-footer="1"] .ks-companion-stage,
.ks-mascot-ready #ks-companion[data-ks-footer="1"] .ks-companion-face,
.ks-mascot-ready #ks-companion[data-ks-footer="1"] .ks-companion-line,
.ks-mascot-ready #ks-companion[data-ks-footer="1"] .ks-companion-line.is-on {
  visibility: hidden !important;
}

/* ========== COMPANION/MASCOTA v2 (comp3) ==========================================
 * 1. El mensaje llena el dock: tipografía clamp grande (PC 18.4-22.7px,
 *    mobile 16-18.6px), stage alto (PC 64-84px / mobile 62-70px) con la línea
 *    activa centrada en vertical (flex) y clamp de 2 líneas en ≥1101.
 * 2. Mobile más alto y sin huecos: stage con flex:1 que ocupa el ancho, inner
 *    centrado con gap; face sin offset de primera línea.
 * 3. Glass épico = mismo recetario que .site-header: rgba(2,13,26,.62) + blur 28
 *    saturate 1.35. El inner deja pasar el fondo (antes .92 opaco mataba el blur
 *    del stage). Contraste AA: composición >7:1 sobre blanco puro + text-shadow;
 *    sin backdrop-filter el tinte sube a .94/.9 opaco (igual que la navbar).
 * 4. Flash neón una vez por cambio de beat (anillo conic enmascarado + halo): lo
 *    dispara .ks-companion--flash / .ks-companion-flash.is-firing (ks-companion.js).
 * 5. Vida: aura/trail del flyer y respiración del avatar en dock (transform/opacity).
 * ================================================================================= */

/* --- 1/2. Mensaje: aprovecha TODO el alto/ancho (mobile first) ---
 * Mobile: ~16-18.5px (antes 15.5), stage 62-70px que llena el dock y centra
 * la línea activa (flex) para que no queden huecos con 1 sola línea.
 * PC ≥861: ~19.3-22.7px (antes 16.3-19.5), stage 64-84px para 2 líneas. */
.ks-mascot-ready #ks-companion .ks-companion-inner {
  align-items: center;
  gap: 12px;
  padding-block: 6px;
}
.ks-mascot-ready #ks-companion .ks-companion-face {
  margin-top: 0 !important; /* el texto ahora centra: fuera el offset de primera línea */
}
.ks-mascot-ready #ks-companion .ks-companion-stage {
  flex: 1 1 auto;
  /* !important: marketing.css fija min-height:0 !important para el dock de una
   * línea; acá el stage alto es el que llena el dock y estabiliza el aterrizaje
   * (misma altura con 1 o 2 líneas). */
  min-height: clamp(62px, 18px + 12vw, 70px) !important;
  padding: 9px 14px 10px 16px !important;
}
.ks-mascot-ready #ks-companion .ks-companion-line,
.ks-mascot-ready #ks-companion .ks-companion-line.is-on {
  font-size: clamp(1rem, 0.55rem + 2.3vw, 1.16rem) !important;
  line-height: 1.38 !important;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}
/* La línea activa centra su texto en el stage alto; las ocultas siguen fuera
 * de layout (absolute + clip, marketing.css) así que el flex no las afecta. */
.ks-mascot-ready #ks-companion .ks-companion-line.is-on {
  display: flex !important;
  align-items: center;
}
@media (min-width: 861px) {
  .ks-mascot-ready #ks-companion .ks-companion-inner {
    gap: 16px;
    padding-block: 5px;
  }
  .ks-mascot-ready #ks-companion .ks-companion-stage {
    min-height: clamp(64px, 24px + 4.5vw, 84px) !important;
    padding: 10px 20px 11px 22px !important;
  }
  .ks-mascot-ready #ks-companion .ks-companion-line,
  .ks-mascot-ready #ks-companion .ks-companion-line.is-on {
    font-size: clamp(1.15rem, 0.72rem + 0.9vw, 1.42rem) !important;
    line-height: 1.35 !important;
  }
}
/* PC: 2 líneas máximo, sin ellipsis de una sola línea; el alto no salta porque
 * el stage ya tiene min-height (alineación del aterrizaje intacta). */
@media (min-width: 1101px) {
  .ks-mascot-ready #ks-companion .ks-companion-line.is-on {
    display: -webkit-box !important;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    white-space: normal !important;
    overflow: hidden !important;
    text-overflow: clip !important;
    max-height: 2.7em;
  }
}

/* --- 3. Glass épico (misma receta que la navbar) --- */
.ks-mascot-ready #ks-companion .ks-companion-inner {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.02) 46%, rgba(45, 212, 191, 0.05)),
    rgba(2, 13, 26, 0.6) !important;
}
.ks-mascot-ready #ks-companion .ks-companion-stage {
  background:
    linear-gradient(160deg, rgba(255, 255, 255, 0.11), rgba(255, 255, 255, 0.02) 46%, rgba(45, 212, 191, 0.08)),
    rgba(2, 13, 26, 0.52) !important;
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .ks-mascot-ready #ks-companion .ks-companion-inner {
    backdrop-filter: blur(28px) saturate(1.35) !important;
    -webkit-backdrop-filter: blur(28px) saturate(1.35) !important;
  }
  .ks-mascot-ready #ks-companion .ks-companion-stage {
    backdrop-filter: blur(28px) saturate(1.35) !important;
    -webkit-backdrop-filter: blur(28px) saturate(1.35) !important;
  }
}
/* Sin blur (misma receta sólida que .site-header): tinte opaco para que el
 * texto #f4f4f5 mantenga contraste AA sobre cualquier fondo claro. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .ks-mascot-ready #ks-companion .ks-companion-inner {
    background:
      linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.02) 46%, rgba(45, 212, 191, 0.05)),
      rgba(2, 13, 26, 0.94) !important;
  }
  .ks-mascot-ready #ks-companion .ks-companion-stage {
    background:
      linear-gradient(160deg, rgba(255, 255, 255, 0.11), rgba(255, 255, 255, 0.02) 46%, rgba(45, 212, 191, 0.08)),
      rgba(2, 13, 26, 0.9) !important;
  }
}

/* --- 4. Flash neón premium al cambiar el mensaje (una vez por beat) --- */
.ks-companion-inner {
  position: relative; /* containing block del anillo (fixed sin importar el gate) */
}
.ks-companion-flash {
  position: absolute;
  z-index: 3;
  pointer-events: none;
  border-radius: 50%;
  opacity: 0;
  transform: scale(0.9) rotate(-10deg);
}
.ks-companion-flash::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: conic-gradient(from 0deg, #2DD4BF, #F5C451, #A855F7, #5EEAD4, #2DD4BF);
}
@supports ((-webkit-mask: radial-gradient(#000, #000)) or (mask: radial-gradient(#000, #000))) {
  .ks-companion-flash::before {
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px));
    mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px));
  }
}
@supports not ((-webkit-mask: radial-gradient(#000, #000)) or (mask: radial-gradient(#000, #000))) {
  .ks-companion-flash::before {
    background: none;
  }
}
.ks-companion-flash::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: inherit;
  border: 2px solid rgba(94, 234, 212, 0.65);
  box-shadow:
    0 0 16px rgba(45, 212, 191, 0.55),
    0 0 30px rgba(245, 196, 81, 0.3);
}
@keyframes ks-face-flash {
  0% { opacity: 0; transform: scale(0.86) rotate(-14deg) }
  18% { opacity: 1; transform: scale(1) rotate(0deg) }
  60% { opacity: 0.85; transform: scale(1.02) rotate(9deg) }
  100% { opacity: 0; transform: scale(1.1) rotate(16deg) }
}
@media (prefers-reduced-motion: no-preference) {
  .ks-companion-flash.is-firing {
    animation: ks-face-flash 680ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
    will-change: transform, opacity;
  }
}
@media (prefers-reduced-motion: reduce) {
  .ks-companion-flash {
    display: none !important;
  }
}

/* --- 5. Vida de vuelo/estados (solo transform/opacity, listeners pasivos) --- */
.ks-mascot-flyer::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 4%;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 42%, rgba(45, 212, 191, 0.38), rgba(245, 196, 81, 0.18) 48%, transparent 72%);
  opacity: 0;
  transform: scale(0.95);
  pointer-events: none;
}
.ks-mascot-flyer::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 2%;
  right: 46%;
  top: 58%;
  height: 14%;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, rgba(94, 234, 212, 0.34), rgba(245, 196, 81, 0.18));
  opacity: 0;
  transform: rotate(-8deg);
  pointer-events: none;
}
@keyframes ks-flyer-aura {
  0%, 100% { opacity: 0.5; transform: scale(0.96) }
  50% { opacity: 1; transform: scale(1.05) }
}
@keyframes ks-flyer-trail {
  0% { opacity: 0; transform: translateX(8%) rotate(-8deg) }
  35% { opacity: 0.85 }
  100% { opacity: 0; transform: translateX(-12%) rotate(-8deg) }
}
@keyframes ks-face-idle {
  0%, 100% { transform: translateY(0) }
  50% { transform: translateY(-2px) }
}
@keyframes ks-dock-settle {
  0% { transform: translateY(-3px) }
  100% { transform: translateY(0) }
}
@media (prefers-reduced-motion: no-preference) {
  .ks-mascot-flyer[data-on="1"]::before {
    animation: ks-flyer-aura 2.6s ease-in-out infinite;
  }
  .ks-mascot-flyer[data-on="1"]::after {
    animation: ks-flyer-trail 1.9s ease-out infinite;
  }
  .ks-mascot-ready #ks-companion[data-ks-mascot-state="dock"]:not(.ks-companion--pulse) .ks-companion-face {
    animation: ks-face-idle 5.2s ease-in-out infinite;
  }
  .ks-mascot-ready #ks-companion[data-ks-mascot-state="dock"] .ks-companion-inner {
    animation: ks-dock-settle 340ms var(--ease-out, ease) both;
  }
}
/* ========== /COMPANION/MASCOTA v2 ================================================ */
